summaryrefslogtreecommitdiff
path: root/sphinx/highlighting.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/highlighting.py')
-rw-r--r--sphinx/highlighting.py94
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')