How to create Pygments extension for Sphinx

969 views
Skip to first unread message

Glenn Hutchings

unread,
Oct 17, 2008, 1:27:44 PM10/17/08
to sphinx-dev
Hi there. I posted this to comp.lang.python recently; no answers so
far. Then I spotted this group...

I'm writing Sphinx documentation for a non-Python program. The program
has an input file syntax suitable for highlighting using Pygments but,
obviously, Pygments knows nothing about it. I've created a Pygments
lexer which should highlight things, but how do I tell Pygments about
the new lexer, short of manually adding the Python source to the
Pygments "lexers" directory (clearly the Wrong Thing)?

I've scoured Sphinx, Pygments and setuptools documentation, and
seemingly the only way is to register a setuptools 'entry point' in
the setup() function -- but that seems to imply I'm installing a
Python package, which I'm not. Do I have to create one, or is there
another way?

Glenn

Gabriel Gellner

unread,
Oct 17, 2008, 3:00:43 PM10/17/08
to sphin...@googlegroups.com
You can register an extension in the Sphinx conf.py file, say you have a
pygments extension called foo_highlighting (which is an importable module or
package . . .). Then add the lines:

# If your extensions are in another directory, add it here.
sys.path.append('sphinxext')

# Import support for foo syntax highlighting (lives
# in the sphinxext directory defined above)
import foo_highlighting

# General configuration
# ---------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['foo_highlighting']

And you should be good to go (if your lexer is useful send it to the Pygments
guys so we can all use it :-)

Gabriel

Bruce Eckel

unread,
Oct 17, 2008, 3:29:10 PM10/17/08
to sphin...@googlegroups.com
Yes, do send it in. In the Jython chapter I've got Java code and it would be nice to pygment-ize that.
--
Bruce Eckel

Georg Brandl

unread,
Oct 17, 2008, 5:33:09 PM10/17/08
to sphin...@googlegroups.com
Bruce Eckel schrieb:

> Yes, do send it in. In the Jython chapter I've got Java code and it
> would be nice to pygment-ize that.

Nothing special is needed for Java, a simple

.. code-block:: java

code

is fine, since Pygments already has support for Java.

Georg

Georg Brandl

unread,
Oct 17, 2008, 5:37:11 PM10/17/08
to sphin...@googlegroups.com
Gabriel Gellner schrieb:

> You can register an extension in the Sphinx conf.py file, say you have a
> pygments extension called foo_highlighting (which is an importable module or
> package . . .). Then add the lines:
>
> # If your extensions are in another directory, add it here.
> sys.path.append('sphinxext')
>
> # Import support for foo syntax highlighting (lives
> # in the sphinxext directory defined above)
> import foo_highlighting

No need to import it, btw.

> # General configuration
> # ---------------------
>
> # Add any Sphinx extension module names here, as strings. They can be
> # extensions
> # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
> extensions = ['foo_highlighting']

The tricky part is what to do in the extension so that Pygments knows
about the lexer :)

Pygments has no API to add a lexer with aliases, because in normal usage
you'd just directly pass the lexer class to highlight(). In this case,
however, Sphinx looks up the lexer via its alias, so this isn't possible.

The solution I'd suggest is to extend the "sphinx.highlighting.lexers"
dictionary, like so:

# e.g. in conf.py
def setup(app):
from sphinx.highlighting import lexers
lexers['alias'] = MyLexer()

where 'alias' is the name you want to use in your code block directives.

cheers,
Georg

Glenn Hutchings

unread,
Oct 17, 2008, 10:59:49 PM10/17/08
to sphinx-dev
On Oct 17, 10:37 pm, Georg Brandl <ge...@python.org> wrote:
> The tricky part is what to do in the extension so that Pygments knows
> about the lexer :)

Yes, that was the problem. Just importing newly-defined lexers from
conf.py doesn't work -- Pygments doesn't implement any metaclass which
detects them. But I finally figured out the "proper" way, alluded to
in the Pygments docs -- create and install a package via setuptools
which contains one or more Pygments entry points. That way, the
'pygmentize' script also knows about the extension.

To save others the hassle of trawling through the docs, here's an
outline of the package (called 'hilite'):

setup.py
hilite
__init__.py
hilitecode.py

setup.py contains:

"""
My syntax highlighting for Pygments.
"""

from setuptools import setup

entry_points = """
[pygments.lexers]
myhighlight = hilite.hilitecode:MyHighlighter
"""

setup(
name = 'pyhilite',
version = '0.1',
description = __doc__,
author = "Glenn Hutchings",
packages = ['hilite'],
entry_points = entry_points
)

hilitecode.py contains the Pygments implementation of MyHighlighter,
as described in the Pygments docs.

After this package is installed, the new highlighter is registered
with Pygments (and listed with 'pygmentize -L').

Glenn

Takayuki Shimizukawa

unread,
Jan 16, 2013, 10:58:42 PM1/16/13
to sphin...@googlegroups.com, sphinx...@googlegroups.com
Hi chenwj,


2013/1/17 陳韋任 <azru...@gmail.com>:
> def setup(app):
> from sphinx.highlighting import lexers
> lexers['tblgen'] = TblgenLexer()
>
>
> But `make html` complains it cannot find TblgenLexer, error message below:
>
> Exception occurred:
> File "/z/tmp/chenwj/lbd/source/conf.py", line 25, in setup
> lexers['tblgen'] = TblgenLexer()
> NameError: global name 'TblgenLexer' is not defined
>
>
> What am I missing here? :-(

You need `from tblgen.tblgen import TblgenLexer` before use.

--
Takayuki SHIMIZUKAWA
http://about.me/shimizukawa
Reply all
Reply to author
Forward
0 new messages