Georg Brandl avatar Georg Brandl committed 5ee4e6e Merge

merge with 0.6

Comments (0)

Files changed (6)

 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;
    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


     # 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
     import pygments
             # 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'
                 return highlight(source, lexer, self.fmter[bool(linenos)])
                 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


     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
 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))


 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:
     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)


         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.curfilestack.append(node.get('docname', ''))
         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])
             hyper = ''
         if d.count == 0:
     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])
     def depart_term(self, node):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.