Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include pygments styles in a sphinx project?

Sphinx can define themes as well as a pygments style to use.

I couldn't however - find a good way for a Sphinx project to define a custom style (color scheme) for pygments to use.

From the docs:

To make the style usable for Pygments, you must

  • either register it as a plugin (see the plugin docs)
  • or drop it into the styles subpackage of your Pygments distribution one style class per style, where the file name is the style name and the class name is StylenameClass.

From what I can tell the first option is what I'm after since it should be possible to extend pygments dynamically. Although from checking the link I'm not sure how this would be done (no examples of how to use the plugin system). The second example involves copying files into pygments which isn't practical especially since the path may not be writable by the user.


I did manage to hack in a style, although it's not a nice solution:

including for completeness

# Sphinx "conf.py"

# Master toctree document
master_doc = 'contents'

# BEGIN MONKEY-PATCH
from pygments.style import Style
from pygments.token import Text, Other, Comment, Whitespace

class MyFancyStyle(Style):
    background_color = "#1e1e27"
    default_style = ""
    styles = {
        Text:                      "#cfbfad",
        Other:                     "#cfbfad",
        Whitespace:                "#434357",
        Comment:                   "#cd8b00",
        Comment.Preproc:           "#409090",
        Comment.PreprocFile:       "bg:#404040 #ffcd8b",
        Comment.Special:           "#808bed",
        # ... snip (just more colors, you get the idea) ...
    }


def pygments_monkeypatch_style(mod_name, cls):
    import sys
    import pygments.styles
    cls_name = cls.__name__
    mod = type(__import__("os"))(mod_name)
    setattr(mod, cls_name, cls)
    setattr(pygments.styles, mod_name, mod)
    sys.modules["pygments.styles." + mod_name] = mod
    from pygments.styles import STYLE_MAP
    STYLE_MAP[mod_name] = mod_name + "::" + cls_name


pygments_monkeypatch_style("my_fancy_style", MyFancyStyle)
pygments_style = "my_fancy_style"
# END MONKEY-PATCH
like image 597
ideasman42 Avatar asked Feb 05 '18 03:02

ideasman42


1 Answers

This is how I set it up:

Folder Structure:

docs
├── source
│   ├── conf.py <--
│   ├── _pygments
│   │   ├── style.py <--
│   ├── _static
│   ├── ...

conf.py

(at the very top)

import sys, os
sys.path.append(os.path.abspath("./_pygments"))
pygments_style = 'style.MonokaiStyle'
...

style.py

from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, Text, \
     Number, Operator, Generic, Whitespace, Punctuation, Other, Literal

class MonokaiStyle(Style):
    """
    This style mimics the Monokai color scheme.
    """

    background_color = "#272822"
    highlight_color = "#49483e"

    styles = {
        # No corresponding class for the following:
        Text:                      "#f8f8f2", # class:  ''
        Whitespace:                "",        # class: 'w'
        Error:                     "#960050 bg:#1e0010", # class: 'err'
        Other:                     "",        # class 'x'
        ...
    }

You can choose a predefined style here (as I did) and put the corresponding *.py file from the official pygment repo into the _pygment folder. Or you can define your own style, renaming the class to your liking (don't forget to adapt the import clause in conf.py to the new names)

EDIT: This is an even better resource for style lookup.

like image 190
glades Avatar answered Sep 26 '22 17:09

glades