2

Consider the below situation:

.. code-block:: my_lang

    ...

If I want to make my_lang as some stuff such as Python, how can I do it?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Carson
  • 6,105
  • 2
  • 37
  • 45

1 Answers1

3

First, you need to create a script (_ext/mylanglexer.py), and then add on the extensions on the conf.py

(_ext is a convention but not a must.)

_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')
]

at some tutorial the tell you better add sys.path.append(os.path.abspath("./_ext")) then extensions = ['mylanglexer']

Anyway, as long as you know that is a module, all extensions should be able to be import ..., so if your module is not in the default path, of course, you must append.

Now, it's working!


How does it work

see the 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)

In which LEXERS is some kind of the following stuff.

# 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')),
    ...
}

There you know, your _alias in the aliases, then will work!

How can I customize my style?

you can copy and do some modify the Lexer, such as ObjectiveCLexer, JsonLexer ...

finally app.add_lexer('my_lang', YourLexer) that's kind of the problem.

Carson
  • 6,105
  • 2
  • 37
  • 45