Add default highlight language selection support.

Add support for recognizing Python 3 console output.
This commit is contained in:
Georg Brandl 2008-09-09 19:10:09 +00:00
parent 97e5802c39
commit 7d3539c041
7 changed files with 63 additions and 32 deletions

View File

@ -27,6 +27,10 @@ New features added
built documentation, and only written to stderr. If you want the built documentation, and only written to stderr. If you want the
old behavior, set the new config value ``keep_warnings`` to True. old behavior, set the new config value ``keep_warnings`` to True.
* The new config value ``highlight_language`` set a global default
for highlighting. When ``'python3'`` is selected, console output
blocks are recognized like for ``'python'``.
* ``SerializingHTMLBuilder`` was added as new abstract builder that * ``SerializingHTMLBuilder`` was added as new abstract builder that
can be subclassed to serialize build HTML in a specific format. can be subclassed to serialize build HTML in a specific format.
The ``PickleHTMLBuilder`` is a concrete subclass of it that uses The ``PickleHTMLBuilder`` is a concrete subclass of it that uses

View File

@ -212,6 +212,14 @@ Project information
%Y'`` (or, if translation is enabled with :confval:`language`, am equivalent %Y'`` (or, if translation is enabled with :confval:`language`, am equivalent
%format for the selected locale). %format for the selected locale).
.. confval:: highlight_language
The default language to highlight source code in. The default is
``'python'``. The value should be a valid Pygments lexer name, see
:ref:`code-examples` for more details.
.. versionadded:: 0.5
.. confval:: pygments_style .. confval:: pygments_style
The style name to use for Pygments highlighting of source code. Default is The style name to use for Pygments highlighting of source code. Default is

View File

