diff options
Diffstat (limited to 'sphinx/highlighting.py')
-rw-r--r-- | sphinx/highlighting.py | 94 |
1 files changed, 29 insertions, 65 deletions
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py index 600a7cf0..e257c370 100644 --- a/sphinx/highlighting.py +++ b/sphinx/highlighting.py @@ -9,7 +9,6 @@ :license: BSD, see LICENSE for details. """ -import sys import re import textwrap @@ -19,62 +18,44 @@ except ImportError: # parser is not available on Jython parser = None +from six import PY2, text_type + from sphinx.util.pycompat import htmlescape from sphinx.util.texescape import tex_hl_escape_map_new from sphinx.ext import doctest -try: - import pygments - from pygments import highlight - from pygments.lexers import PythonLexer, PythonConsoleLexer, CLexer, \ - TextLexer, RstLexer - from pygments.lexers import get_lexer_by_name, guess_lexer - from pygments.formatters import HtmlFormatter, LatexFormatter - from pygments.filters import ErrorToken - from pygments.styles import get_style_by_name - from pygments.util import ClassNotFound - from sphinx.pygments_styles import SphinxStyle, NoneStyle -except ImportError: - pygments = None - lexers = None - HtmlFormatter = LatexFormatter = None -else: - - lexers = dict( - none = TextLexer(), - python = PythonLexer(), - pycon = PythonConsoleLexer(), - pycon3 = PythonConsoleLexer(python3=True), - rest = RstLexer(), - c = CLexer(), - ) - for _lexer in lexers.values(): - _lexer.add_filter('raiseonerror') +from pygments import highlight +from pygments.lexers import PythonLexer, PythonConsoleLexer, CLexer, \ + TextLexer, RstLexer +from pygments.lexers import get_lexer_by_name, guess_lexer +from pygments.formatters import HtmlFormatter, LatexFormatter +from pygments.filters import ErrorToken +from pygments.styles import get_style_by_name +from pygments.util import ClassNotFound +from sphinx.pygments_styles import SphinxStyle, NoneStyle + +lexers = dict( + none = TextLexer(), + python = PythonLexer(), + pycon = PythonConsoleLexer(), + pycon3 = PythonConsoleLexer(python3=True), + rest = RstLexer(), + c = CLexer(), +) +for _lexer in lexers.values(): + _lexer.add_filter('raiseonerror') escape_hl_chars = {ord(u'\\'): u'\\PYGZbs{}', ord(u'{'): u'\\PYGZob{}', ord(u'}'): u'\\PYGZcb{}'} -# used if Pygments is not available -_LATEX_STYLES = r''' -\newcommand\PYGZbs{\char`\\} -\newcommand\PYGZob{\char`\{} -\newcommand\PYGZcb{\char`\}} -''' - # used if Pygments is available # use textcomp quote to get a true single quote _LATEX_ADD_STYLES = r''' \renewcommand\PYGZsq{\textquotesingle} ''' -parsing_exceptions = (SyntaxError, UnicodeEncodeError) -if sys.version_info < (2, 5): - # Python <= 2.4 raises MemoryError when parsing an - # invalid encoding cookie - parsing_exceptions += MemoryError, - class PygmentsBridge(object): # Set these attributes if you want to have different Pygments formatters @@ -85,8 +66,6 @@ class PygmentsBridge(object): def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=False): self.dest = dest - if not pygments: - return if stylename is None or stylename == 'sphinx': style = SphinxStyle elif stylename == 'none': @@ -117,7 +96,7 @@ class PygmentsBridge(object): source = source.translate(escape_hl_chars) # then, escape all characters nonrepresentable in LaTeX source = source.translate(tex_hl_escape_map_new) - return '\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n' + \ + return '\\begin{Verbatim}[frame=single,commandchars=\\\\\\{\\}]\n' + \ source + '\\end{Verbatim}\n' def try_parse(self, src): @@ -137,11 +116,7 @@ class PygmentsBridge(object): # 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 sys.version_info < (3, 0) and isinstance(src, unicode): + if PY2 and isinstance(src, text_type): # 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 @@ -149,27 +124,19 @@ class PygmentsBridge(object): # just replace all non-ASCII characters. src = src.encode('ascii', 'replace') - if (3, 0) <= sys.version_info < (3, 2): - # Python 3.1 can't process '\r' as linesep. - # `parser.suite("print('hello')\r\n")` cause error. - if '\r\n' in src: - src = src.replace('\r\n', '\n') - if parser is None: return True try: parser.suite(src) - except parsing_exceptions: + except (SyntaxError, UnicodeEncodeError): return False else: return True def highlight_block(self, source, lang, warn=None, force=False, **kwargs): - if not isinstance(source, unicode): + if not isinstance(source, text_type): source = source.decode() - if not pygments: - return self.unhighlighted(source) # find out which lexer to use if lang in ('py', 'python'): @@ -223,16 +190,13 @@ class PygmentsBridge(object): if self.dest == 'html': return hlsource else: - if not isinstance(hlsource, unicode): # Py2 / Pygments < 1.6 + hlsource = re.sub(r'(?<=\\begin{Verbatim}\[)(?=commandchars)', + r'frame=single,', hlsource) + if not isinstance(hlsource, text_type): # Py2 / Pygments < 1.6 hlsource = hlsource.decode() return hlsource.translate(tex_hl_escape_map_new) def get_stylesheet(self): - if not pygments: - if self.dest == 'latex': - return _LATEX_STYLES - # no HTML styles needed - return '' formatter = self.get_formatter() if self.dest == 'html': return formatter.get_style_defs('.highlight') |