squidfunk / mkdocs-material

Documentation that simply works
https://squidfunk.github.io/mkdocs-material/
MIT License
20.44k stars 3.49k forks source link

The dark side of material #338

Closed fmaida closed 7 years ago

fmaida commented 7 years ago

Hello,

I really like mkdocs-material but I also like dark themes; since I wasn't unable to get a result of my like by changing the values of palette->primary and palette->accent, I wrote an external CSS file to get the style I wanted:

piconauta

I quite like it, but there's a thing that I'm still not getting as I hoped. I tried to use codehilite and pygments for showing code snippets, but the default color scheme used is not really suitable for my dark-colored theme IMHO.

So I read briefly the pygments documentation and then I tried to get the available styles for pygments by entering this in python:

>>> from pygments.styles import get_all_styles
>>> styles = list(get_all_styles())
>>> styles

And i got this:

['default', 'emacs', 'friendly', 'colorful', 'autumn', 'murphy', 'manni', 
'monokai', 'perldoc', 'pastie', 'borland', 'trac', 'native', 'fruity', 'bw', 
'vim', 'vs', 'tango', 'rrt', 'xcode', 'igor', 'paraiso-light', 'paraiso-dark', 
'lovelace', 'algol', 'algol_nu', 'arduino', 'rainbow_dash', 'abap']

Then I tried to add one of this styles to my mkdocs.ymlconfiguration file by writing:

markdown_extensions:
    - codehilite(pygments_style=monokai)

