diff --git a/CHANGES b/CHANGES index 9a35b4209..c03429c22 100644 --- a/CHANGES +++ b/CHANGES @@ -62,6 +62,10 @@ Release 1.0 (in development) Release 0.6.4 (in development) ============================== +* Restore compatibility with Pygments >= 1.2. + +* #295: Fix escaping of hyperref targets in LaTeX output. + * #302: Fix links generated by the ``:doc:`` role for LaTeX output. * #286: collect todo nodes after the whole document has been read; diff --git a/doc/concepts.rst b/doc/concepts.rst index 277672111..5aabdd3b8 100644 --- a/doc/concepts.rst +++ b/doc/concepts.rst @@ -133,8 +133,8 @@ tables of contents. The ``toctree`` directive is the central element. In the end, all documents in the :term:`source directory` (or subdirectories) must occur in some ``toctree`` directive; Sphinx will emit a warning if it finds a file that is not included, because that means that this file will not - be reachable through standard navigation. Use :confval:`unused_documents` to - explicitly exclude documents from building, and :confval:`exclude_dirs` to + be reachable through standard navigation. Use :confval:`unused_docs` to + explicitly exclude documents from building, and :confval:`exclude_trees` to exclude whole directories. The "master document" (selected by :confval:`master_doc`) is the "root" of diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py index bf3ffafce..8300bd326 100644 --- a/sphinx/highlighting.py +++ b/sphinx/highlighting.py @@ -20,7 +20,7 @@ except ImportError: # parser is not available on Jython parser = None -from sphinx.util.texescape import tex_hl_escape_map +from sphinx.util.texescape import tex_hl_escape_map_old, tex_hl_escape_map_new try: import pygments @@ -130,7 +130,7 @@ class PygmentsBridge(object): # first, escape highlighting characters like Pygments does source = source.translate(escape_hl_chars) # then, escape all characters nonrepresentable in LaTeX - source = source.translate(tex_hl_escape_map) + source = source.translate(tex_hl_escape_map_old) return '\\begin{Verbatim}[commandchars=@\\[\\]]\n' + \ source + '\\end{Verbatim}\n' @@ -215,7 +215,10 @@ class PygmentsBridge(object): return highlight(source, lexer, self.fmter[bool(linenos)]) else: hlsource = highlight(source, lexer, self.fmter[bool(linenos)]) - return hlsource.translate(tex_hl_escape_map) + if hlsource.startswith(r'\begin{Verbatim}[commandchars=\\\{\}'): + # Pygments >= 1.2 + return hlsource.translate(tex_hl_escape_map_new) + return hlsource.translate(tex_hl_escape_map_old) except ErrorToken: # this is most probably not the selected language, # so let it pass unhighlighted diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index b719b391a..e04137ee5 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -278,7 +278,6 @@ def patfilter(names, pat): Return the subset of the list NAMES that match PAT. Adapted from fnmatch module. """ - result = [] if pat not in _pat_cache: _pat_cache[pat] = re.compile(_translate_pattern(pat)) match = _pat_cache[pat].match @@ -409,7 +408,6 @@ def movefile(source, dest): def copytimes(source, dest): """Copy a file's modification times.""" st = os.stat(source) - mode = stat.S_IMODE(st.st_mode) if hasattr(os, 'utime'): os.utime(dest, (st.st_atime, st.st_mtime)) diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py index 00d0325c4..737908295 100644 --- a/sphinx/util/texescape.py +++ b/sphinx/util/texescape.py @@ -99,8 +99,9 @@ tex_replacements = [ ] tex_escape_map = {} -tex_hl_escape_map = {} -_new_cmd_chars = {ord(u'\\'): u'@', ord(u'{'): u'[', ord(u'}'): u']'} +tex_hl_escape_map_old = {} # replacement map for Pygments <= 1.1 +tex_hl_escape_map_new = {} # replacement map for Pygments >= 1.2 +_old_cmd_chars = {ord(u'\\'): u'@', ord(u'{'): u'[', ord(u'}'): u']'} def init(): for a, b in tex_replacements: @@ -108,4 +109,5 @@ def init(): for a, b in tex_replacements: if a in u'[]{}\\': continue - tex_hl_escape_map[ord(a)] = b.translate(_new_cmd_chars) + tex_hl_escape_map_new[ord(a)] = b + tex_hl_escape_map_old[ord(a)] = b.translate(_old_cmd_chars) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index ee3a10467..35e393c54 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -253,6 +253,9 @@ class LaTeXTranslator(nodes.NodeVisitor): return (HEADER % self.elements + self.highlighter.get_stylesheet() + u''.join(self.body) + FOOTER % self.elements) + def idescape(self, id): + return str(unicode(id).translate(tex_escape_map)) + def visit_document(self, node): self.footnotestack.append(self.collect_footnotes(node)) self.curfilestack.append(node.get('docname', '')) @@ -466,7 +469,7 @@ class LaTeXTranslator(nodes.NodeVisitor): d = self.descstack[-1] d.cls = d.cls.rstrip('.') if node.parent['desctype'] != 'describe' and node['ids']: - hyper = '\\hypertarget{%s}{}' % node['ids'][0] + hyper = '\\hypertarget{%s}{}' % self.idescape(node['ids'][0]) else: hyper = '' if d.count == 0: @@ -757,7 +760,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_term(self, node): ctx = '] \\leavevmode' if node.has_key('ids') and node['ids']: - ctx += '\\hypertarget{%s}{}' % node['ids'][0] + ctx += '\\hypertarget{%s}{}' % self.idescape(node['ids'][0]) self.body.append('\\item[') self.context.append(ctx) def depart_term(self, node):