如何在sphinx项目中包含pygments样式?

时间:2018-02-05 03:48:51

标签: python-sphinx pygments

Sphinx可以定义主题以及要使用的pygments样式。

然而,我无法为Sphinx项目找到一个好方法来定义要使用的pygments的自定义样式(颜色方案)。

来自the docs

  

要使样式可用于Pygments,您必须

     
      
  • 将其注册为插件(see the plugin docs)
  •   
  • 或将其放入Pygments分发的样式子包中,每个样式一个样式类,其中文件名是样式名,类名是StylenameClass。
  •   

据我所知,第一个选项是我所追求的,因为它应该可以动态扩展pygments。虽然从检查链接我不知道如何做到这一点(没有如何使用插件系统的例子)。 第二个例子涉及将文件复制到pygments中,这是不实际的,特别是因为用户可能无法写入该路径。

确实设法破解了一种风格,虽然这不是一个好的解决方案:

包括完整性

# 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

2 个答案:

答案 0 :(得分:1)

如果开箱即用的Pygments样式不符合您的喜好,那么您可以create a custom Pygments style

答案 1 :(得分:0)

我也有类似的需求,不过我真正想要的是稍微改变现有的样式(下面称为基本样式)。我能够根据我的需要扩展问题中的代码。我将其发布在这里,供其他遇到此问题的人使用。

# Sphinx "conf.py"

# Syntax highlighting of code blocks
import pygments.styles, pygments.token
def monkeypatch_pygments(name, base_name='default', attrs={}):
    import importlib, sys
    base_module = importlib.import_module('.'.join(['pygments', 'styles', base_name]))

    def name_to_class_name(name):
        return name.capitalize() + 'Style'
    base_class = getattr(base_module, name_to_class_name(base_name))
    styles = getattr(base_class, 'styles', {}).copy()
    styles.update(attrs.pop('styles', {}))
    attrs['styles'] = styles
    class_name = name_to_class_name(name)
    Style = type(class_name, (base_class,), attrs)
    module = type(base_module)(name)
    setattr(module, class_name, Style)
    setattr(pygments.styles, name, module)
    pygments.styles.STYLE_MAP[name] = f'{name}::{class_name}'
    sys.modules['.'.join(['pygments', 'styles', name])] = module
pygments_style = 'custom'  # Arbitrary name of new style
monkeypatch_pygments(
    pygments_style,
    'friendly',  # Name of base style to use
    {
        # Changes to base style
        'background_color': '#f6f6f6',
        'styles': {
            pygments.token.Comment:       'italic #688F98',
            pygments.token.Name.Variable: '#d27a0a',
        },
    },
)

在上面的示例中,friendly 样式用作基本样式。它的 'background_color''styles' 字典中的一些项目被重新定义。请注意,未在 'styles' 中指定的项目将从基本样式中获取。基本样式本身没有改变。