merge with 0.6

This commit is contained in:
Georg Brandl 2009-06-04 18:47:43 +02:00
commit 288af885c2
7 changed files with 73 additions and 12 deletions

View File

@ -23,6 +23,14 @@ Release 1.0 (in development)
Release 0.6.2 (in development) Release 0.6.2 (in development)
============================== ==============================
* #158: Allow '..' in template names, and absolute template paths;
Jinja 2 by default disables both.
* When highlighting Python code, ignore extra indentation before
trying to parse it as Python.
* #191: Don't escape the tilde in URIs in LaTeX.
* Don't consider contents of source comments for the search index. * Don't consider contents of source comments for the search index.
* Set the default encoding to ``utf-8-sig`` to handle files with a * Set the default encoding to ``utf-8-sig`` to handle files with a

View File

@ -13,6 +13,7 @@ import sys
import cgi import cgi
import re import re
import parser import parser
import textwrap
from sphinx.util.texescape import tex_hl_escape_map from sphinx.util.texescape import tex_hl_escape_map
@ -129,6 +130,10 @@ class PygmentsBridge(object):
# Make sure it ends in a newline # Make sure it ends in a newline
src += '\n' src += '\n'
# Ignore consistent indentation.
if src.lstrip('\n').startswith(' '):
src = textwrap.dedent(src)
# Replace "..." by a mark which is also a valid python expression # Replace "..." by a mark which is also a valid python expression
# (Note, the highlighter gets the original source, this is only done # (Note, the highlighter gets the original source, this is only done
# to allow "..." in code and still highlight it as Python code.) # to allow "..." in code and still highlight it as Python code.)

View File

@ -15,6 +15,7 @@ from pprint import pformat
from jinja2 import FileSystemLoader, BaseLoader, TemplateNotFound, \ from jinja2 import FileSystemLoader, BaseLoader, TemplateNotFound, \
contextfunction contextfunction
from jinja2.utils import open_if_exists
from jinja2.sandbox import SandboxedEnvironment from jinja2.sandbox import SandboxedEnvironment
from sphinx.util import mtimes_of_files from sphinx.util import mtimes_of_files
@ -36,6 +37,32 @@ def accesskey(context, key):
return '' return ''
class SphinxFileSystemLoader(FileSystemLoader):
"""FileSystemLoader subclass that is not so strict about '..'
entries in template names."""
def get_source(self, environment, template):
for searchpath in self.searchpath:
filename = path.join(searchpath, template)
f = open_if_exists(filename)
if f is None:
continue
try:
contents = f.read().decode(self.encoding)
finally:
f.close()
mtime = path.getmtime(filename)
def uptodate():
try:
return path.getmtime(filename) == mtime
except OSError:
return False
return contents, filename, uptodate
raise TemplateNotFound(template)
class BuiltinTemplateLoader(TemplateBridge, BaseLoader): class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
""" """
Interfaces the rendering environment of jinja2 for use in Sphinx. Interfaces the rendering environment of jinja2 for use in Sphinx.
@ -65,7 +92,7 @@ class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
self.pathchain = chain self.pathchain = chain
# make the paths into loaders # make the paths into loaders
self.loaders = map(FileSystemLoader, chain) self.loaders = map(SphinxFileSystemLoader, chain)
use_i18n = builder.translator is not None use_i18n = builder.translator is not None
extensions = use_i18n and ['jinja2.ext.i18n'] or [] extensions = use_i18n and ['jinja2.ext.i18n'] or []

View File

