diff --git a/CHANGES b/CHANGES index 5c0b91de8..27761d8ad 100644 --- a/CHANGES +++ b/CHANGES @@ -23,13 +23,15 @@ Release 1.0 (in development) * #284: All docinfo metadata is now put into the document metadata, not just the author. +* Added new HTML theme ``nature``. + * Added new HTML theme ``agogo``, created by Andi Albrecht. +* Added new HTML theme called scrolls, created by Armin Ronacher. + * The ``toctree()`` callable in templates now has a ``maxdepth`` keyword argument to control the depth of the generated tree. -* Added new minimal theme called scrolls, created by Armin Ronacher. - * Added Catalan translation, thanks to Pau Fernández. * Added ``html_output_encoding`` config value. @@ -71,6 +73,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 212b4c7cc..6f7967cf8 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/doc/ext/appapi.rst b/doc/ext/appapi.rst index 754f22eb4..7ed3d3d49 100644 --- a/doc/ext/appapi.rst +++ b/doc/ext/appapi.rst @@ -56,9 +56,11 @@ the following public API: given as keyword arguments: the keyword must be one or more of ``'html'``, ``'latex'``, ``'text'``, the value a 2-tuple of ``(visit, depart)`` methods. ``depart`` can be ``None`` if the ``visit`` function raises - :exc:`docutils.nodes.SkipNode`. Example:: + :exc:`docutils.nodes.SkipNode`. Example: - class math(docutils.nodes.Element) + .. code-block:: python + + class math(docutils.nodes.Element): pass def visit_math_html(self, node): self.body.append(self.starttag(node, 'math')) @@ -98,7 +100,9 @@ the following public API: support directive classes otherwise). For example, the (already existing) :dir:`literalinclude` directive would be - added like this:: + added like this: + + .. code-block:: python from docutils.parsers.rst import directives add_directive('literalinclude', literalinclude_directive, diff --git a/doc/themes/fullsize/nature.png b/doc/themes/fullsize/nature.png new file mode 100644 index 000000000..d42957e3b Binary files /dev/null and b/doc/themes/fullsize/nature.png differ diff --git a/doc/themes/nature.png b/doc/themes/nature.png new file mode 100644 index 000000000..053970d8c Binary files /dev/null and b/doc/themes/nature.png differ diff --git a/doc/theming.rst b/doc/theming.rst index c2566ac39..4771dbec5 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -65,9 +65,9 @@ Builtin themes | | | | *scrolls* | *agogo* | +--------------------+--------------------+ -| |traditional| | | +| |traditional| | |nature| | | | | -| *traditional* | | +| *traditional* | *nature* | +--------------------+--------------------+ .. |default| image:: themes/default.png @@ -75,6 +75,7 @@ Builtin themes .. |scrolls| image:: themes/scrolls.png .. |agogo| image:: themes/agogo.png .. |traditional| image:: themes/traditional.png +.. |nature| image:: themes/nature.png Sphinx comes with a selection of themes to choose from. @@ -157,6 +158,9 @@ These themes are: - **headerlinkcolor** (CSS color): Color for the backreference link in headings. +* **nature** -- A greenish theme. There are currently no options beyond + *nosidebar*. + * **traditional** -- A theme resembling the old Python documentation. There are currently no options beyond *nosidebar*. diff --git a/sphinx/environment.py b/sphinx/environment.py index 3abc17494..3ae42bd54 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -1300,7 +1300,8 @@ class BuildEnvironment: # keywords are oddballs: they are referenced by named labels docname, labelid, _ = self.labels.get(target, ('','','')) if not docname: - #self.warn(node['refdoc'], 'unknown keyword: %s' % target) + #self.warn(node['refdoc'], + # 'unknown keyword: %s' % target) newnode = None else: newnode = make_refnode(builder, fromdocname, docname, 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/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t new file mode 100644 index 000000000..31d9ec622 --- /dev/null +++ b/sphinx/themes/nature/static/nature.css_t @@ -0,0 +1,229 @@ +/** + * Sphinx stylesheet -- nature theme + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Arial, sans-serif; + font-size: 100%; + background-color: #111; + color: #555; + margin: 0; + padding: 0; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.document { + background-color: #eee; +} + +div.body { + background-color: #ffffff; + color: #3E4349; + padding: 0 30px 30px 30px; + font-size: 0.9em; +} + +div.footer { + color: #555; + width: 100%; + padding: 13px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #444; + text-decoration: underline; +} + +div.related { + background-color: #6BA81E; + line-height: 32px; + color: #fff; + text-shadow: 0px 1px 0 #444; + font-size: 0.9em; +} + +div.related a { + color: #E2F3CC; +} + +div.sphinxsidebar { + font-size: 0.75em; + line-height: 1.5em; +} + +div.sphinxsidebarwrapper{ + padding: 20px 0; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Arial, sans-serif; + color: #222; + font-size: 1.2em; + font-weight: normal; + margin: 0; + padding: 5px 10px; + background-color: #ddd; + text-shadow: 1px 1px 0 white +} + +div.sphinxsidebar h4{ + font-size: 1.1em; +} + +div.sphinxsidebar h3 a { + color: #444; +} + + +div.sphinxsidebar p { + color: #888; + padding: 5px 20px; +} + +div.sphinxsidebar p.topless { +} + +div.sphinxsidebar ul { + margin: 10px 20px; + padding: 0; + color: #000; +} + +div.sphinxsidebar a { + color: #444; +} + +div.sphinxsidebar input { + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar input[type=text]{ + margin-left: 20px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #005B81; + text-decoration: none; +} + +a:hover { + color: #E32E00; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Arial, sans-serif; + background-color: #BED4EB; + font-weight: normal; + color: #212224; + margin: 30px 0px 10px 0px; + padding: 5px 0 5px 10px; + text-shadow: 0px 1px 0 white +} + +div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 150%; background-color: #C8D5E3; } +div.body h3 { font-size: 120%; background-color: #D8DEE3; } +div.body h4 { font-size: 110%; background-color: #D8DEE3; } +div.body h5 { font-size: 100%; background-color: #D8DEE3; } +div.body h6 { font-size: 100%; background-color: #D8DEE3; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + line-height: 1.5em; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.highlight{ + background-color: white; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 10px; + background-color: White; + color: #222; + line-height: 1.2em; + border: 1px solid #C6C9CB; + font-size: 1.1em; + margin: 1.5em 0 1.5em 0; + -webkit-box-shadow: 1px 1px 1px #d8d8d8; + -moz-box-shadow: 1px 1px 1px #d8d8d8; +} + +tt { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ + font-size: 1.1em; + font-family: monospace; +} diff --git a/sphinx/themes/nature/theme.conf b/sphinx/themes/nature/theme.conf new file mode 100644 index 000000000..1cc400446 --- /dev/null +++ b/sphinx/themes/nature/theme.conf @@ -0,0 +1,4 @@ +[theme] +inherit = basic +stylesheet = nature.css +pygments_style = tango diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index 3ceafa5e5..b7f756fcd 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -280,7 +280,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 @@ -411,7 +410,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 46634428b..eb8128ba3 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', '')) @@ -467,7 +470,7 @@ class LaTeXTranslator(nodes.NodeVisitor): d = self.descstack[-1] d.cls = d.cls.rstrip('.') if node.parent['objtype'] != 'describe' and node['ids']: - hyper = '\\hypertarget{%s}{}' % node['ids'][0] + hyper = '\\hypertarget{%s}{}' % self.idescape(node['ids'][0]) else: hyper = '' if d.count == 0: @@ -758,7 +761,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): diff --git a/tests/test_theming.py b/tests/test_theming.py index 6dd5e12c7..be5105a65 100644 --- a/tests/test_theming.py +++ b/tests/test_theming.py @@ -25,7 +25,7 @@ def test_theme_api(app): # test Theme class API assert set(Theme.themes.keys()) == \ set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc', - 'traditional', 'testtheme', 'ziptheme', 'epub']) + 'traditional', 'testtheme', 'ziptheme', 'epub', 'nature']) assert Theme.themes['testtheme'][1] is None assert isinstance(Theme.themes['ziptheme'][1], zipfile.ZipFile)