mkdocs accepts that pygments_style parameter (at least I'm not getting a KeyError exception) but when I use the command mkdocs serve and try to take a look at the website, nothing seems to have changed.

I also tried to disable my css styles, to see if they're conflicting with codehilite but the style doesn't change either:

piconauta

I tried to read your documentation at http://squidfunk.github.io/mkdocs-material/extensions/codehilite/ but I haven't found anything about changing the color scheme.

Could you help me, please?

facelessuser commented 7 years ago

As far as the codehilite thing, MkDocs is providing its own Pygments theme in the stylesheets: https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/stylesheets/extensions/_codehilite.scss#L112.

Calling Pygments with a style doesn't really do anything unless you also enable noclasses which should just inject all the styling into the style attributes of each span.

You could try to override the style by including your own CSS in extra_css, but there may be a little clashing with two themes included at the same time, but maybe not.

The only other thing I can think of is turning off use_pygments and then using a JavaScript highlighter that recognizes HTML5 style code blocks <pre><code class="language-python"></code></pre>. That would allow you style it with whatever color scheme you like. There is nothing that says you have to use CodeHilite. It's the easiest to get working out of the box, but your are free to use other things.

Lastly, you could just fork Material and directly put in your favorite Pygments code style.

fmaida commented 7 years ago

Thank you. I tried to add the noclasses parameter as you suggested and I changed some parts of my mkdocs.yml configuration file with this:

- codehilite:
        guess_lang: False
        use_pygments: True
        noclasses: True
        pygments_style: monokai

And it's almost working as I hoped:

piconauta

I still have to fix that gray color on black background that is quite unreadable, but I'm almost there.

Thank you very much again

squidfunk commented 7 years ago

Thanks for clarifying, @facelessuser. Considering this as solved.

meleu commented 6 years ago

@fmaida I also love dark themes, and yours looks neat 👌

Would you mind in sharing your CSS file(s)?

By the way, I want to use it to generate pages for this project here

Thanks.

fmaida commented 6 years ago

It's available online here: https://github.com/fmaida/mkdocs-material-dark-theme

meleu commented 6 years ago

Thanks for sharing this @fmaida 👍

fmaida commented 6 years ago

You're welcome @meleu

squidfunk commented 6 years ago

I just experimented with the Pygments themes and they work for code blocks, but not for inline code snippets. Pygments doesn't apply any style for inline <code> sections. This means that changing the style will only change code blocks. I was hoping to add your hack to the documentation as a guide but I'm not quite satisfied with the result because a lot of custom tweaking is necessary per syntax theme, see:

bildschirmfoto 2018-04-29 um 17 12 16

@facelessuser - have you experimented with light/dark themes? Does the Highlight extension provided by Pymdown solve this problem?

squidfunk commented 6 years ago

Sorry guys, I posted this in the wrong issue (wrong tab) - should go here: #768

AXVin commented 5 years ago

If anyone wants to just add the dark theme as an external_css file then you can use this: :smiley:

/*
//////////////////
// Main content //
//////////////////
*/

/*
Default text color
and background color
*/
.md-main {
  color: rgba(255, 255, 255, 0.75) !important;
  background-color: #36393e !important;
}

/*
Main headlines
*/
.md-main h1 {
  color: rgba(255, 255, 255, 0.8) !important;
}

/*
Tables
*/
table {
  background-color: #616161 !important;
}

tbody {
  background-color: #484848 !important;
}

/*
////////////////////
// Navigation bar //
////////////////////
*/

/*
Left and right toc scrollbar
*/
.md-sidebar__scrollwrap::-webkit-scrollbar-thumb {
  background-color: #e0e0e0 !important;
}

.md-nav {
  color: rgba(255, 255, 255, 0.8) !important;
  background-color: #36393e !important;
}

/*
Arrow Left Icon
*/
html .md-nav--primary .md-nav__title:before {
  color: #fafafa !important;
}

.md-nav__title {
  color: rgba(255, 255, 255, 0.9) !important;
  background-color: #36393e !important;
}

/*
Arrow Right Icon
*/
.md-nav--primary .md-nav__link:after {
  color: #fafafa !important;
}

.md-nav__list {
  color: rgba(255, 255, 255, 0.8) !important;
  background-color: #36393e !important;
}

.md-nav__item {
  color: rgba(255, 255, 255, 0.7) !important;
  background-color: #36393e !important;
}

/*
////////////
// Search //
////////////
*/

/*
scroll bar
attention:
background is scroll handle color!
*/
.md-search__scrollwrap::-webkit-scrollbar-thumb {
  background-color: #e0e0e0 !important;
}
/*
scroll bar background color
*/
.md-search__scrollwrap {
  background-color: #44484e !important;
}

/*
Icon color
*/
.md-search-result__article--document:before {
  color: #eeeeee !important;
}

/*
headline color and
result list background
*/
.md-search-result__list {
  color: #eeeeee !important;
  background-color: #36393e !important;
}

/*
result info/count
*/
.md-search-result__meta {
  background-color: #eeeeee !important;
}

/*
article preview text color
*/
.md-search-result__teaser {
  color: #bdbdbd !important;
}

/*
/////////////////
// Inline Code //
/////////////////
*/

.md-typeset code {
  color: white !important;
/*  box-shadow: 0.29412em 0 0 hsla(0, 0%, 100%, 0.07),
    -0.29412em 0 0 hsla(0, 0%, 100%, 0.1);*/
}

.md-typeset a code {
  color: #94acff !important;
}

.md-typeset a:hover code {
  text-decoration: underline;
}

/*
/////////////////
// Code Blocks //
/////////////////
*/

/*
line number
*/
.linenos {
  color: #f5f5f5 !important;
  background-color: #313131 !important;
}

/*
code block background
*/
.codehilite {
  background-color: #44484e !important;
}

/*
scroll bar size
*/

.md-typeset .codehilite::-webkit-scrollbar {
  height: 1rem !important;
}

/*
actual syntax highlighting
*/
.codehilite pre {
  color: #fafafa !important;
  background-color: transparent !important;
}
.codehilite .hll {
  background-color: #272822 !important;
}
.codehilite .c {
  color: #8a8f98 !important;
} /* Comment */
.codehilite .err {
  color: #960050 !important;
  background-color: #1e0010 !important;
} /* Error */
.codehilite .k {
  color: #66d9ef !important;
} /* Keyword */
.codehilite .l {
  color: #ae81ff !important;
} /* Literal */
.codehilite .n {
  color: #f8f8f2 !important;
} /* Name */
.codehilite .o {
  color: #f92672 !important;
} /* Operator */
.codehilite .p {
  color: #f8f8f2 !important;
} /* Punctuation */
.codehilite .cm {
  color: #8a8f98 !important;
} /* Comment.Multiline */
.codehilite .cp {
  color: #8a8f98 !important;
} /* Comment.Preproc */
.codehilite .c1 {
  color: #8a8f98 !important;
} /* Comment.Single */
.codehilite .cs {
  color: #8a8f98 !important;
} /* Comment.Special */
.codehilite .ge {
  font-style: italic !important;
} /* Generic.Emph */
.codehilite .gs {
  font-weight: bold !important;
} /* Generic.Strong */
.codehilite .kc {
  color: #66d9ef !important;
} /* Keyword.Constant */
.codehilite .kd {
  color: #66d9ef !important;
} /* Keyword.Declaration */
.codehilite .kn {
  color: #f92672 !important;
} /* Keyword.Namespace */
.codehilite .kp {
  color: #66d9ef !important;
} /* Keyword.Pseudo */
.codehilite .kr {
  color: #66d9ef !important;
} /* Keyword.Reserved */
.codehilite .kt {
  color: #66d9ef !important;
} /* Keyword.Type */
.codehilite .ld {
  color: #e6db74 !important;
} /* Literal.Date */
.codehilite .m {
  color: #ae81ff !important;
} /* Literal.Number */
.codehilite .s {
  color: #e6db74 !important;
} /* Literal.String */
.codehilite .na {
  color: #a6e22e !important;
} /* Name.Attribute */
.codehilite .nb {
  color: #f8f8f2 !important;
} /* Name.Builtin */
.codehilite .nc {
  color: #a6e22e !important;
} /* Name.Class */
.codehilite .no {
  color: #66d9ef !important;
} /* Name.Constant */
.codehilite .nd {
  color: #a6e22e !important;
} /* Name.Decorator */
.codehilite .ni {
  color: #f8f8f2 !important;
} /* Name.Entity */
.codehilite .ne {
  color: #a6e22e !important;
} /* Name.Exception */
.codehilite .nf {
  color: #a6e22e !important;
} /* Name.Function */
.codehilite .nl {
  color: #f8f8f2 !important;
} /* Name.Label */
.codehilite .nn {
  color: #f8f8f2 !important;
} /* Name.Namespace */
.codehilite .nx {
  color: #a6e22e !important;
} /* Name.Other */
.codehilite .py {
  color: #f8f8f2 !important;
} /* Name.Property */
.codehilite .nt {
  color: #f92672 !important;
} /* Name.Tag */
.codehilite .nv {
  color: #f8f8f2 !important;
} /* Name.Variable */
.codehilite .ow {
  color: #f92672 !important;
} /* Operator.Word */
.codehilite .w {
  color: #f8f8f2 !important;
} /* Text.Whitespace */
.codehilite .mf {
  color: #ae81ff !important;
} /* Literal.Number.Float */
.codehilite .mh {
  color: #ae81ff !important;
} /* Literal.Number.Hex */
.codehilite .mi {
  color: #ae81ff !important;
} /* Literal.Number.Integer */
.codehilite .mo {
  color: #ae81ff !important;
} /* Literal.Number.Oct */
.codehilite .sb {
  color: #e6db74 !important;
} /* Literal.String.Backtick */
.codehilite .sc {
  color: #e6db74 !important;
} /* Literal.String.Char */
.codehilite .sd {
  color: #e6db74 !important;
} /* Literal.String.Doc */
.codehilite .s2 {
  color: #e6db74 !important;
} /* Literal.String.Double */
.codehilite .se {
  color: #ae81ff !important;
} /* Literal.String.Escape */
.codehilite .sh {
  color: #e6db74 !important;
} /* Literal.String.Heredoc */
.codehilite .si {
  color: #e6db74 !important;
} /* Literal.String.Interpol */
.codehilite .sx {
  color: #e6db74 !important;
} /* Literal.String.Other */
.codehilite .sr {
  color: #e6db74 !important;
} /* Literal.String.Regex */
.codehilite .s1 {
  color: #e6db74 !important;
} /* Literal.String.Single */
.codehilite .ss {
  color: #e6db74 !important;
} /* Literal.String.Symbol */
.codehilite .bp {
  color: #f8f8f2 !important;
} /* Name.Builtin.Pseudo */
.codehilite .vc {
  color: #f8f8f2 !important;
} /* Name.Variable.Class */
.codehilite .vg {
  color: #f8f8f2 !important;
} /* Name.Variable.Global */
.codehilite .vi {
  color: #f8f8f2 !important;
} /* Name.Variable.Instance */
.codehilite .il {
  color: #ae81ff !important;
} /* Literal.Number.Integer.Long */

.codehilite .gh {
} /* Generic Heading & Diff Header */
.codehilite .gu {
  color: #8a8f98 !important ;
} /* Generic.Subheading & Diff Unified/Comment? */
.codehilite .gd {
  color: #f92672 !important ;
} /* Generic.Deleted & Diff Deleted */
.codehilite .gi {
  color: #a6e22e !important ;
} /* Generic.Inserted & Diff Inserted */

.md-clipboard:before {
  color: rgba(255, 255, 255, 0.31);
}
.codehilite:hover .md-clipboard:before,
.md-typeset .highlight:hover .md-clipboard:before,
pre:hover .md-clipboard:before {
  color: rgba(255, 255, 255, 0.6);
}

.md-typeset summary:after {
  color: rgba(255, 255, 255, 0.26);
}

.md-typeset .admonition.example > .admonition-title,
.md-typeset .admonition.example > summary,
.md-typeset details.example > .admonition-title,
.md-typeset details.example > summary {
  background-color: rgba(154, 109, 255, 0.21);
}

.md-nav__link[data-md-state='blur'] {
  color: #aec0ff;
}

/*
///////////////
// Footnote //
/////////////
*/

.md-typeset .footnote {
  color: #888484 !important;
}

.md-typeset .footnote-ref:before {
  border-color: #888484 !important;
}
lightzane commented 7 months ago

Hi 🙂 I would like to ask a question. I’m quite new to mkdocs-material and I’m quite wondering, since it uses Pygments, is there any way that I can configure it to use a different Pygments style (i.e https://pygments.org/styles/)?

I cannot find anything about specifying which Pygment style / theme that I wanted to use.

I’m currently looking at this document: https://squidfunk.github.io/mkdocs-material/setup/extensions/python-markdown-extensions/#highlight

marcelbrueckner commented 7 months ago

PyMdown Extensions is the documentation you're looking for.

With the following options you can set the desired Pygments style:

markdown_extensions:
  - pymdownx.highlight:
      pygments_style: default
      noclasses: true

Check https://pygments.org/styles/ for a quick overview about available styles. The exact list of styles can be obtained via Python:

$ python
>>> from pygments.styles import get_all_styles
>>> styles = list(get_all_styles())
>>> print(styles)
['abap', 'algol', 'algol_nu', 'arduino', 'autumn', 'bw', 'borland', 'colorful', 'default', 'dracula',
'emacs', 'friendly_grayscale', 'friendly', 'fruity', 'github-dark', 'gruvbox-dark', 'gruvbox-light',
'igor', 'inkpot', 'lightbulb', 'lilypond', 'lovelace', 'manni', 'material', 'monokai', 'murphy',
'native', 'nord-darker', 'nord', 'one-dark', 'paraiso-dark', 'paraiso-light', 'pastie', 'perldoc',
'rainbow_dash', 'rrt', 'sas', 'solarized-dark', 'solarized-light', 'staroffice', 'stata-dark', 'stata-light',
'tango', 'trac', 'vim', 'vs', 'xcode', 'zenburn']

As you see, coffee isn't available as opposed to the above mentioned webpage. What a pitty.

lightzane commented 6 months ago

PyMdown Extensions is the documentation you're looking for.

With the following options you can set the desired Pygments style:

markdown_extensions:
  - pymdownx.highlight:
      pygments_style: default
      noclasses: true

Check https://pygments.org/styles/ for a quick overview about available styles. The exact list of styles can be obtained via Python:

$ python
>>> from pygments.styles import get_all_styles
>>> styles = list(get_all_styles())
>>> print(styles)
['abap', 'algol', 'algol_nu', 'arduino', 'autumn', 'bw', 'borland', 'colorful', 'default', 'dracula',
'emacs', 'friendly_grayscale', 'friendly', 'fruity', 'github-dark', 'gruvbox-dark', 'gruvbox-light',
'igor', 'inkpot', 'lightbulb', 'lilypond', 'lovelace', 'manni', 'material', 'monokai', 'murphy',
'native', 'nord-darker', 'nord', 'one-dark', 'paraiso-dark', 'paraiso-light', 'pastie', 'perldoc',
'rainbow_dash', 'rrt', 'sas', 'solarized-dark', 'solarized-light', 'staroffice', 'stata-dark', 'stata-light',
'tango', 'trac', 'vim', 'vs', 'xcode', 'zenburn']

As you see, coffee isn't available as opposed to the above mentioned webpage. What a pitty.

Thank you for this wonderful information.

I tried it, and it seems it might have been just missing CSS styles, since syntax highlighting is not properly working on .tsx syntax.

jturbide commented 6 months ago

Thanks! Can we change the pygments_style easily based on the selected theme?

This is my solution so far using a custom javascript:

document.addEventListener('DOMContentLoaded', function () {
    const lightModeStyle = '/stylesheets/friendly.css';
    const darkModeStyle = '/stylesheets/monokai.css';

    const switchStyle = (isDarkMode) => {
        // Define the style elements for Pygments
        // Remove existing Pygments style if present
        const existingStyle = document.getElementById('pygments-style');
        if (existingStyle) {
            existingStyle.parentNode.removeChild(existingStyle);
        }

        // Create a new link element for the Pygments style
        const link = document.createElement('link');
        link.id = 'pygments-style';
        link.rel = 'stylesheet';
        link.type = 'text/css';
        link.href = isDarkMode ? darkModeStyle : lightModeStyle;
        document.head.appendChild(link);
    };

    // Initial style setup
    const isDarkModeInitial = document.body.classList.contains('md-theme--slate');
    switchStyle(isDarkModeInitial);

    // Mutation observer for class changes in body
    const observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
            if (mutation.attributeName === 'class') {
                const isDarkMode = document.body.classList.contains('md-theme--slate');
                switchStyle(isDarkMode);
            }
        });
    });

    observer.observe(document.body, { attributes: true });
});

