【问题标题】:How to include pygments styles in a sphinx project?如何在 sphinx 项目中包含 pygments 样式?
【发布时间】:2018-07-14 21:35:16
【问题描述】:

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

【问题讨论】:

    标签: python-sphinx pygments


    【解决方案1】:

    在您的conf.py 中指定您要使用的 Pygments 样式。来自Sphinx documentation

    pygments_style

    用于 Pygments 突出显示源代码的样式名称。如果未设置,则为 HTML 输出选择主题的默认样式或“sphinx”。

    Available names 可以通过以下方式检索:

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

    一些Sphinx 主题和Pygments 样式组合的online preview 可用。

    如果你不喜欢开箱即用的 Pygments 样式,那么你可以create a custom Pygments style

    【讨论】:

    • 我已经阅读了“创建自定义 Pygments 样式”。 docs,但不确定如何应用此信息-conf.py 如何注册样式插件? - 请参阅:pygments.org/docs/plugins - 这里有一些非 Python 文本,所以我不确定如何在 conf.py 中使用它。
    • 您编辑的我的原始答案包含有关指定 Pygments 样式的相关信息。您可以按照我在答案中链接到的 Pygments 文档中的描述创建自定义样式,并在 conf.py 中使用该样式的名称。指定 Pygments 样式不是插件,而是配置值。您引用的非 Python 文本是什么?
    • 问题是“如何包含 pygments 样式” 包含样式与从预设列表中选择一个样式完全不同。这就是为什么原始答案的第一个部分不相关。 RE:您可以按照我在回答中链接到的 Pygments 文档中的描述创建自定义样式。 --- 如何? - 文档很差,或者我读错了,文档说要使用插件系统或将它们放入 pygments 模块(这是我目前正在做的 - 尽管通过猴子补丁)。
    • 更新了问题,因为包含样式的确切方法并不明显。
    【解决方案2】:

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

    # 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' 中未指定的项目将取自基本样式。基本样式本身没有改变。

    【讨论】:

      【解决方案3】:

      将 pygments 样式包含为插件的“正确”方法是制作一个新包并通过 setuptools 安装它。

      • 使用常规流程创建setup.cfg (https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html)

      • 添加以下部分:

        [options.entry_points]
        pygments.styles =
             my_fancy_style = mypackage.mystyle:MyFancyStyle
        
      • mypackage/mystyle.py 中创建class MyFancyStyle 的风格

      • 安装包:pip install -e .

      • 利润!您现在可以在任何需要 Pygments 样式的地方使用 "my_fancy_style"。唷。

      【讨论】:

        【解决方案4】:

        我是这样设置的:

        文件夹结构:

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

        conf.py

        (在最顶端)

        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'
                ...
            }
        

        你可以选择一个预定义的样式here(和我一样)并将official pygment repo中对应的*.py文件放到_pygment文件夹中。或者您可以定义自己的样式,根据自己的喜好重命名类(不要忘记将 conf.py 中的 import 子句调整为新名称)

        编辑:This 是更好的样式查找资源。

        【讨论】:

          猜你喜欢
          • 2017-11-17
          • 1970-01-01
          • 1970-01-01
          • 2016-07-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-30
          • 2015-06-18
          相关资源
          最近更新 更多