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
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
can be subclassed to serialize build HTML in a specific format.
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
%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
The style name to use for Pygments highlighting of source code. Default is

View File

@ -1,5 +1,7 @@
.. highlight:: rest
.. _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:
* 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
automatically and highlighted appropriately.
@ -48,7 +52,7 @@ installed) and handled in a smart way:
* The valid values for the highlighting language are:
* ``none`` (no highlighting)
* ``python`` (the default)
* ``python`` (the default when :confval:`highlight_language` isn't set)
* ``rest``
* ``c``
* ... and any other lexer name that Pygments supports.

View File

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

View File

@ -51,6 +51,9 @@ else:
none = TextLexer(),
python = PythonLexer(),
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(),
c = CLexer(),
)
@ -106,43 +109,54 @@ class PygmentsBridge(object):
return '\\begin{Verbatim}[commandchars=@\\[\\]]\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):
if not pygments:
return self.unhighlighted(source)
if lang == 'python':
if lang in ('py', 'python'):
if source.startswith('>>>'):
# interactive session
lexer = lexers['pycon']
else:
# maybe Python -- try parsing it
src = source + '\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 self.unhighlighted(source)
else:
if self.try_parse(source):
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:
if lang in lexers:
lexer = lexers[lang]

View File

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

View File

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