Generate the CSS Files: First, you'll need to generate the CSS for the Pygments styles.

from pygments.formatters import HtmlFormatter

# For 'friendly' style
with open('friendly.css', 'w') as f:
    f.write(HtmlFormatter(style='friendly').get_style_defs('.highlight'))

# For 'monokai' style
with open('monokai.css', 'w') as f:
    f.write(HtmlFormatter(style='monokai').get_style_defs('.highlight'))

Place the Generated CSS Files: After generating the CSS files, place them in a directory within your MkDocs site, such as docs/stylesheets/.

If you want to generate all the styles:

import os
from pygments import styles
from pygments.formatters import HtmlFormatter

# Directory where the CSS files will be stored
output_dir = 'docs/stylesheets/pygments/'
os.makedirs(output_dir, exist_ok=True)

for style in styles.get_all_styles():
    formatter = HtmlFormatter(style=style)
    style_css = formatter.get_style_defs('.highlight')
    file_name = f'{style}.css'
    file_path = os.path.join(output_dir, file_name)

    with open(file_path, 'w') as f:
        f.write(style_css)
    print(f'Generated CSS for style: {style}')

Adjust the Path in JavaScript: In your extra.js, update the paths to these CSS files:

extra_css:
  - stylesheets/extra.css
extra_javascript:
  - javascripts/extra.js