【问题标题】:How to customize the code-block language of Sphinx?如何自定义 Sphinx 的代码块语言?
【发布时间】:2020-05-29 10:57:59
【问题描述】:

考虑以下情况:

.. code-block:: my_lang

    ...

如果我想把 my_lang 做成 Python 之类的东西,我该怎么做?

【问题讨论】:

    标签: python python-sphinx pygments


    【解决方案1】:

    首先,你需要创建一个脚本(_ext/mylanglexer.py),然后在conf.py上添加extensions

    _ext 是约定,但不是必须的。

    _ext/mylanglexer.py

    # _ext/mylanglexer.py
    
    from pygments.lexers import get_lexer_by_name  # refer LEXERS
    from pygments.lexers._mapping import LEXERS
    from pygments.lexers.python import PythonLexer
    
    
    def setup(app):
        # choose one, both ok
        app.add_lexer('my_lang', get_lexer_by_name('py'))
        # app.add_lexer('my_lang', PythonLexer)
    

    conf.py

    # conf.py
    
    extensions = [
        ...
        '_ext.mylanglexer',  # types.ModuleType, they are likely the_module = __import__('sphinx.ext.autodoc')
    ]
    

    在一些tutorial 告诉你最好添加sys.path.append(os.path.abspath("./_ext")) 然后extensions = ['mylanglexer']

    不管怎样,只要知道是一个模块,所有的扩展名都应该是import ...,所以如果你的模块不在默认路径下,当然要追加。

    现在,它开始工作了!


    它是如何工作的

    pygements.lexers.init.py

    # pygements.lexers.__init__.py
    
    def get_lexer_by_name(_alias, **options):
        ...
    
        # lookup builtin lexers
        for module_name, name, aliases, _, _ in LEXERS.values():  # <-- Be focus on this line.
            if _alias.lower() in aliases:
                return _lexer_cache[name](**options)  # The class object (module_name+key_name), for example: pygments.lexers.python.PythonLexer(**options)
        # continue with lexers from setuptools entrypoints
        for cls in find_plugin_lexers():
    
            ...
            return cls(**options)
    
        raise ClassNotFound('no lexer for alias %r found' % _alias)
    

    其中LEXERS 是以下某种东西。

    # pygments.lexers._mapping.py
    
    LEXERS = {
        # key_name: module_name, name, aliases: Tuple[str], _, _
        ...
        'ObjectiveCLexer': ('pygments.lexers.objective', 'Objective-C', ('objective-c', 'objectivec', 'obj-c', 'objc'), ('*.m', '*.h'), ('text/x-objective-c',)),
        'ObjectiveCppLexer': ('pygments.lexers.objective', 'Objective-C++', ('objective-c++', 'objectivec++', 'obj-c++', 'objc++'), ('*.mm', '*.hh'), ('text/x-objective-c++',)),
        'ObjectiveJLexer': ('pygments.lexers.javascript', 'Objective-J', ('objective-j', 'objectivej', 'obj-j', 'objj'), ('*.j',), ('text/x-objective-j',)),
        'OcamlLexer': ('pygments.lexers.ml', 'OCaml', ('ocaml',), ('*.ml', '*.mli', '*.mll', '*.mly'), ('text/x-ocaml',)),
        'OctaveLexer': ('pygments.lexers.matlab', 'Octave', ('octave',), ('*.m',), ('text/octave',)),
        'JsonLexer': ('pygments.lexers.data', 'JSON', ('json',), ('*.json', 'Pipfile.lock'), ('application/json',)),
        'PythonLexer': ('pygments.lexers.python', 'Python', ('python', 'py', 'sage', 'python3', 'py3'), ('*.py', '*.pyw', '*.jy', '*.sage', '*.sc', 'SConstruct', 'SConscript', '*.bzl', 'BUCK', 'BUILD', 'BUILD.bazel', 'WORKSPACE', '*.tac'), ('text/x-python', 'application/x-python', 'text/x-python3', 'application/x-python3')),
        ...
    }
    

    你知道,你在aliases 中的_alias,然后就可以工作了!

    如何自定义我的风格?

    你可以复制并修改Lexer,例如ObjectiveCLexerJsonLexer ...

    最后app.add_lexer('my_lang', YourLexer) 是个问题。

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 1970-01-01
      • 2013-06-09
      • 2020-01-06
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多