@ -1,5 +1,7 @@
.. highlight:: rest .. highlight:: rest
.. _code-examples:
Showing code examples Showing code examples
--------------------- ---------------------
@ -23,7 +25,9 @@ Syntax highlighting is done with `Pygments <http://pygments.org>`_ (if it's
installed) and handled in a smart way: installed) and handled in a smart way:
* There is a "highlighting language" for each source file. Per default, this is * There is a "highlighting language" for each source file. Per default, this is
``'python'`` as the majority of files will have to highlight Python snippets. ``'python'`` as the majority of files will have to highlight Python snippets,
but the doc-wide default can be set with the :confval:`highlight_language`
config value.
* Within Python highlighting mode, interactive sessions are recognized * Within Python highlighting mode, interactive sessions are recognized
automatically and highlighted appropriately. automatically and highlighted appropriately.
@ -48,7 +52,7 @@ installed) and handled in a smart way:
* The valid values for the highlighting language are: * The valid values for the highlighting language are:
* ``none`` (no highlighting) * ``none`` (no highlighting)
* ``python`` (the default) * ``python`` (the default when :confval:`highlight_language` isn't set)
* ``rest`` * ``rest``
* ``c`` * ``c``
* ... and any other lexer name that Pygments supports. * ... and any other lexer name that Pygments supports.

View File

@ -44,6 +44,7 @@ class Config(object):
add_module_names = (True, True), add_module_names = (True, True),
show_authors = (False, True), show_authors = (False, True),
pygments_style = ('sphinx', False), pygments_style = ('sphinx', False),
highlight_language = ('python', False),
templates_path = ([], False), templates_path = ([], False),
template_bridge = (None, False), template_bridge = (None, False),
keep_warnings = (False, True), keep_warnings = (False, True),

View File

@ -51,6 +51,9 @@ else:
none = TextLexer(), none = TextLexer(),
python = PythonLexer(), python = PythonLexer(),
pycon = PythonConsoleLexer(), pycon = PythonConsoleLexer(),
# the python3 option exists as of Pygments 0.12, but it doesn't
# do any harm in previous versions
pycon3 = PythonConsoleLexer(python3=True),
rest = RstLexer(), rest = RstLexer(),
c = CLexer(), c = CLexer(),
) )
@ -106,43 +109,54 @@ class PygmentsBridge(object):
return '\\begin{Verbatim}[commandchars=@\\[\\]]\n' + \ return '\\begin{Verbatim}[commandchars=@\\[\\]]\n' + \
source + '\\end{Verbatim}\n' source + '\\end{Verbatim}\n'
def try_parse(self, src):
# Make sure it ends in a newline
src += '\n'
# Replace "..." by a mark which is also a valid python expression
# (Note, the highlighter gets the original source, this is only done
# to allow "..." in code and still highlight it as Python code.)
mark = "__highlighting__ellipsis__"
src = src.replace("...", mark)
# lines beginning with "..." are probably placeholders for suite
src = re.sub(r"(?m)^(\s*)" + mark + "(.)", r"\1"+ mark + r"# \2", src)
# if we're using 2.5, use the with statement
if sys.version_info >= (2, 5):
src = 'from __future__ import with_statement\n' + src
if isinstance(src, unicode):
# Non-ASCII chars will only occur in string literals
# and comments. If we wanted to give them to the parser
# correctly, we'd have to find out the correct source
# encoding. Since it may not even be given in a snippet,
# just replace all non-ASCII characters.
src = src.encode('ascii', 'replace')
try:
parser.suite(src)
except parsing_exceptions:
return False
else:
return True
def highlight_block(self, source, lang, linenos=False): def highlight_block(self, source, lang, linenos=False):
if not pygments: if not pygments:
return self.unhighlighted(source) return self.unhighlighted(source)
if lang == 'python': if lang in ('py', 'python'):
if source.startswith('>>>'): if source.startswith('>>>'):
# interactive session # interactive session
lexer = lexers['pycon'] lexer = lexers['pycon']
else: else:
# maybe Python -- try parsing it # maybe Python -- try parsing it
src = source + '\n' if self.try_parse(source):
# Replace "..." by a mark which is also a valid python expression
# (Note, the highlighter gets the original source, this is only done
# to allow "..." in code and still highlight it as Python code.)
mark = "__highlighting__ellipsis__"
src = src.replace("...", mark)
# lines beginning with "..." are probably placeholders for suite
src = re.sub(r"(?m)^(\s*)" + mark + "(.)", r"\1"+ mark + r"# \2", src)
# if we're using 2.5, use the with statement
if sys.version_info >= (2, 5):
src = 'from __future__ import with_statement\n' + src
if isinstance(src, unicode):
# Non-ASCII chars will only occur in string literals
# and comments. If we wanted to give them to the parser
# correctly, we'd have to find out the correct source
# encoding. Since it may not even be given in a snippet,
# just replace all non-ASCII characters.
src = src.encode('ascii', 'replace')
try:
parser.suite(src)
except parsing_exceptions:
return self.unhighlighted(source)
else:
lexer = lexers['python'] lexer = lexers['python']
else:
return self.unhighlighted(source)
elif lang in ('python3', 'py3') and source.startswith('>>>'):
# for py3, recognize interactive sessions, but do not try parsing...
lexer = lexers['pycon3']
else: else:
if lang in lexers: if lang in lexers:
lexer = lexers[lang] lexer = lexers[lang]

View File

@ -49,7 +49,7 @@ class HTMLTranslator(BaseTranslator):
self.highlighter = PygmentsBridge('html', builder.config.pygments_style) self.highlighter = PygmentsBridge('html', builder.config.pygments_style)
self.no_smarty = 0 self.no_smarty = 0
self.builder = builder self.builder = builder
self.highlightlang = 'python' self.highlightlang = builder.config.highlight_language
self.highlightlinenothreshold = sys.maxint self.highlightlinenothreshold = sys.maxint
self.protect_literal_text = 0 self.protect_literal_text = 0

View File

@ -157,7 +157,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.bibitems = [] self.bibitems = []
self.table = None self.table = None
self.next_table_colspec = None self.next_table_colspec = None
self.highlightlang = 'python' self.highlightlang = builder.config.highlight_language
self.highlightlinenothreshold = sys.maxint self.highlightlinenothreshold = sys.maxint
self.written_ids = set() self.written_ids = set()
if docclass == 'manual': if docclass == 'manual':