@ -835,12 +835,16 @@ class LaTeXTranslator(nodes.NodeVisitor):
res = "%.3f\\linewidth" % (float(amount) / 100.0) res = "%.3f\\linewidth" % (float(amount) / 100.0)
return res return res
def is_inline(self, node):
"""Check whether a node represents an inline element."""
return isinstance(node.parent, nodes.TextElement)
def visit_image(self, node): def visit_image(self, node):
attrs = node.attributes attrs = node.attributes
pre = [] # in reverse order pre = [] # in reverse order
post = [] post = []
include_graphics_options = [] include_graphics_options = []
inline = isinstance(node.parent, nodes.TextElement) is_inline = self.is_inline(node)
if attrs.has_key('scale'): if attrs.has_key('scale'):
# Could also be done with ``scale`` option to # Could also be done with ``scale`` option to
# ``\includegraphics``; doing it this way for consistency. # ``\includegraphics``; doing it this way for consistency.
@ -867,11 +871,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
(0, 'left'): ('{', '\\hfill}'), (0, 'left'): ('{', '\\hfill}'),
(0, 'right'): ('{\\hfill', '}'),} (0, 'right'): ('{\\hfill', '}'),}
try: try:
pre.append(align_prepost[inline, attrs['align']][0]) pre.append(align_prepost[is_inline, attrs['align']][0])
post.append(align_prepost[inline, attrs['align']][1]) post.append(align_prepost[is_inline, attrs['align']][1])
except KeyError: except KeyError:
pass # XXX complain here? pass # XXX complain here?
if not inline: if not is_inline:
pre.append('\n') pre.append('\n')
post.append('\n') post.append('\n')
pre.reverse() pre.reverse()
@ -1029,7 +1033,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.context.append('') self.context.append('')
elif uri.startswith('mailto:') or uri.startswith('http:') or \ elif uri.startswith('mailto:') or uri.startswith('http:') or \
uri.startswith('https:') or uri.startswith('ftp:'): uri.startswith('https:') or uri.startswith('ftp:'):
self.body.append('\\href{%s}{' % self.encode(uri)) self.body.append('\\href{%s}{' % self.encode_uri(uri))
self.context.append('}') self.context.append('}')
elif uri.startswith('#'): elif uri.startswith('#'):
self.body.append('\\hyperlink{%s}{' % uri[1:]) self.body.append('\\hyperlink{%s}{' % uri[1:])
@ -1330,6 +1334,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
text = text.replace('--', u'-{-}') text = text.replace('--', u'-{-}')
return text return text
def encode_uri(self, text):
# in \href, the tilde is allowed and must be represented literally
return self.encode(text).replace('\\textasciitilde{}', '~')
def visit_Text(self, node): def visit_Text(self, node):
if self.verbatim is not None: if self.verbatim is not None:
self.verbatim += node.astext() self.verbatim += node.astext()

View File

@ -1,3 +1,10 @@
Testing downloadable files
==========================
Download :download:`img.png` here.
Download :download:`this <subdir/img.png>` there.
Don't download :download:`this <nonexisting.png>`.
Test file and literal inclusion Test file and literal inclusion
=============================== ===============================
@ -42,9 +49,10 @@ Literalinclude options
:prepend: START CODE :prepend: START CODE
:append: END CODE :append: END CODE
Testing downloadable files Test if dedenting before parsing works.
==========================
Download :download:`img.png` here. .. highlight:: python
Download :download:`this <subdir/img.png>` there.
Don't download :download:`this <nonexisting.png>`. .. cssclass:: inc-pyobj-dedent
.. literalinclude:: literal.inc
:pyobject: Bar.baz

View File

@ -43,7 +43,7 @@ ENV_WARNINGS = """\
http://www.python.org/logo.png http://www.python.org/logo.png
%(root)s/includes.txt:: (WARNING/2) Encoding 'utf-8-sig' used for reading \ %(root)s/includes.txt:: (WARNING/2) Encoding 'utf-8-sig' used for reading \
included file u'wrongenc.inc' seems to be wrong, try giving an :encoding: option included file u'wrongenc.inc' seems to be wrong, try giving an :encoding: option
%(root)s/includes.txt:60: WARNING: download file not readable: nonexisting.png %(root)s/includes.txt:4: WARNING: download file not readable: nonexisting.png
""" """
HTML_WARNINGS = ENV_WARNINGS + """\ HTML_WARNINGS = ENV_WARNINGS + """\
@ -136,6 +136,8 @@ if pygments:
ur'^foo = u"Including Unicode characters: üöä"\n$', ur'^foo = u"Including Unicode characters: üöä"\n$',
".//div[@class='inc-preappend highlight-text']/div/pre": ".//div[@class='inc-preappend highlight-text']/div/pre":
r'(?m)^START CODE$', r'(?m)^START CODE$',
".//div[@class='inc-pyobj-dedent highlight-python']/div/pre/span":
r'def',
}) })
HTML_XPATH['subdir/includes.html'].update({ HTML_XPATH['subdir/includes.html'].update({
".//pre/span": 'line 1', ".//pre/span": 'line 1',

View File

@ -118,3 +118,6 @@ def test_latex_escaping():
u'\\begin{Verbatim}[commandchars=@\\[\\]]\n' u'\\begin{Verbatim}[commandchars=@\\[\\]]\n'
u'@PYGZat[]@(@Gamma@)\\@(@infty@)@$@PYGZlb[]@PYGZrb[]\n' u'@PYGZat[]@(@Gamma@)\\@(@infty@)@$@PYGZlb[]@PYGZrb[]\n'
u'\\end{Verbatim}') u'\\end{Verbatim}')
# in URIs
yield (verify, u'`test <http://example.com/~me/>`_', None,
u'\\href{http://example.com/~me/}{test}')