summaryrefslogtreecommitdiff
path: root/sphinx
diff options
context:
space:
mode:
authorshimizukawa <shimizukawa@gmail.com>2014-01-15 05:25:56 +0000
committershimizukawa <shimizukawa@gmail.com>2014-01-15 05:25:56 +0000
commitf458a7f06e8f18d446fc0bf7cb397b777cf1ef1d (patch)
treeb436c36a949d036d656363ad0e24b91ca8a39a4d /sphinx
parent8b375619a7a91d26f07f1ba944757700ae82827f (diff)
parentcbe7cad734728bdeee093066005c36e1598fa37e (diff)
downloadsphinx-f458a7f06e8f18d446fc0bf7cb397b777cf1ef1d.tar.gz
merge heads
Diffstat (limited to 'sphinx')
-rw-r--r--sphinx/addnodes.py5
-rw-r--r--sphinx/application.py4
-rw-r--r--sphinx/builders/html.py5
-rw-r--r--sphinx/builders/linkcheck.py90
-rw-r--r--sphinx/builders/text.py1
-rw-r--r--sphinx/cmdline.py13
-rw-r--r--sphinx/config.py35
-rw-r--r--sphinx/directives/__init__.py19
-rw-r--r--sphinx/directives/code.py19
-rw-r--r--sphinx/domains/c.py7
-rw-r--r--sphinx/domains/python.py23
-rw-r--r--sphinx/domains/std.py38
-rw-r--r--sphinx/environment.py9
-rw-r--r--sphinx/ext/autodoc.py22
-rw-r--r--sphinx/ext/autosummary/__init__.py3
-rw-r--r--sphinx/ext/autosummary/generate.py17
-rw-r--r--sphinx/ext/mathbase.py6
-rw-r--r--sphinx/ext/pngmath.py17
-rw-r--r--sphinx/ext/todo.py1
-rw-r--r--sphinx/highlighting.py22
-rw-r--r--sphinx/jinja2glue.py6
-rw-r--r--sphinx/locale/__init__.py2
-rw-r--r--sphinx/locale/cs/LC_MESSAGES/sphinx.mobin10472 -> 10669 bytes
-rw-r--r--sphinx/locale/cs/LC_MESSAGES/sphinx.po178
-rw-r--r--sphinx/locale/ja/LC_MESSAGES/sphinx.mobin11311 -> 11311 bytes
-rw-r--r--sphinx/locale/ja/LC_MESSAGES/sphinx.po4
-rw-r--r--sphinx/pycode/Grammar-py2.txt (renamed from sphinx/pycode/Grammar.txt)80
-rw-r--r--sphinx/pycode/Grammar-py3.txt126
-rw-r--r--sphinx/pycode/__init__.py4
-rw-r--r--sphinx/pycode/pgen2/driver.py7
-rw-r--r--sphinx/pycode/pgen2/grammar.py1
-rwxr-xr-xsphinx/pycode/pgen2/token.py3
-rw-r--r--sphinx/quickstart.py48
-rw-r--r--sphinx/roles.py6
-rw-r--r--sphinx/search/__init__.py17
-rw-r--r--sphinx/search/ja.py4
-rw-r--r--sphinx/texinputs/sphinx.sty8
-rw-r--r--sphinx/texinputs/sphinxmanual.cls3
-rw-r--r--sphinx/texinputs/tabulary.sty9
-rw-r--r--sphinx/themes/basic/static/basic.css_t1
-rw-r--r--sphinx/themes/basic/static/searchtools.js_t4
-rw-r--r--sphinx/themes/epub/static/epub.css1
-rw-r--r--sphinx/themes/haiku/layout.html2
-rw-r--r--sphinx/themes/scrolls/static/print.css12
-rw-r--r--sphinx/util/docfields.py6
-rw-r--r--sphinx/util/pycompat.py10
-rw-r--r--sphinx/writers/html.py42
-rw-r--r--sphinx/writers/latex.py90
-rw-r--r--sphinx/writers/manpage.py13
-rw-r--r--sphinx/writers/texinfo.py13
-rw-r--r--sphinx/writers/text.py15
51 files changed, 734 insertions, 337 deletions
diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py
index d8dca2ce..e3f6d7d6 100644
--- a/sphinx/addnodes.py
+++ b/sphinx/addnodes.py
@@ -168,6 +168,11 @@ class literal_emphasis(nodes.emphasis):
applied (e.g. smartypants for HTML output).
"""
+class literal_strong(nodes.strong):
+ """Node that behaves like `strong`, but further text processors are not
+ applied (e.g. smartypants for HTML output).
+ """
+
class abbreviation(nodes.Inline, nodes.TextElement):
"""Node for abbreviations with explanations."""
diff --git a/sphinx/application.py b/sphinx/application.py
index ceb7c32c..751f39b5 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -15,6 +15,7 @@ import os
import sys
import types
import posixpath
+import traceback
from os import path
from cStringIO import StringIO
@@ -122,7 +123,7 @@ class Sphinx(object):
self.config.setup(self)
# now that we know all config values, collect them from conf.py
- self.config.init_values()
+ self.config.init_values(self.warn)
# check the Sphinx version if requested
if self.config.needs_sphinx and \
@@ -282,6 +283,7 @@ class Sphinx(object):
try:
mod = __import__(extension, None, None, ['setup'])
except ImportError, err:
+ self.verbose('Original exception:\n' + traceback.format_exc())
raise ExtensionError('Could not import extension %s' % extension,
err)
if not hasattr(mod, 'setup'):
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index b0cde297..b6ebf926 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -593,7 +593,9 @@ class StandaloneHTMLBuilder(Builder):
if self.config.html_logo:
logobase = path.basename(self.config.html_logo)
logotarget = path.join(self.outdir, '_static', logobase)
- if not path.isfile(logotarget):
+ if not path.isfile(logobase):
+ self.warn('logo file %r does not exist' % logobase)
+ elif not path.isfile(logotarget):
copyfile(path.join(self.confdir, self.config.html_logo),
logotarget)
if self.config.html_favicon:
@@ -614,6 +616,7 @@ class StandaloneHTMLBuilder(Builder):
self.warn('html_extra_path entry %r does not exist' % entry)
continue
copy_static_entry(entry, self.outdir, self)
+ self.info('done')
def write_buildinfo(self):
# write build info file
diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py
index c3369b5a..171e68d5 100644
--- a/sphinx/builders/linkcheck.py
+++ b/sphinx/builders/linkcheck.py
@@ -14,17 +14,30 @@ import Queue
import socket
import threading
from os import path
-from urllib2 import build_opener, unquote, Request
+from urllib2 import build_opener, unquote, Request, \
+ HTTPError, HTTPRedirectHandler
from HTMLParser import HTMLParser, HTMLParseError
from docutils import nodes
from sphinx.builders import Builder
-from sphinx.util.console import purple, red, darkgreen, darkgray
+from sphinx.util.console import purple, red, darkgreen, darkgray, \
+ darkred, turquoise
+
+
+class RedirectHandler(HTTPRedirectHandler):
+ """A RedirectHandler that records the redirect code we got."""
+
+ def redirect_request(self, req, fp, code, msg, headers, newurl):
+ new_req = HTTPRedirectHandler.redirect_request(self, req, fp, code,
+ msg, headers, newurl)
+ req.redirect_code = code
+ return new_req
# create an opener that will simulate a browser user-agent
-opener = build_opener()
-opener.addheaders = [('User-agent', 'Mozilla/5.0')]
+opener = build_opener(RedirectHandler)
+opener.addheaders = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) '
+ 'Gecko/20100101 Firefox/25.0')]
class HeadRequest(Request):
@@ -103,18 +116,18 @@ class CheckExternalLinksBuilder(Builder):
# check for various conditions without bothering the network
if len(uri) == 0 or uri[0] == '#' or \
uri[0:7] == 'mailto:' or uri[0:4] == 'ftp:':
- return 'unchecked', ''
+ return 'unchecked', '', 0
elif not (uri[0:5] == 'http:' or uri[0:6] == 'https:'):
- return 'local', ''
+ return 'local', '', 0
elif uri in self.good:
- return 'working', ''
+ return 'working', '', 0
elif uri in self.broken:
- return 'broken', self.broken[uri]
+ return 'broken', self.broken[uri], 0
elif uri in self.redirected:
- return 'redirected', self.redirected[uri]
+ return 'redirected', self.redirected[uri][0], self.redirected[uri][1]
for rex in self.to_ignore:
if rex.match(uri):
- return 'ignored', ''
+ return 'ignored', '', 0
if '#' in uri:
req_url, hash = uri.split('#', 1)
@@ -126,61 +139,82 @@ class CheckExternalLinksBuilder(Builder):
try:
if hash and self.app.config.linkcheck_anchors:
# Read the whole document and see if #hash exists
- f = opener.open(Request(req_url), **kwargs)
+ req = Request(req_url)
+ f = opener.open(req, **kwargs)
found = check_anchor(f, unquote(hash))
f.close()
if not found:
raise Exception("Anchor '%s' not found" % hash)
else:
- f = opener.open(HeadRequest(req_url), **kwargs)
- f.close()
+ try:
+ # try a HEAD request, which should be easier on
+ # the server and the network
+ req = HeadRequest(req_url)
+ f = opener.open(req, **kwargs)
+ f.close()
+ except HTTPError, err:
+ if err.code != 405:
+ raise
+ # retry with GET if that fails, some servers
+ # don't like HEAD requests and reply with 405
+ req = Request(req_url)
+ f = opener.open(req, **kwargs)
+ f.close()
except Exception, err:
self.broken[uri] = str(err)
- return 'broken', str(err)
+ return 'broken', str(err), 0
if f.url.rstrip('/') == req_url.rstrip('/'):
self.good.add(uri)
- return 'working', 'new'
+ return 'working', 'new', 0
else:
new_url = f.url
if hash:
new_url += '#' + hash
-
- self.redirected[uri] = new_url
- return 'redirected', new_url
+ code = getattr(req, 'redirect_code', 0)
+ self.redirected[uri] = (new_url, code)
+ return 'redirected', new_url, code
while True:
uri, docname, lineno = self.wqueue.get()
if uri is None:
break
- status, info = check()
- self.rqueue.put((uri, docname, lineno, status, info))
+ status, info, code = check()
+ self.rqueue.put((uri, docname, lineno, status, info, code))
def process_result(self, result):
- uri, docname, lineno, status, info = result
+ uri, docname, lineno, status, info, code = result
if status == 'unchecked':
return
if status == 'working' and info != 'new':
return
if lineno:
- self.info('(line %3d) ' % lineno, nonl=1)
+ self.info('(line %4d) ' % lineno, nonl=1)
if status == 'ignored':
- self.info(uri + ' - ' + darkgray('ignored'))
+ self.info(darkgray('-ignored- ') + uri)
elif status == 'local':
- self.info(uri + ' - ' + darkgray('local'))
+ self.info(darkgray('-local- ') + uri)
self.write_entry('local', docname, lineno, uri)
elif status == 'working':
- self.info(uri + ' - ' + darkgreen('working'))
+ self.info(darkgreen('ok ') + uri)
elif status == 'broken':
- self.info(uri + ' - ' + red('broken: ') + info)
+ self.info(red('broken ') + uri + red(' - ' + info))
self.write_entry('broken', docname, lineno, uri + ': ' + info)
if self.app.quiet:
self.warn('broken link: %s' % uri,
'%s:%s' % (self.env.doc2path(docname), lineno))
elif status == 'redirected':
- self.info(uri + ' - ' + purple('redirected') + ' to ' + info)
- self.write_entry('redirected', docname, lineno, uri + ' to ' + info)
+ text, color = {
+ 301: ('permanently', darkred),
+ 302: ('with Found', purple),
+ 303: ('with See Other', purple),
+ 307: ('temporarily', turquoise),
+ 0: ('with unknown code', purple),
+ }[code]
+ self.write_entry('redirected ' + text, docname, lineno,
+ uri + ' to ' + info)
+ self.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
def get_target_uri(self, docname, typ=None):
return ''
diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py
index 4b73167b..f09ad654 100644
--- a/sphinx/builders/text.py
+++ b/sphinx/builders/text.py
@@ -54,6 +54,7 @@ class TextBuilder(Builder):
self.writer = TextWriter(self)
def write_doc(self, docname, doctree):
+ self.current_docname = docname
destination = StringOutput(encoding='utf-8')
self.writer.write(doctree, destination)
outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix)
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py
index e5ad3ab5..2d7146c3 100644
--- a/sphinx/cmdline.py
+++ b/sphinx/cmdline.py
@@ -173,14 +173,11 @@ def main(argv):
print >>sys.stderr, ('Error: -D option argument must be '
'in the form name=value.')
return 1
- try:
- val = int(val)
- except ValueError:
- if likely_encoding and isinstance(val, bytes):
- try:
- val = val.decode(likely_encoding)
- except UnicodeError:
- pass
+ if likely_encoding and isinstance(val, bytes):
+ try:
+ val = val.decode(likely_encoding)
+ except UnicodeError:
+ pass
confoverrides[key] = val
elif opt == '-A':
try:
diff --git a/sphinx/config.py b/sphinx/config.py
index 4cca4b35..df74e914 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -72,7 +72,7 @@ class Config(object):
primary_domain = ('py', 'env'),
needs_sphinx = (None, None),
nitpicky = (False, 'env'),
- nitpick_ignore = ([], 'env'),
+ nitpick_ignore = ([], 'html'),
# HTML options
html_theme = ('default', 'html'),
@@ -214,8 +214,11 @@ class Config(object):
self.overrides = overrides
self.values = Config.config_values.copy()
config = {}
- if "extensions" in overrides:
- config["extensions"] = overrides["extensions"]
+ if 'extensions' in overrides:
+ if isinstance(overrides['extensions'], (str, unicode)):
+ config['extensions'] = overrides.pop('extensions').split(',')
+ else:
+ config['extensions'] = overrides.pop('extensions')
if dirname is not None:
config_file = path.join(dirname, filename)
config['__file__'] = config_file
@@ -248,12 +251,36 @@ class Config(object):
'Please use Unicode strings, e.g. %r.' % (name, u'Content')
)
- def init_values(self):
+ def init_values(self, warn):
config = self._raw_config
for valname, value in self.overrides.iteritems():
if '.' in valname:
realvalname, key = valname.split('.', 1)
config.setdefault(realvalname, {})[key] = value
+ continue
+ elif valname not in self.values:
+ warn('unknown config value %r in override, ignoring' % valname)
+ continue
+ defvalue = self.values[valname][0]
+ if isinstance(value, (str, unicode)):
+ if isinstance(defvalue, dict):
+ warn('cannot override dictionary config setting %r, '
+ 'ignoring (use %r to set individual elements)' %
+ (valname, valname + '.key=value'))
+ continue
+ elif isinstance(defvalue, list):
+ config[valname] = value.split(',')
+ elif isinstance(defvalue, (int, long)):
+ try:
+ config[valname] = int(value)
+ except ValueError:
+ warn('invalid number %r for config value %r, ignoring'
+ % (value, valname))
+ elif defvalue is not None and not isinstance(defvalue, (str, unicode)):
+ warn('cannot override config setting %r with unsupported type, '
+ 'ignoring' % valname)
+ else:
+ config[valname] = value
else:
config[valname] = value
for name in config:
diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py
index 388522dc..3133b7e3 100644
--- a/sphinx/directives/__init__.py
+++ b/sphinx/directives/__init__.py
@@ -12,7 +12,6 @@
import re
from docutils.parsers.rst import Directive, directives
-from docutils.parsers.rst.directives import images
from sphinx import addnodes
from sphinx.util.docfields import DocFieldTransformer
@@ -22,15 +21,6 @@ from sphinx.directives.code import *
from sphinx.directives.other import *
-# allow units for the figure's "figwidth"
-try:
- images.Figure.option_spec['figwidth'] = \
- directives.length_or_percentage_or_unitless
-except AttributeError:
- images.figure.options['figwidth'] = \
- directives.length_or_percentage_or_unitless
-
-
# RE to strip backslash escapes
nl_escape_re = re.compile(r'\\\n')
strip_backslash_re = re.compile(r'\\(.)')
@@ -149,11 +139,12 @@ class ObjectDescription(Directive):
signode.clear()
signode += addnodes.desc_name(sig, sig)
continue # we don't want an index entry here
- if not noindex and name not in self.names:
- # only add target and index entry if this is the first
- # description of the object with this name in this desc block
+ if name not in self.names:
self.names.append(name)
- self.add_target_and_index(name, sig, signode)
+ if not noindex:
+ # only add target and index entry if this is the first
+ # description of the object with this name in this desc block
+ self.add_target_and_index(name, sig, signode)
contentnode = addnodes.desc_content()
node.append(contentnode)
diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py
index 4d43e5ff..7b1acfd5 100644
--- a/sphinx/directives/code.py
+++ b/sphinx/directives/code.py
@@ -56,6 +56,7 @@ class CodeBlock(Directive):
final_argument_whitespace = False
option_spec = {
'linenos': directives.flag,
+ 'lineno-start': int,
'emphasize-lines': directives.unchanged_required,
}
@@ -75,9 +76,13 @@ class CodeBlock(Directive):
literal = nodes.literal_block(code, code)
literal['language'] = self.arguments[0]
- literal['linenos'] = 'linenos' in self.options
+ literal['linenos'] = 'linenos' in self.options or \
+ 'lineno-start' in self.options
+ extra_args = literal['highlight_args'] = {}
if hl_lines is not None:
- literal['highlight_args'] = {'hl_lines': hl_lines}
+ extra_args['hl_lines'] = hl_lines
+ if 'lineno-start' in self.options:
+ extra_args['linenostart'] = self.options['lineno-start']
set_source_info(self, literal)
return [literal]
@@ -95,6 +100,7 @@ class LiteralInclude(Directive):
final_argument_whitespace = True
option_spec = {
'linenos': directives.flag,
+ 'lineno-start': int,
'tab-width': int,
'language': directives.unchanged_required,
'encoding': directives.encoding,
@@ -204,10 +210,13 @@ class LiteralInclude(Directive):
set_source_info(self, retnode)
if self.options.get('language', ''):
retnode['language'] = self.options['language']
- if 'linenos' in self.options:
- retnode['linenos'] = True
+ retnode['linenos'] = 'linenos' in self.options or \
+ 'lineno-start' in self.options
+ extra_args = retnode['highlight_args'] = {}
if hl_lines is not None:
- retnode['highlight_args'] = {'hl_lines': hl_lines}
+ extra_args['hl_lines'] = hl_lines
+ if 'lineno-start' in self.options:
+ extra_args['linenostart'] = self.options['lineno-start']
env.note_dependency(rel_filename)
return [retnode]
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index f9f2e664..aed5b47e 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -59,7 +59,12 @@ class CObject(ObjectDescription):
# These C types aren't described anywhere, so don't try to create
# a cross-reference to them
- stopwords = set(('const', 'void', 'char', 'int', 'long', 'FILE', 'struct'))
+ stopwords = set((
+ 'const', 'void', 'char', 'wchar_t', 'int', 'short',
+ 'long', 'float', 'double', 'unsigned', 'signed', 'FILE',
+ 'clock_t', 'time_t', 'ptrdiff_t', 'size_t', 'ssize_t',
+ 'struct', '_Bool',
+ ))
def _parse_type(self, node, ctype):
# add cross-ref nodes for all words
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index 0c08b60b..6714e838 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -81,6 +81,23 @@ def _pseudo_parse_arglist(signode, arglist):
signode += paramlist
+# This override allows our inline type specifiers to behave like :class: link
+# when it comes to handling "." and "~" prefixes.
+class PyTypedField(TypedField):
+ def make_xref(self, rolename, domain, target, innernode=nodes.emphasis):
+ result = super(PyTypedField, self).make_xref(rolename, domain, target,
+ innernode)
+ if target.startswith('.'):
+ result['reftarget'] = target[1:]
+ result['refspecific'] = True
+ result[0][0] = nodes.Text(target[1:])
+ if target.startswith('~'):
+ result['reftarget'] = target[1:]
+ title = target.split('.')[-1]
+ result[0][0] = nodes.Text(title)
+ return result
+
+
class PyObject(ObjectDescription):
"""
Description of a general Python object.
@@ -92,7 +109,7 @@ class PyObject(ObjectDescription):
}
doc_field_types = [
- TypedField('parameter', label=l_('Parameters'),
+ PyTypedField('parameter', label=l_('Parameters'),
names=('param', 'parameter', 'arg', 'argument',
'keyword', 'kwarg', 'kwparam'),
typerolename='obj', typenames=('paramtype', 'type'),
@@ -559,8 +576,8 @@ class PythonDomain(Domain):
object_types = {
'function': ObjType(l_('function'), 'func', 'obj'),
'data': ObjType(l_('data'), 'data', 'obj'),
- 'class': ObjType(l_('class'), 'class', 'obj'),
- 'exception': ObjType(l_('exception'), 'exc', 'obj'),
+ 'class': ObjType(l_('class'), 'class', 'exc', 'obj'),
+ 'exception': ObjType(l_('exception'), 'exc', 'class', 'obj'),
'method': ObjType(l_('method'), 'meth', 'obj'),
'classmethod': ObjType(l_('class method'), 'meth', 'obj'),
'staticmethod': ObjType(l_('static method'), 'meth', 'obj'),
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index ae67bf0e..895e35e5 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -27,8 +27,7 @@ from sphinx.util.compat import Directive
# RE for option descriptions
-option_desc_re = re.compile(
- r'((?:/|-|--)[-_a-zA-Z0-9]+)(\s*.*?)(?=,\s+(?:/|-|--)|$)')
+option_desc_re = re.compile(r'((?:/|-|--)[-_a-zA-Z0-9]+)(\s*.*)')
class GenericObject(ObjectDescription):
@@ -130,14 +129,23 @@ class Target(Directive):
class Cmdoption(ObjectDescription):
"""
- Description of a command-line option (.. cmdoption).
+ Description of a command-line option (.. option).
"""
def handle_signature(self, sig, signode):
"""Transform an option description into RST nodes."""
count = 0
firstname = ''
- for m in option_desc_re.finditer(sig):
+ for potential_option in sig.split(', '):
+ potential_option = potential_option.strip()
+ m = option_desc_re.match(potential_option)
+ if not m:
+ self.env.warn(
+ self.env.docname,
+ 'Malformed option description %r, should '
+ 'look like "-opt args", "--opt args" or '
+ '"/opt args"' % potential_option, self.lineno)
+ continue
optname, args = m.groups()
if count:
signode += addnodes.desc_addname(', ', ', ')
@@ -190,17 +198,26 @@ class Program(Directive):
class OptionXRefRole(XRefRole):
innernodeclass = addnodes.literal_emphasis
+ def _split(self, text, refnode, env):
+ try:
+ program, target = re.split(' (?=-|--|/)', text, 1)
+ except ValueError:
+ env.warn_node('Malformed :option: %r, does not contain option '
+ 'marker - or -- or /' % text, refnode)
+ return None, text
+ else:
+ program = ws_re.sub('-', program)
+ return program, target
+
def process_link(self, env, refnode, has_explicit_title, title, target):
program = env.temp_data.get('std:program')
if not has_explicit_title:
if ' ' in title and not (title.startswith('/') or
title.startswith('-')):
- program, target = re.split(' (?=-|--|/)', title, 1)
- program = ws_re.sub('-', program)
+ program, target = self._split(title, refnode, env)
target = target.strip()
elif ' ' in target:
- program, target = re.split(' (?=-|--|/)', target, 1)
- program = ws_re.sub('-', program)
+ program, target = self._split(target, refnode, env)
refnode['refprogram'] = program
return title, target
@@ -603,6 +620,11 @@ class StandardDomain(Domain):
self.object_types[type].attrs['searchprio'])
for name, info in self.data['labels'].iteritems():
yield (name, info[2], 'label', info[0], info[1], -1)
+ # add anonymous-only labels as well
+ non_anon_labels = set(self.data['labels'])
+ for name, info in self.data['anonlabels'].iteritems():
+ if name not in non_anon_labels:
+ yield (name, name, 'label', info[0], info[1], -1)
def get_type_name(self, type, primary=False):
# never prepend "Default"
diff --git a/sphinx/environment.py b/sphinx/environment.py
index 919ae710..a319ef3c 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -177,9 +177,6 @@ class BuildEnvironment:
# this is to invalidate old pickles
self.version = ENV_VERSION
- # make this a set for faster testing
- self._nitpick_ignore = set(self.config.nitpick_ignore)
-
# All "docnames" here are /-separated and relative and exclude
# the source suffix.
@@ -440,6 +437,9 @@ class BuildEnvironment:
self.find_files(config)
self.config = config
+ # this cache also needs to be updated every time
+ self._nitpick_ignore = set(self.config.nitpick_ignore)
+
added, changed, removed = self.get_outdated_files(config_changed)
# allow user intervention as well
@@ -1385,6 +1385,9 @@ class BuildEnvironment:
dtype = domain and '%s:%s' % (domain.name, typ) or typ
if (dtype, target) in self._nitpick_ignore:
warn = False
+ # for "std" types also try without domain name
+ if domain.name == 'std' and (typ, target) in self._nitpick_ignore:
+ warn = False
if not warn:
return
if domain and typ in domain.dangling_warnings:
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index 5ea64bf3..571f36cb 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -450,9 +450,10 @@ class Documenter(object):
# into lines
if isinstance(docstring, unicode):
return [prepare_docstring(docstring, ignore)]
- elif docstring:
+ elif isinstance(docstring, str): # this will not trigger on Py3
return [prepare_docstring(force_decode(docstring, encoding),
ignore)]
+ # ... else it is something strange, let's ignore it
return []
def process_doc(self, docstrings):
@@ -1052,7 +1053,7 @@ class ClassDocumenter(ModuleLevelDocumenter):
# add inheritance info, if wanted
if not self.doc_as_attr and self.options.show_inheritance:
self.add_line(u'', '<autodoc>')
- if len(self.object.__bases__):
+ if hasattr(self.object, '__bases__') and len(self.object.__bases__):
bases = [b.__module__ == '__builtin__' and
u':class:`%s`' % b.__name__ or
u':class:`%s.%s`' % (b.__module__, b.__name__)
@@ -1084,7 +1085,8 @@ class ClassDocumenter(ModuleLevelDocumenter):
initdocstring = self.get_attr(
self.get_attr(self.object, '__init__', None), '__doc__')
# for new-style classes, no __init__ means default __init__
- if initdocstring == object.__init__.__doc__:
+ if (initdocstring == object.__init__.__doc__ or # for pypy
+ initdocstring.strip() == object.__init__.__doc__): #for !pypy
initdocstring = None
if initdocstring:
if content == 'init':
@@ -1243,7 +1245,8 @@ class AttributeDocumenter(ClassLevelDocumenter):
def can_document_member(cls, member, membername, isattr, parent):
isdatadesc = isdescriptor(member) and not \
isinstance(member, cls.method_types) and not \
- type(member).__name__ in ("type", "method_descriptor")
+ type(member).__name__ in ("type", "method_descriptor",
+ "instancemethod")
return isdatadesc or (not isinstance(parent, ModuleDocumenter)
and not inspect.isroutine(member)
and not isinstance(member, class_types))
@@ -1383,8 +1386,15 @@ class AutoDirective(Directive):
not negated:
self.options[flag] = None
# process the options with the selected documenter's option_spec
- self.genopt = Options(assemble_option_dict(
- self.options.items(), doc_class.option_spec))
+ try:
+ self.genopt = Options(assemble_option_dict(
+ self.options.items(), doc_class.option_spec))
+ except (KeyError, ValueError, TypeError), err:
+ # an option is either unknown or has a wrong type
+ msg = self.reporter.error('An option to %s is either unknown or '
+ 'has an invalid value: %s' % (self.name, err),
+ line=self.lineno)
+ return [msg]
# generate the output
documenter = doc_class(self, self.arguments[0])
documenter.generate(more_content=self.content)
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index a73e79f5..af0fa65c 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -199,7 +199,6 @@ class Autosummary(Directive):
nodes = self.get_table(items)
if 'toctree' in self.options:
- suffix = env.config.source_suffix
dirname = posixpath.dirname(env.docname)
tree_prefix = self.options['toctree'].strip()
@@ -276,7 +275,7 @@ class Autosummary(Directive):
while doc and not doc[0].strip():
doc.pop(0)
- m = re.search(r"^([A-Z][^A-Z]*?\.\s)", " ".join(doc).strip())
+ m = re.search(r"^([A-Z].*?\.)(?:\s|$)", " ".join(doc).strip())
if m:
summary = m.group(1).strip()
elif doc:
diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py
index 0640a332..f45aa085 100644
--- a/sphinx/ext/autosummary/generate.py
+++ b/sphinx/ext/autosummary/generate.py
@@ -33,6 +33,21 @@ from sphinx.jinja2glue import BuiltinTemplateLoader
from sphinx.util.osutil import ensuredir
from sphinx.util.inspect import safe_getattr
+# Add documenters to AutoDirective registry
+from sphinx.ext.autodoc import add_documenter, \
+ ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, \
+ FunctionDocumenter, MethodDocumenter, AttributeDocumenter, \
+ InstanceAttributeDocumenter
+add_documenter(ModuleDocumenter)
+add_documenter(ClassDocumenter)
+add_documenter(ExceptionDocumenter)
+add_documenter(DataDocumenter)
+add_documenter(FunctionDocumenter)
+add_documenter(MethodDocumenter)
+add_documenter(AttributeDocumenter)
+add_documenter(InstanceAttributeDocumenter)
+
+
def main(argv=sys.argv):
usage = """%prog [OPTIONS] SOURCEFILE ..."""
p = optparse.OptionParser(usage.strip())
@@ -101,7 +116,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
new_files = []
# write
- for name, path, template_name in sorted(items):
+ for name, path, template_name in sorted(items, key=str):
if path is None:
# The corresponding autosummary:: directive did not have
# a :toctree: option
diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py
index 3955e4bc..0c5eaf8b 100644
--- a/sphinx/ext/mathbase.py
+++ b/sphinx/ext/mathbase.py
@@ -30,11 +30,15 @@ def wrap_displaymath(math, label):
parts = math.split('\n\n')
ret = []
for i, part in enumerate(parts):
+ if not part.strip():
+ continue
if label is not None and i == 0:
ret.append('\\begin{split}%s\\end{split}' % part +
(label and '\\label{'+label+'}' or ''))
else:
ret.append('\\begin{split}%s\\end{split}\\notag' % part)
+ if not ret:
+ return ''
return '\\begin{gather}\n' + '\\\\'.join(ret) + '\n\\end{gather}'
@@ -84,7 +88,7 @@ class MathDirective(Directive):
def latex_visit_math(self, node):
- self.body.append('$' + node['latex'] + '$')
+ self.body.append('\\(' + node['latex'] + '\\)')
raise nodes.SkipNode
def latex_visit_displaymath(self, node):
diff --git a/sphinx/ext/pngmath.py b/sphinx/ext/pngmath.py
index 3938dab1..e23bbd06 100644
--- a/sphinx/ext/pngmath.py
+++ b/sphinx/ext/pngmath.py
@@ -26,7 +26,7 @@ from docutils import nodes
from sphinx.errors import SphinxError
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.osutil import ensuredir, ENOENT
-from sphinx.util.pycompat import b
+from sphinx.util.pycompat import b, sys_encoding
from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath
class MathExtError(SphinxError):
@@ -34,9 +34,9 @@ class MathExtError(SphinxError):
def __init__(self, msg, stderr=None, stdout=None):
if stderr:
- msg += '\n[stderr]\n' + stderr
+ msg += '\n[stderr]\n' + stderr.decode(sys_encoding, 'replace')
if stdout:
- msg += '\n[stdout]\n' + stdout
+ msg += '\n[stdout]\n' + stdout.decode(sys_encoding, 'replace')
SphinxError.__init__(self, msg)
@@ -82,8 +82,10 @@ def render_math(self, math):
may not fail since that indicates a problem in the math source.
"""
use_preview = self.builder.config.pngmath_use_preview
+ latex = DOC_HEAD + self.builder.config.pngmath_latex_preamble
+ latex += (use_preview and DOC_BODY_PREVIEW or DOC_BODY) % math
- shasum = "%s.png" % sha(math.encode('utf-8')).hexdigest()
+ shasum = "%s.png" % sha(latex.encode('utf-8')).hexdigest()
relfn = posixpath.join(self.builder.imgpath, 'math', shasum)
outfn = path.join(self.builder.outdir, '_images', 'math', shasum)
if path.isfile(outfn):
@@ -95,9 +97,6 @@ def render_math(self, math):
hasattr(self.builder, '_mathpng_warned_dvipng'):
return None, None
- latex = DOC_HEAD + self.builder.config.pngmath_latex_preamble
- latex += (use_preview and DOC_BODY_PREVIEW or DOC_BODY) % math
-
# use only one tempdir per build -- the use of a directory is cleaner
# than using temporary files, since we can clean up everything at once
# just removing the whole directory (see cleanup_tempdir)
@@ -192,11 +191,11 @@ def html_visit_math(self, node):
try:
fname, depth = render_math(self, '$'+node['latex']+'$')
except MathExtError, exc:
- msg = unicode(str(exc), 'utf-8', 'replace')
+ msg = unicode(exc)
sm = nodes.system_message(msg, type='WARNING', level=2,
backrefs=[], source=node['latex'])
sm.walkabout(self)
- self.builder.warn('display latex %r: ' % node['latex'] + str(exc))
+ self.builder.warn('display latex %r: ' % node['latex'] + msg)
raise nodes.SkipNode
if fname is None:
# something failed -- use text-only as a bad substitute
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index de5d2b9f..253ae07d 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -171,4 +171,3 @@ def setup(app):
app.connect('doctree-read', process_todos)
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)
-
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index 807a1826..c30c9ef3 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -159,7 +159,7 @@ class PygmentsBridge(object):
if self.try_parse(source):
lexer = lexers['python']
else:
- return self.unhighlighted(source)
+ lexer = lexers['none']
else:
lexer = lexers['python']
elif lang in ('python3', 'py3') and source.startswith('>>>'):
@@ -169,7 +169,7 @@ class PygmentsBridge(object):
try:
lexer = guess_lexer(source)
except Exception:
- return self.unhighlighted(source)
+ lexer = lexers['none']
else:
if lang in lexers:
lexer = lexers[lang]
@@ -179,7 +179,7 @@ class PygmentsBridge(object):
except ClassNotFound:
if warn:
warn('Pygments lexer name %r is not known' % lang)
- return self.unhighlighted(source)
+ lexer = lexers['none']
else:
raise
else:
@@ -191,19 +191,19 @@ class PygmentsBridge(object):
source = doctest.doctestopt_re.sub('', source)
# highlight via Pygments
+ formatter = self.get_formatter(**kwargs)
try:
- formatter = self.get_formatter(**kwargs)
hlsource = highlight(source, lexer, formatter)
- if self.dest == 'html':
- return hlsource
- else:
- if not isinstance(hlsource, unicode): # Py2 / Pygments < 1.6
- hlsource = hlsource.decode()
- return hlsource.translate(tex_hl_escape_map_new)
except ErrorToken:
# this is most probably not the selected language,
# so let it pass unhighlighted
- return self.unhighlighted(source)
+ hlsource = highlight(source, lexers['none'], formatter)
+ if self.dest == 'html':
+ return hlsource
+ else:
+ if not isinstance(hlsource, unicode): # Py2 / Pygments < 1.6
+ hlsource = hlsource.decode()
+ return hlsource.translate(tex_hl_escape_map_new)
def get_stylesheet(self):
if not pygments:
diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py
index 300cfef6..a298d2ea 100644
--- a/sphinx/jinja2glue.py
+++ b/sphinx/jinja2glue.py
@@ -95,9 +95,11 @@ class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
# then the theme parent paths
loaderchain = pathchain + theme.themepath
elif dirs:
- pathchain = loaderchain = list(dirs)
+ pathchain = list(dirs)
+ loaderchain = list(dirs)
else:
- pathchain = loaderchain = []
+ pathchain = []
+ loaderchain = []
# prepend explicit template paths
self.templatepathlen = len(builder.config.templates_path)
diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py
index 96da67d6..06a11a6e 100644
--- a/sphinx/locale/__init__.py
+++ b/sphinx/locale/__init__.py
@@ -215,7 +215,7 @@ def init(locale_dirs, language, catalog='sphinx'):
except Exception:
# Language couldn't be found in the specified path
pass
- # guarantee translations[catalog] exists
+ # guarantee translators[catalog] exists
if translator is None:
translator = gettext.NullTranslations()
has_translation = False
diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.mo b/sphinx/locale/cs/LC_MESSAGES/sphinx.mo
index 972f39de..79f22853 100644
--- a/sphinx/locale/cs/LC_MESSAGES/sphinx.mo
+++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.mo
Binary files differ
diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.po b/sphinx/locale/cs/LC_MESSAGES/sphinx.po
index 2a4722dc..76b26189 100644
--- a/sphinx/locale/cs/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.po
@@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: Sphinx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2013-04-02 10:33+0200\n"
-"PO-Revision-Date: 2013-04-02 15:12+0000\n"
-"Last-Translator: birkenfeld <g.brandl@gmx.net>\n"
+"PO-Revision-Date: 2013-12-26 13:32+0000\n"
+"Last-Translator: pm13 <petr.marhoun@gmail.com>\n"
"Language-Team: Czech (http://www.transifex.com/projects/p/sphinx-1/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -22,21 +22,21 @@ msgstr ""
#: sphinx/config.py:81
#, python-format
msgid "%s %s documentation"
-msgstr ""
+msgstr "Dokumentace pro %s %s"
#: sphinx/environment.py:1510
#, python-format
msgid "see %s"
-msgstr ""
+msgstr "viz %s"
#: sphinx/environment.py:1513
#, python-format
msgid "see also %s"
-msgstr ""
+msgstr "viz také %s"
#: sphinx/environment.py:1570
msgid "Symbols"
-msgstr ""
+msgstr "Symboly"
#: sphinx/roles.py:175
#, python-format
@@ -55,7 +55,7 @@ msgstr "Vestavěné funkce"
#: sphinx/builders/changes.py:75
msgid "Module level"
-msgstr "Úroveň modulů"
+msgstr "Úroveň modulu"
#: sphinx/builders/html.py:290
#, python-format
@@ -64,11 +64,11 @@ msgstr "%d.%m.%Y"
#: sphinx/builders/html.py:309 sphinx/themes/basic/defindex.html:30
msgid "General Index"
-msgstr "Rejstřík indexů"
+msgstr "Obecný rejstřík"
#: sphinx/builders/html.py:309
msgid "index"
-msgstr "index"
+msgstr "rejstřík"
#: sphinx/builders/html.py:369
msgid "next"
@@ -80,7 +80,7 @@ msgstr "předchozí"
#: sphinx/builders/latex.py:141 sphinx/builders/texinfo.py:196
msgid " (in "
-msgstr "(v"
+msgstr " (v "
#: sphinx/directives/other.py:138
msgid "Section author: "
@@ -92,7 +92,7 @@ msgstr "Autor modulu: "
#: sphinx/directives/other.py:142
msgid "Code author: "
-msgstr ""
+msgstr "Autor kódu:"
#: sphinx/directives/other.py:144
msgid "Author: "
@@ -101,7 +101,7 @@ msgstr "Autor: "
#: sphinx/domains/__init__.py:244
#, python-format
msgid "%s %s"
-msgstr ""
+msgstr "%s %s"
#: sphinx/domains/c.py:51 sphinx/domains/cpp.py:939
#: sphinx/domains/python.py:95
@@ -126,7 +126,7 @@ msgstr "%s (C funkce)"
#: sphinx/domains/c.py:143
#, python-format
msgid "%s (C member)"
-msgstr "%s (člen C)"
+msgstr "%s (C člen)"
#: sphinx/domains/c.py:145
#, python-format
@@ -154,7 +154,7 @@ msgstr "člen"
#: sphinx/domains/c.py:205
msgid "macro"
-msgstr ""
+msgstr "makro"
#: sphinx/domains/c.py:206 sphinx/domains/cpp.py:1209
msgid "type"
@@ -162,11 +162,11 @@ msgstr "typ"
#: sphinx/domains/c.py:207
msgid "variable"
-msgstr ""
+msgstr "proměnná"
#: sphinx/domains/cpp.py:942 sphinx/domains/javascript.py:125
msgid "Throws"
-msgstr ""
+msgstr "Vyvolá"
#: sphinx/domains/cpp.py:1038
#, python-format
@@ -181,7 +181,7 @@ msgstr "%s (C++ typ)"
#: sphinx/domains/cpp.py:1081
#, python-format
msgid "%s (C++ member)"
-msgstr "%s (člen C++)"
+msgstr "%s (C++ člen)"
#: sphinx/domains/cpp.py:1137
#, python-format
@@ -211,20 +211,20 @@ msgstr "%s() (třída)"
#: sphinx/domains/javascript.py:111
#, python-format
msgid "%s (global variable or constant)"
-msgstr ""
+msgstr "%s (globální proměnná nebo konstanta)"
#: sphinx/domains/javascript.py:113 sphinx/domains/python.py:355
#, python-format
msgid "%s (%s attribute)"
-msgstr "%s() (atribut %s)"
+msgstr "%s (atribut %s)"
#: sphinx/domains/javascript.py:122
msgid "Arguments"
-msgstr ""
+msgstr "Argumenty"
#: sphinx/domains/javascript.py:166 sphinx/domains/python.py:561
msgid "data"
-msgstr ""
+msgstr "data"
#: sphinx/domains/javascript.py:167 sphinx/domains/python.py:567
msgid "attribute"
@@ -232,7 +232,7 @@ msgstr "atribut"
#: sphinx/domains/python.py:100
msgid "Variables"
-msgstr ""
+msgstr "Proměnné"
#: sphinx/domains/python.py:104
msgid "Raises"
@@ -247,22 +247,22 @@ msgstr "%s() (v modulu %s)"
#: sphinx/domains/python.py:257
#, python-format
msgid "%s (built-in variable)"
-msgstr "%s() (vestavěná proměnná)"
+msgstr "%s (vestavěná proměnná)"
#: sphinx/domains/python.py:258 sphinx/domains/python.py:349
#, python-format
msgid "%s (in module %s)"
-msgstr "%s() (v modulu %s)"
+msgstr "%s (v modulu %s)"
#: sphinx/domains/python.py:274
#, python-format
msgid "%s (built-in class)"
-msgstr "%s () (vestavěná proměnná)"
+msgstr "%s (vestavěná třída)"
#: sphinx/domains/python.py:275
#, python-format
msgid "%s (class in %s)"
-msgstr "%s() (třída v %s)"
+msgstr "%s (třída v %s)"
#: sphinx/domains/python.py:315
#, python-format
@@ -282,26 +282,26 @@ msgstr "%s() (statická metoda %s)"
#: sphinx/domains/python.py:340
#, python-format
msgid "%s() (%s.%s class method)"
-msgstr ""
+msgstr "%s() (třídní metoda %s.%s)"
#: sphinx/domains/python.py:343
#, python-format
msgid "%s() (%s class method)"
-msgstr ""
+msgstr "%s() (třídní metoda %s)"
#: sphinx/domains/python.py:353
#, python-format
msgid "%s (%s.%s attribute)"
-msgstr "%s() (atribut %s.%s)"
+msgstr "%s (atribut %s.%s)"
#: sphinx/domains/python.py:434
#, python-format
msgid "%s (module)"
-msgstr "%s (module)"
+msgstr "%s (modul)"
#: sphinx/domains/python.py:491
msgid "Python Module Index"
-msgstr ""
+msgstr "Rejstřík modulů Pythonu"
#: sphinx/domains/python.py:492
msgid "modules"
@@ -317,11 +317,11 @@ msgstr "výjimka"
#: sphinx/domains/python.py:564
msgid "method"
-msgstr ""
+msgstr "metoda"
#: sphinx/domains/python.py:565
msgid "class method"
-msgstr ""
+msgstr "třídní metoda"
#: sphinx/domains/python.py:566
msgid "static method"
@@ -338,50 +338,50 @@ msgstr " (zastaralé)"
#: sphinx/domains/rst.py:53
#, python-format
msgid "%s (directive)"
-msgstr ""
+msgstr "%s (direktiva)"
#: sphinx/domains/rst.py:55
#, python-format
msgid "%s (role)"
-msgstr ""
+msgstr "%s (role)"
#: sphinx/domains/rst.py:104
msgid "directive"
-msgstr ""
+msgstr "direktiva"
#: sphinx/domains/rst.py:105
msgid "role"
-msgstr ""
+msgstr "role"
#: sphinx/domains/std.py:70 sphinx/domains/std.py:86
#, python-format
msgid "environment variable; %s"
-msgstr "promměná prostředí, %s"
+msgstr "proměnná prostředí; %s"
#: sphinx/domains/std.py:162
#, python-format
msgid "%scommand line option; %s"
-msgstr "%s parametry příkazového řádku; %s"
+msgstr "%svolba příkazového řádku; %s"
#: sphinx/domains/std.py:414
msgid "glossary term"
-msgstr ""
+msgstr "termín v glosáři"
#: sphinx/domains/std.py:415
msgid "grammar token"
-msgstr ""
+msgstr "token gramatiky"
#: sphinx/domains/std.py:416
msgid "reference label"
-msgstr ""
+msgstr "referenční návěstí"
#: sphinx/domains/std.py:418
msgid "environment variable"
-msgstr "promměná prostředí"
+msgstr "proměnná prostředí"
#: sphinx/domains/std.py:419
msgid "program option"
-msgstr ""
+msgstr "volba programu"
#: sphinx/domains/std.py:449 sphinx/themes/basic/genindex-single.html:32
#: sphinx/themes/basic/genindex-single.html:57
@@ -391,11 +391,11 @@ msgstr ""
#: sphinx/themes/basic/genindex.html:68 sphinx/themes/basic/layout.html:134
#: sphinx/writers/latex.py:191 sphinx/writers/texinfo.py:475
msgid "Index"
-msgstr "Index"
+msgstr "Rejstřík"
#: sphinx/domains/std.py:450
msgid "Module Index"
-msgstr "Rejstřík modulů "
+msgstr "Rejstřík modulů"
#: sphinx/domains/std.py:451 sphinx/themes/basic/defindex.html:25
msgid "Search Page"
@@ -404,42 +404,42 @@ msgstr "Vyhledávací stránka"
#: sphinx/ext/autodoc.py:1042
#, python-format
msgid " Bases: %s"
-msgstr ""
+msgstr " Nadtřídy: %s"
#: sphinx/ext/autodoc.py:1078
#, python-format
msgid "alias of :class:`%s`"
-msgstr ""
+msgstr "alias třídy :class:`%s`"
#: sphinx/ext/graphviz.py:294 sphinx/ext/graphviz.py:302
#, python-format
msgid "[graph: %s]"
-msgstr ""
+msgstr "[graf: %s]"
#: sphinx/ext/graphviz.py:296 sphinx/ext/graphviz.py:304
msgid "[graph]"
-msgstr ""
+msgstr "[graf]"
#: sphinx/ext/intersphinx.py:234
#, python-format
msgid "(in %s v%s)"
-msgstr ""
+msgstr "(v %s v%s)"
#: sphinx/ext/linkcode.py:66 sphinx/ext/viewcode.py:70
msgid "[source]"
-msgstr ""
+msgstr "[zdroj]"
#: sphinx/ext/refcounting.py:83
msgid "Return value: Always NULL."
-msgstr ""
+msgstr "Navrácená hodnota: Vždy NULL."
#: sphinx/ext/refcounting.py:85
msgid "Return value: New reference."
-msgstr ""
+msgstr "Navrácená hodnota: Nová reference."
#: sphinx/ext/refcounting.py:87
msgid "Return value: Borrowed reference."
-msgstr ""
+msgstr "Navrácená hodnota: Vypůjčená reference."
#: sphinx/ext/todo.py:42
msgid "Todo"
@@ -448,32 +448,32 @@ msgstr "Todo"
#: sphinx/ext/todo.py:110
#, python-format
msgid "(The <<original entry>> is located in %s, line %d.)"
-msgstr ""
+msgstr "(<<original entry>> se nachází v %s, řádka %d.)"
#: sphinx/ext/todo.py:119
msgid "original entry"
-msgstr ""
+msgstr "původní záznam"
#: sphinx/ext/viewcode.py:117
msgid "[docs]"
-msgstr ""
+msgstr "[dokumentace]"
#: sphinx/ext/viewcode.py:131
msgid "Module code"
-msgstr ""
+msgstr "Kód modulu"
#: sphinx/ext/viewcode.py:137
#, python-format
msgid "<h1>Source code for %s</h1>"
-msgstr ""
+msgstr "<h1>Zdrojový kód pro %s</h1>"
#: sphinx/ext/viewcode.py:164
msgid "Overview: module code"
-msgstr ""
+msgstr "Přehled: kód modulu"
#: sphinx/ext/viewcode.py:165
msgid "<h1>All modules for which code is available</h1>"
-msgstr ""
+msgstr "<h1>Všechny moduly s dostupným kódem</h1>"
#: sphinx/locale/__init__.py:155
msgid "Attention"
@@ -559,15 +559,15 @@ msgstr "Obsah"
#: sphinx/themes/basic/search.html:11 sphinx/themes/basic/search.html:23
#: sphinx/themes/basic/searchresults.html:10
msgid "Search"
-msgstr "Hledání"
+msgstr "Vyhledávání"
#: sphinx/themes/agogo/layout.html:53 sphinx/themes/basic/searchbox.html:15
msgid "Go"
-msgstr "hledej"
+msgstr "OK"
#: sphinx/themes/agogo/layout.html:58 sphinx/themes/basic/searchbox.html:20
msgid "Enter search terms or a module, class or function name."
-msgstr ""
+msgstr "Zadejte hledané termíny nebo jméno modulu, třídy či funkce."
#: sphinx/themes/agogo/layout.html:79 sphinx/themes/basic/sourcelink.html:14
msgid "Show Source"
@@ -579,15 +579,15 @@ msgstr "Přehled"
#: sphinx/themes/basic/defindex.html:15
msgid "Welcome! This is"
-msgstr ""
+msgstr "Vítejte! Toto je"
#: sphinx/themes/basic/defindex.html:16
msgid "the documentation for"
-msgstr ""
+msgstr "dokumentace pro"
#: sphinx/themes/basic/defindex.html:17
msgid "last updated"
-msgstr ""
+msgstr "naposledy aktualizováno"
#: sphinx/themes/basic/defindex.html:20
msgid "Indices and tables:"
@@ -603,7 +603,7 @@ msgstr "seznam všech sekcí a podsekcí"
#: sphinx/themes/basic/defindex.html:26
msgid "search this documentation"
-msgstr "prohledej tuto dokumentaci"
+msgstr "prohledat tuto dokumentaci"
#: sphinx/themes/basic/defindex.html:28
msgid "Global Module Index"
@@ -620,18 +620,18 @@ msgstr "všechny funkce, třídy, termíny"
#: sphinx/themes/basic/genindex-single.html:35
#, python-format
msgid "Index &ndash; %(key)s"
-msgstr "Index &ndash; %(key)s"
+msgstr "Rejstřík &ndash; %(key)s"
#: sphinx/themes/basic/genindex-single.html:63
#: sphinx/themes/basic/genindex-split.html:24
#: sphinx/themes/basic/genindex-split.html:38
#: sphinx/themes/basic/genindex.html:74
msgid "Full index on one page"
-msgstr "Plný index na jedné stránce"
+msgstr "Celý rejstřík na jedné stránce"
#: sphinx/themes/basic/genindex-split.html:16
msgid "Index pages by letter"
-msgstr "Index podle písmene"
+msgstr "Rejstřík podle písmene"
#: sphinx/themes/basic/genindex-split.html:25
msgid "can be huge"
@@ -644,7 +644,7 @@ msgstr "Navigace"
#: sphinx/themes/basic/layout.html:122
#, python-format
msgid "Search within %(docstitle)s"
-msgstr "Hledání uvnitř %(docstitle)s"
+msgstr "Prohledat %(docstitle)s"
#: sphinx/themes/basic/layout.html:131
msgid "About these documents"
@@ -701,7 +701,7 @@ msgstr "další kapitola"
msgid ""
"Please activate JavaScript to enable the search\n"
" functionality."
-msgstr ""
+msgstr "Pro podporu vyhledávání aktivujte JavaScript."
#: sphinx/themes/basic/search.html:32
msgid ""
@@ -709,18 +709,18 @@ msgid ""
" words into the box below and click \"search\". Note that the search\n"
" function will automatically search for all of the words. Pages\n"
" containing fewer words won't appear in the result list."
-msgstr "Toto je vyhledávací stránka. Zadejte klíčová slova a klikněte na \"hledej\". \nVyhledávání hledá automaticky všechna slova. Nebudou tedy nalezeny stránky, obsahující méně slov."
+msgstr "Toto je vyhledávací stránka. Zadejte klíčová slova a klikněte na \"hledat\". \nVyhledávání automaticky hledá všechna slova, nebudou tedy nalezeny stránky obsahující jen některé z nich."
#: sphinx/themes/basic/search.html:39
#: sphinx/themes/basic/searchresults.html:17
msgid "search"
-msgstr "hledej"
+msgstr "hledat"
#: sphinx/themes/basic/search.html:43
#: sphinx/themes/basic/searchresults.html:21
#: sphinx/themes/basic/static/searchtools.js_t:281
msgid "Search Results"
-msgstr "Výsledky hledání"
+msgstr "Výsledky vyhledávání"
#: sphinx/themes/basic/search.html:45
#: sphinx/themes/basic/searchresults.html:23
@@ -728,7 +728,7 @@ msgstr "Výsledky hledání"
msgid ""
"Your search did not match any documents. Please make sure that all words are"
" spelled correctly and that you've selected enough categories."
-msgstr ""
+msgstr "Vyhledávání nenalezlo žádný odpovídající dokument. Ujistěte se, že jste všechna slova zapsal/a správně a že jste vybral/a dostatek kategorií."
#: sphinx/themes/basic/searchbox.html:12
msgid "Quick search"
@@ -781,33 +781,33 @@ msgstr "Skrýt výsledky vyhledávání"
#: sphinx/themes/basic/static/searchtools.js_t:119
msgid "Searching"
-msgstr ""
+msgstr "Probíhá vyhledání"
#: sphinx/themes/basic/static/searchtools.js_t:124
msgid "Preparing search..."
-msgstr ""
+msgstr "Vyhledávání se připravuje..."
#: sphinx/themes/basic/static/searchtools.js_t:285
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
-msgstr ""
+msgstr "Vyhledávání dokončeno, stránky odpovídající hledanému výrazu: %s."
#: sphinx/themes/basic/static/searchtools.js_t:337
msgid ", in "
-msgstr ""
+msgstr ", v "
#: sphinx/themes/default/static/sidebar.js_t:83
msgid "Expand sidebar"
-msgstr ""
+msgstr "Rozbalit boční lištu"
#: sphinx/themes/default/static/sidebar.js_t:96
#: sphinx/themes/default/static/sidebar.js_t:124
msgid "Collapse sidebar"
-msgstr ""
+msgstr "Sbalit boční lištu"
#: sphinx/themes/haiku/layout.html:26
msgid "Contents"
-msgstr ""
+msgstr "Obsah"
#: sphinx/writers/latex.py:189
msgid "Release"
@@ -816,20 +816,20 @@ msgstr "Vydání"
#: sphinx/writers/latex.py:620 sphinx/writers/manpage.py:181
#: sphinx/writers/texinfo.py:612
msgid "Footnotes"
-msgstr ""
+msgstr "Poznámky pod čarou"
#: sphinx/writers/latex.py:704
msgid "continued from previous page"
-msgstr ""
+msgstr "pokračujte na předchozí stránce"
#: sphinx/writers/latex.py:710
msgid "Continued on next page"
-msgstr ""
+msgstr "Pokračujte na další stránce"
#: sphinx/writers/manpage.py:226 sphinx/writers/text.py:541
#, python-format
msgid "[image: %s]"
-msgstr ""
+msgstr "[obrázek: %s]"
#: sphinx/writers/manpage.py:227 sphinx/writers/text.py:542
msgid "[image]"
diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo
index 67e2656f..82b838b0 100644
--- a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo
+++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo
Binary files differ
diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.po b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
index a6fbb348..7906d68b 100644
--- a/sphinx/locale/ja/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
@@ -3,7 +3,7 @@
# This file is distributed under the same license as the Sphinx project.
#
# Translators:
-# しろう, 2013
+# shirou - しろう, 2013
# Akitoshi Ohta <fire.kuma8@gmail.com>, 2011
# Kouhei Sutou <kou@clear-code.com>, 2011
# Takayuki Shimizukawa <shimizukawa@gmail.com>, 2013
@@ -13,7 +13,7 @@ msgstr ""
"Project-Id-Version: Sphinx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2013-04-02 10:33+0200\n"
-"PO-Revision-Date: 2013-08-05 23:51+0000\n"
+"PO-Revision-Date: 2013-11-20 09:59+0000\n"
"Last-Translator: Takayuki Shimizukawa <shimizukawa@gmail.com>\n"
"Language-Team: Japanese (http://www.transifex.com/projects/p/sphinx-1/language/ja/)\n"
"MIME-Version: 1.0\n"
diff --git a/sphinx/pycode/Grammar.txt b/sphinx/pycode/Grammar-py2.txt
index fcab0b69..98bd1f22 100644
--- a/sphinx/pycode/Grammar.txt
+++ b/sphinx/pycode/Grammar-py2.txt
@@ -1,18 +1,11 @@
-# Grammar for Python. This grammar supports Python 2.x and 3.x.
+# Grammar for Python 2.x
-# Note: Changing the grammar specified in this file will most likely
-# require corresponding changes in the parser module
-# (../Modules/parsermodule.c). If you can't make the changes to
-# that module yourself, please co-ordinate the required changes
-# with someone who can; ask around on python-dev for help. Fred
-# Drake <fdrake@acm.org> will probably be listening there.
-
-# NOTE WELL: You should also follow all the steps listed in PEP 306,
-# "How to Change Python's Grammar"
+# IMPORTANT: when copying over a new Grammar file, make sure file_input
+# is the first nonterminal in the file!
# Start symbols for the grammar:
-# file_input is a module or sequence of commands read from an input file;
# single_input is a single interactive statement;
+# file_input is a module or sequence of commands read from an input file;
# eval_input is the input for the eval() and input() functions.
# NB: compound_stmt in single_input is followed by extra NEWLINE!
file_input: (NEWLINE | stmt)* ENDMARKER
@@ -22,28 +15,20 @@ eval_input: testlist NEWLINE* ENDMARKER
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
decorated: decorators (classdef | funcdef)
-funcdef: 'def' NAME parameters ['->' test] ':' suite
-parameters: '(' [typedargslist] ')'
-typedargslist: ((tfpdef ['=' test] ',')*
- ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
- | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
-tname: NAME [':' test]
-tfpdef: tname | '(' tfplist ')'
-tfplist: tfpdef (',' tfpdef)* [',']
-varargslist: ((vfpdef ['=' test] ',')*
- ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname)
- | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
-vname: NAME
-vfpdef: vname | '(' vfplist ')'
-vfplist: vfpdef (',' vfpdef)* [',']
+funcdef: 'def' NAME parameters ':' suite
+parameters: '(' [varargslist] ')'
+varargslist: ((fpdef ['=' test] ',')*
+ ('*' NAME [',' '**' NAME] | '**' NAME) |
+ fpdef ['=' test] (',' fpdef ['=' test])* [','])
+fpdef: NAME | '(' fplist ')'
+fplist: fpdef (',' fpdef)* [',']
stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt |
import_stmt | global_stmt | exec_stmt | assert_stmt)
-expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
- ('=' (yield_expr|testlist_star_expr))*)
-testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
+expr_stmt: testlist (augassign (yield_expr|testlist) |
+ ('=' (yield_expr|testlist))*)
augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
'<<=' | '>>=' | '**=' | '//=')
# For normal assignments, additional restrictions enforced by the interpreter
@@ -56,7 +41,7 @@ break_stmt: 'break'
continue_stmt: 'continue'
return_stmt: 'return' [testlist]
yield_stmt: yield_expr
-raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]]
+raise_stmt: 'raise' [test [',' test [',' test]]]
import_stmt: import_name | import_from
import_name: 'import' dotted_as_names
import_from: ('from' ('.'* dotted_name | '.'+)
@@ -66,7 +51,7 @@ dotted_as_name: dotted_name ['as' NAME]
import_as_names: import_as_name (',' import_as_name)* [',']
dotted_as_names: dotted_as_name (',' dotted_as_name)*
dotted_name: NAME ('.' NAME)*
-global_stmt: ('global' | 'nonlocal') NAME (',' NAME)*
+global_stmt: 'global' NAME (',' NAME)*
exec_stmt: 'exec' expr ['in' test [',' test]]
assert_stmt: 'assert' test [',' test]
@@ -82,7 +67,7 @@ try_stmt: ('try' ':' suite
with_stmt: 'with' with_item (',' with_item)* ':' suite
with_item: test ['as' expr]
# NB compile.c makes sure that the default except clause is last
-except_clause: 'except' [test [(',' | 'as') test]]
+except_clause: 'except' [test [('as' | ',') test]]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
# Backward compatibility cruft to support:
@@ -100,7 +85,6 @@ and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
-star_expr: '*' expr
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
@@ -109,32 +93,38 @@ arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ['**' factor]
-atom: ('(' [yield_expr|testlist_gexp] ')' |
+atom: ('(' [yield_expr|testlist_comp] ')' |
'[' [listmaker] ']' |
- '{' [dictsetmaker] '}' |
+ '{' [dictorsetmaker] '}' |
'`' testlist1 '`' |
- NAME | NUMBER | STRING+ | '.' '.' '.')
-listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
-testlist_gexp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
+ NAME | NUMBER | STRING+)
+listmaker: test ( list_for | (',' test)* [','] )
+testlist_comp: test ( comp_for | (',' test)* [','] )
lambdef: 'lambda' [varargslist] ':' test
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [',']
-subscript: test | [test] ':' [test] [sliceop]
+subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
sliceop: ':' [test]
-exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
+exprlist: expr (',' expr)* [',']
testlist: test (',' test)* [',']
-dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
- (test (comp_for | (',' test)* [','])) )
+dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
+ (test (comp_for | (',' test)* [','])) )
-classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
+classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
arglist: (argument ',')* (argument [',']
- |'*' test (',' argument)* [',' '**' test]
+ |'*' test (',' argument)* [',' '**' test]
|'**' test)
-argument: test [comp_for] | test '=' test # Really [keyword '='] test
+# The reason that keywords are test nodes instead of NAME is that using NAME
+# results in an ambiguity. ast.c makes sure it's a NAME.
+argument: test [comp_for] | test '=' test
+
+list_iter: list_for | list_if
+list_for: 'for' exprlist 'in' testlist_safe [list_iter]
+list_if: 'if' old_test [list_iter]
comp_iter: comp_for | comp_if
-comp_for: 'for' exprlist 'in' testlist_safe [comp_iter]
+comp_for: 'for' exprlist 'in' or_test [comp_iter]
comp_if: 'if' old_test [comp_iter]
testlist1: test (',' test)*
diff --git a/sphinx/pycode/Grammar-py3.txt b/sphinx/pycode/Grammar-py3.txt
new file mode 100644
index 00000000..083b5f91
--- /dev/null
+++ b/sphinx/pycode/Grammar-py3.txt
@@ -0,0 +1,126 @@
+# Grammar for Python 3.x (with at least x <= 4)
+
+# IMPORTANT: when copying over a new Grammar file, make sure file_input
+# is the first nonterminal in the file!
+
+# Start symbols for the grammar:
+# single_input is a single interactive statement;
+# file_input is a module or sequence of commands read from an input file;
+# eval_input is the input for the eval() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+file_input: (NEWLINE | stmt)* ENDMARKER
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+decorated: decorators (classdef | funcdef)
+funcdef: 'def' NAME parameters ['->' test] ':' suite
+parameters: '(' [typedargslist] ')'
+typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [','
+ ['*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef]]
+ | '*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
+tfpdef: NAME [':' test]
+varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [','
+ ['*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef]]
+ | '*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef)
+vfpdef: NAME
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
+ import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
+expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
+ ('=' (yield_expr|testlist_star_expr))*)
+testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
+augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+ '<<=' | '>>=' | '**=' | '//=')
+# For normal assignments, additional restrictions enforced by the interpreter
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: yield_expr
+raise_stmt: 'raise' [test ['from' test]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
+import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
+ 'import' ('*' | '(' import_as_names ')' | import_as_names))
+import_as_name: NAME ['as' NAME]
+dotted_as_name: dotted_name ['as' NAME]
+import_as_names: import_as_name (',' import_as_name)* [',']
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: 'global' NAME (',' NAME)*
+nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
+assert_stmt: 'assert' test [',' test]
+
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+while_stmt: 'while' test ':' suite ['else' ':' suite]
+for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
+try_stmt: ('try' ':' suite
+ ((except_clause ':' suite)+
+ ['else' ':' suite]
+ ['finally' ':' suite] |
+ 'finally' ':' suite))
+with_stmt: 'with' with_item (',' with_item)* ':' suite
+with_item: test ['as' expr]
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test ['as' NAME]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+test: or_test ['if' or_test 'else' test] | lambdef
+test_nocond: or_test | lambdef_nocond
+lambdef: 'lambda' [varargslist] ':' test
+lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+# <> isn't actually a valid comparison operator in Python. It's here for the
+# sake of a __future__ import described in PEP 401
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+star_expr: '*' expr
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'/'|'%'|'//') factor)*
+factor: ('+'|'-'|'~') factor | power
+power: atom trailer* ['**' factor]
+atom: ('(' [yield_expr|testlist_comp] ')' |
+ '[' [testlist_comp] ']' |
+ '{' [dictorsetmaker] '}' |
+ NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
+testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
+trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+subscriptlist: subscript (',' subscript)* [',']
+subscript: test | [test] ':' [test] [sliceop]
+sliceop: ':' [test]
+exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
+testlist: test (',' test)* [',']
+dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
+ (test (comp_for | (',' test)* [','])) )
+
+classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
+
+arglist: (argument ',')* (argument [',']
+ |'*' test (',' argument)* [',' '**' test]
+ |'**' test)
+# The reason that keywords are test nodes instead of NAME is that using NAME
+# results in an ambiguity. ast.c makes sure it's a NAME.
+argument: test [comp_for] | test '=' test # Really [keyword '='] test
+comp_iter: comp_for | comp_if
+comp_for: 'for' exprlist 'in' or_test [comp_iter]
+comp_if: 'if' test_nocond [comp_iter]
+
+# not used in grammar, but may appear in "node" passed from Parser to Compiler
+encoding_decl: NAME
+
+yield_expr: 'yield' [yield_arg]
+yield_arg: 'from' test | testlist
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index d69fe0ca..54e79da6 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -9,6 +9,7 @@
:license: BSD, see LICENSE for details.
"""
+import sys
from os import path
from sphinx import package_dir
@@ -21,7 +22,8 @@ from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
# load the Python grammar
-_grammarfile = path.join(package_dir, 'pycode', 'Grammar.txt')
+_grammarfile = path.join(package_dir, 'pycode',
+ 'Grammar-py%d.txt' % sys.version_info[0])
pygrammar = driver.load_grammar(_grammarfile)
pydriver = driver.Driver(pygrammar, convert=nodes.convert)
diff --git a/sphinx/pycode/pgen2/driver.py b/sphinx/pycode/pgen2/driver.py
index 5e6cf9a5..422671db 100644
--- a/sphinx/pycode/pgen2/driver.py
+++ b/sphinx/pycode/pgen2/driver.py
@@ -18,7 +18,8 @@ __all__ = ["Driver", "load_grammar"]
# Python imports
import os
import logging
-import sys
+
+import sphinx
# Pgen imports
from sphinx.pycode.pgen2 import grammar, parse, token, tokenize, pgen
@@ -120,7 +121,9 @@ def load_grammar(gt="Grammar.txt", gp=None,
head, tail = os.path.splitext(gt)
if tail == ".txt":
tail = ""
- gp = head + tail + ".".join(map(str, sys.version_info[:2])) + ".pickle"
+ # embed Sphinx major version for the case we ever change the grammar...
+ gp = head + tail + "-sphinx" + \
+ ".".join(map(str, sphinx.version_info[:2])) + ".pickle"
if force or not _newer(gp, gt):
logger.info("Generating grammar tables from %s", gt)
g = pgen.generate_grammar(gt)
diff --git a/sphinx/pycode/pgen2/grammar.py b/sphinx/pycode/pgen2/grammar.py
index 5a433578..01d84346 100644
--- a/sphinx/pycode/pgen2/grammar.py
+++ b/sphinx/pycode/pgen2/grammar.py
@@ -162,6 +162,7 @@ opmap_raw = """
// DOUBLESLASH
//= DOUBLESLASHEQUAL
-> RARROW
+... ELLIPSIS
"""
opmap = {}
diff --git a/sphinx/pycode/pgen2/token.py b/sphinx/pycode/pgen2/token.py
index 61468b31..56a40ce7 100755
--- a/sphinx/pycode/pgen2/token.py
+++ b/sphinx/pycode/pgen2/token.py
@@ -62,7 +62,8 @@ COMMENT = 52
NL = 53
RARROW = 54
ERRORTOKEN = 55
-N_TOKENS = 56
+ELLIPSIS = 56
+N_TOKENS = 57
NT_OFFSET = 256
#--end constants--
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index 5733b34b..3e32f35b 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -99,7 +99,10 @@ release = '%(release_str)s'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
-#language = None
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = %(language)r
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
@@ -320,7 +323,7 @@ epub_copyright = u'%(copyright_str)s'
#epub_theme = 'epub'
# The language of the text. It defaults to the language option
-# or en if the language is not set.
+# or 'en' if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
@@ -348,7 +351,7 @@ epub_copyright = u'%(copyright_str)s'
#epub_post_files = []
# A list of files that should not be packed into the epub file.
-#epub_exclude_files = []
+epub_exclude_files = ['search.html']
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
@@ -948,6 +951,7 @@ def ask_user(d):
* author: author names
* version: version of project
* release: release of project
+ * language: document language
* suffix: source file suffix
* master: master document name
* epub: use epub (bool)
@@ -986,7 +990,7 @@ Enter the root path for documentation.'''
You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.'''
- do_prompt(d, 'sep', 'Separate source and build directories (y/N)', 'n',
+ do_prompt(d, 'sep', 'Separate source and build directories (y/n)', 'n',
boolean)
if 'dot' not in d:
@@ -1014,6 +1018,18 @@ just set both to the same value.'''
if 'release' not in d:
do_prompt(d, 'release', 'Project release', d['version'])
+ if 'language' not in d:
+ print '''
+If the documents are to be written in a language other than English,
+you can select a language here by its language code. Sphinx will then
+translate text that it generates into that language.
+
+For a list of supported codes, see
+http://sphinx-doc.org/config.html#confval-language.'''
+ do_prompt(d, 'language', 'Project language', 'en')
+ if d['language'] == 'en':
+ d['language'] = None
+
if 'suffix' not in d:
print '''
The file name suffix for source files. Commonly, this is either ".txt"
@@ -1042,50 +1058,50 @@ document is a custom template, you can also set this to another filename.'''
if 'epub' not in d:
print '''
Sphinx can also add configuration for epub output:'''
- do_prompt(d, 'epub', 'Do you want to use the epub builder (y/N)',
+ do_prompt(d, 'epub', 'Do you want to use the epub builder (y/n)',
'n', boolean)
if 'ext_autodoc' not in d:
print '''
Please indicate if you want to use one of the following Sphinx extensions:'''
do_prompt(d, 'ext_autodoc', 'autodoc: automatically insert docstrings '
- 'from modules (y/N)', 'n', boolean)
+ 'from modules (y/n)', 'n', boolean)
if 'ext_doctest' not in d:
do_prompt(d, 'ext_doctest', 'doctest: automatically test code snippets '
- 'in doctest blocks (y/N)', 'n', boolean)
+ 'in doctest blocks (y/n)', 'n', boolean)
if 'ext_intersphinx' not in d:
do_prompt(d, 'ext_intersphinx', 'intersphinx: link between Sphinx '
- 'documentation of different projects (y/N)', 'n', boolean)
+ 'documentation of different projects (y/n)', 'n', boolean)
if 'ext_todo' not in d:
do_prompt(d, 'ext_todo', 'todo: write "todo" entries '
- 'that can be shown or hidden on build (y/N)', 'n', boolean)
+ 'that can be shown or hidden on build (y/n)', 'n', boolean)
if 'ext_coverage' not in d:
do_prompt(d, 'ext_coverage', 'coverage: checks for documentation '
- 'coverage (y/N)', 'n', boolean)
+ 'coverage (y/n)', 'n', boolean)
if 'ext_pngmath' not in d:
do_prompt(d, 'ext_pngmath', 'pngmath: include math, rendered '
- 'as PNG images (y/N)', 'n', boolean)
+ 'as PNG images (y/n)', 'n', boolean)
if 'ext_mathjax' not in d:
do_prompt(d, 'ext_mathjax', 'mathjax: include math, rendered in the '
- 'browser by MathJax (y/N)', 'n', boolean)
+ 'browser by MathJax (y/n)', 'n', boolean)
if d['ext_pngmath'] and d['ext_mathjax']:
print '''Note: pngmath and mathjax cannot be enabled at the same time.
pngmath has been deselected.'''
if 'ext_ifconfig' not in d:
do_prompt(d, 'ext_ifconfig', 'ifconfig: conditional inclusion of '
- 'content based on config values (y/N)', 'n', boolean)
+ 'content based on config values (y/n)', 'n', boolean)
if 'ext_viewcode' not in d:
do_prompt(d, 'ext_viewcode', 'viewcode: include links to the source '
- 'code of documented Python objects (y/N)', 'n', boolean)
+ 'code of documented Python objects (y/n)', 'n', boolean)
if 'makefile' not in d:
print '''
A Makefile and a Windows command file can be generated for you so that you
only have to run e.g. `make html' instead of invoking sphinx-build
directly.'''
- do_prompt(d, 'makefile', 'Create Makefile? (Y/n)', 'y', boolean)
+ do_prompt(d, 'makefile', 'Create Makefile? (y/n)', 'y', boolean)
if 'batchfile' not in d:
- do_prompt(d, 'batchfile', 'Create Windows command file? (Y/n)',
+ do_prompt(d, 'batchfile', 'Create Windows command file? (y/n)',
'y', boolean)
print
diff --git a/sphinx/roles.py b/sphinx/roles.py
index 6703b6b8..3b858588 100644
--- a/sphinx/roles.py
+++ b/sphinx/roles.py
@@ -22,15 +22,15 @@ from sphinx.util.nodes import split_explicit_title, process_index_entry, \
generic_docroles = {
- 'command' : nodes.strong,
+ 'command' : addnodes.literal_strong,
'dfn' : nodes.emphasis,
'kbd' : nodes.literal,
'mailheader' : addnodes.literal_emphasis,
- 'makevar' : nodes.strong,
+ 'makevar' : addnodes.literal_strong,
'manpage' : addnodes.literal_emphasis,
'mimetype' : addnodes.literal_emphasis,
'newsgroup' : addnodes.literal_emphasis,
- 'program' : nodes.strong, # XXX should be an x-ref
+ 'program' : addnodes.literal_strong, # XXX should be an x-ref
'regexp' : nodes.literal,
}
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index 5f64495b..87377c31 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -10,10 +10,9 @@
"""
from __future__ import with_statement
import re
-import itertools
import cPickle as pickle
-from docutils.nodes import comment, title, Text, NodeVisitor, SkipNode
+from docutils.nodes import raw, comment, title, Text, NodeVisitor, SkipNode
from sphinx.util import jsdump, rpartition
@@ -146,7 +145,16 @@ class WordCollector(NodeVisitor):
def dispatch_visit(self, node):
if node.__class__ is comment:
raise SkipNode
- elif node.__class__ is Text:
+ if node.__class__ is raw:
+ # Some people might put content in raw HTML that should be searched,
+ # so we just amateurishly strip HTML tags and index the remaining
+ # content
+ nodetext = re.sub(r'(?is)<style.*?</style>', '', node.astext())
+ nodetext = re.sub(r'(?is)<script.*?</script>', '', nodetext)
+ nodetext = re.sub(r'<[^<]+?>', '', nodetext)
+ self.found_words.extend(self.lang.split(nodetext))
+ raise SkipNode
+ if node.__class__ is Text:
self.found_words.extend(self.lang.split(node.astext()))
elif node.__class__ is title:
self.found_title_words.extend(self.lang.split(node.astext()))
@@ -306,8 +314,7 @@ class IndexBuilder(object):
return self._stem_cache[word]
_filter = self.lang.word_filter
- for word in itertools.chain(visitor.found_title_words,
- self.lang.split(title)):
+ for word in visitor.found_title_words:
word = stem(word)
if _filter(word):
self._title_mapping.setdefault(word, set()).add(filename)
diff --git a/sphinx/search/ja.py b/sphinx/search/ja.py
index f0deb154..099f4717 100644
--- a/sphinx/search/ja.py
+++ b/sphinx/search/ja.py
@@ -236,7 +236,7 @@ class TinySegmenter(object):
score += self.ts_(self.TQ4__, p3 + c2 + c3 + c4)
p = u'O'
if score > 0:
- result.append(word)
+ result.append(word.strip())
word = u''
p = u'B'
p1 = p2
@@ -244,7 +244,7 @@ class TinySegmenter(object):
p3 = p
word += seg[i]
- result.append(word)
+ result.append(word.strip())
return result
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index 50c0d16a..554845f8 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -30,6 +30,8 @@
\RequirePackage{wrapfig}
% Separate paragraphs by space by default.
\RequirePackage{parskip}
+% For parsed-literal blocks.
+\RequirePackage{alltt}
% Redefine these colors to your liking in the preamble.
\definecolor{TitleColor}{rgb}{0.126,0.263,0.361}
@@ -238,9 +240,11 @@
\def\productioncont##1{\\& &\code{##1}}
\parindent=2em
\indent
- \begin{tabular}{lcl}
+ \setlength{\LTpre}{0pt}
+ \setlength{\LTpost}{0pt}
+ \begin{longtable}[l]{lcl}
}{%
- \end{tabular}
+ \end{longtable}
}
% Notices / Admonitions
diff --git a/sphinx/texinputs/sphinxmanual.cls b/sphinx/texinputs/sphinxmanual.cls
index 26df488e..a6b9b392 100644
--- a/sphinx/texinputs/sphinxmanual.cls
+++ b/sphinx/texinputs/sphinxmanual.cls
@@ -97,6 +97,7 @@
%
\let\py@OldTableofcontents=\tableofcontents
\renewcommand{\tableofcontents}{%
+ \pagenumbering{roman}%
\setcounter{page}{1}%
\pagebreak%
\pagestyle{plain}%
@@ -114,7 +115,7 @@
\pagenumbering{arabic}%
\@ifundefined{fancyhf}{}{\pagestyle{normal}}%
}
-\pagenumbering{roman}
+\pagenumbering{alph}
% This is needed to get the width of the section # area wide enough in the
% library reference. Doing it here keeps it the same for all the manuals.
diff --git a/sphinx/texinputs/tabulary.sty b/sphinx/texinputs/tabulary.sty
index ba83c0af..7ea572c1 100644
--- a/sphinx/texinputs/tabulary.sty
+++ b/sphinx/texinputs/tabulary.sty
@@ -8,13 +8,13 @@
%% DRAFT VERSION
%%
%% File `tabulary.dtx'.
-%% Copyright (C) 1995 1996 2003 David Carlisle
+%% Copyright (C) 1995 1996 2003 2008 David Carlisle
%% This file may be distributed under the terms of the LPPL.
%% See 00readme.txt for details.
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tabulary}
- [2007/10/02 v0.9 tabulary package (DPC)]
+ [2008/12/01 v0.9 tabulary package (DPC)]
\RequirePackage{array}
\catcode`\Z=14
\DeclareOption{debugshow}{\catcode`\Z=9\relax}
@@ -109,8 +109,6 @@ Z \string\tymax: \the\tymax^^J}%
\global\advance\TY@linewidth-#1\relax}
\def\endtabulary{%
\gdef\@halignto{}%
- \let\TY@footnote\footnote%
- \def\footnote{}% prevent footnotes from doing anything
\expandafter\TY@tab\the\toks@
\crcr\omit
{\xdef\TY@save@row{}%
@@ -174,7 +172,6 @@ Z \message{> tymin}%
\TY@checkmin
\TY@count\z@
\let\TY@box\TY@box@v
- \let\footnote\TY@footnote % restore footnotes
{\expandafter\TY@final\the\toks@\endTY@final}%
\count@\z@
\@tempswatrue
@@ -195,7 +192,7 @@ Z \message{> tymin}%
\let\TY@checkmin\relax
\ifdim\TY@tablewidth>\z@
\Gscale@div\TY@ratio\TY@linewidth\TY@tablewidth
- \ifdim\TY@tablewidth <\linewidth
+ \ifdim\TY@tablewidth <\TY@linewidth
\def\TY@ratio{1}%
\fi
\else
diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t
index 83af2303..d54e7f4e 100644
--- a/sphinx/themes/basic/static/basic.css_t
+++ b/sphinx/themes/basic/static/basic.css_t
@@ -89,6 +89,7 @@ div.sphinxsidebar #searchbox input[type="submit"] {
img {
border: 0;
+ max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
diff --git a/sphinx/themes/basic/static/searchtools.js_t b/sphinx/themes/basic/static/searchtools.js_t
index 50b970ff..523ecaaa 100644
--- a/sphinx/themes/basic/static/searchtools.js_t
+++ b/sphinx/themes/basic/static/searchtools.js_t
@@ -150,13 +150,13 @@ var Search = {
objectterms.push(tmp[i].toLowerCase());
}
- if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
+ if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
- var word = stemmer.stemWord(tmp[i]).toLowerCase();
+ var word = stemmer.stemWord(tmp[i].toLowerCase());
var toAppend;
// select the correct list
if (word[0] == '-') {
diff --git a/sphinx/themes/epub/static/epub.css b/sphinx/themes/epub/static/epub.css
index 5e5f07c1..3f4664f6 100644
--- a/sphinx/themes/epub/static/epub.css
+++ b/sphinx/themes/epub/static/epub.css
@@ -92,6 +92,7 @@ div.sphinxsidebar input {
img {
border: 0;
+ max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
diff --git a/sphinx/themes/haiku/layout.html b/sphinx/themes/haiku/layout.html
index 337d0ca2..0c6b41e7 100644
--- a/sphinx/themes/haiku/layout.html
+++ b/sphinx/themes/haiku/layout.html
@@ -8,8 +8,6 @@
:license: BSD, see LICENSE for details.
#}
{%- extends "basic/layout.html" %}
-{% set script_files = script_files + ['_static/theme_extras.js'] %}
-{% set css_files = css_files + ['_static/print.css'] %}
{# do not display relbars #}
{% block relbar1 %}{% endblock %}
diff --git a/sphinx/themes/scrolls/static/print.css b/sphinx/themes/scrolls/static/print.css
index fb633d87..715d90ab 100644
--- a/sphinx/themes/scrolls/static/print.css
+++ b/sphinx/themes/scrolls/static/print.css
@@ -1,5 +1,7 @@
-div.header, div.relnav, #toc { display: none; }
-#contentwrapper { padding: 0; margin: 0; border: none; }
-body { color: black; background-color: white; }
-div.footer { border-top: 1px solid #888; color: #888; margin-top: 1cm; }
-div.footer a { text-decoration: none; }
+@media print {
+ div.header, div.relnav, #toc { display: none; }
+ #contentwrapper { padding: 0; margin: 0; border: none; }
+ body { color: black; background-color: white; }
+ div.footer { border-top: 1px solid #888; color: #888; margin-top: 1cm; }
+ div.footer a { text-decoration: none; }
+}
diff --git a/sphinx/util/docfields.py b/sphinx/util/docfields.py
index 6fd8ba95..150bf3a1 100644
--- a/sphinx/util/docfields.py
+++ b/sphinx/util/docfields.py
@@ -99,7 +99,8 @@ class GroupedField(Field):
return Field.make_field(self, types, domain, items[0])
for fieldarg, content in items:
par = nodes.paragraph()
- par += self.make_xref(self.rolename, domain, fieldarg, nodes.strong)
+ par += self.make_xref(self.rolename, domain, fieldarg,
+ addnodes.literal_strong)
par += nodes.Text(' -- ')
par += content
listnode += nodes.list_item('', par)
@@ -137,7 +138,8 @@ class TypedField(GroupedField):
def make_field(self, types, domain, items):
def handle_item(fieldarg, content):
par = nodes.paragraph()
- par += self.make_xref(self.rolename, domain, fieldarg, nodes.strong)
+ par += self.make_xref(self.rolename, domain, fieldarg,
+ addnodes.literal_strong)
if fieldarg in types:
par += nodes.Text(' (')
# NOTE: using .pop() here to prevent a single type node to be
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index a0e09965..9941dc0c 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -29,6 +29,9 @@ if sys.version_info >= (3, 0):
# safely encode a string for printing to the terminal
def terminal_safe(s):
return s.encode('ascii', 'backslashreplace').decode('ascii')
+ # some kind of default system encoding; should be used with a lenient
+ # error handler
+ sys_encoding = sys.getdefaultencoding()
# support for running 2to3 over config files
def convert_with_2to3(filepath):
from lib2to3.refactor import RefactoringTool, get_fixers_from_package
@@ -62,7 +65,12 @@ else:
# safely encode a string for printing to the terminal
def terminal_safe(s):
return s.encode('ascii', 'backslashreplace')
- from itertools import izip_longest as zip_longest # use Python 3 name
+ # some kind of default system encoding; should be used with a lenient
+ # error handler
+ import locale
+ sys_encoding = locale.getpreferredencoding()
+ # use Python 3 name
+ from itertools import izip_longest as zip_longest
def execfile_(filepath, _globals):
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index 1abe7b3a..308e1f5b 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -131,24 +131,40 @@ class HTMLTranslator(BaseTranslator):
def visit_desc_parameterlist(self, node):
self.body.append('<big>(</big>')
self.first_param = 1
+ self.optional_param_level = 0
+ # How many required parameters are left.
+ self.required_params_left = sum([isinstance(c, addnodes.desc_parameter)
+ for c in node.children])
self.param_separator = node.child_text_separator
def depart_desc_parameterlist(self, node):
self.body.append('<big>)</big>')
+ # If required parameters are still to come, then put the comma after
+ # the parameter. Otherwise, put the comma before. This ensures that
+ # signatures like the following render correctly (see issue #1001):
+ #
+ # foo([a, ]b, c[, d])
+ #
def visit_desc_parameter(self, node):
- if not self.first_param:
- self.body.append(self.param_separator)
- else:
+ if self.first_param:
self.first_param = 0
+ elif not self.required_params_left:
+ self.body.append(self.param_separator)
+ if self.optional_param_level == 0:
+ self.required_params_left -= 1
if not node.hasattr('noemph'):
self.body.append('<em>')
def depart_desc_parameter(self, node):
if not node.hasattr('noemph'):
self.body.append('</em>')
+ if self.required_params_left:
+ self.body.append(self.param_separator)
def visit_desc_optional(self, node):
+ self.optional_param_level += 1
self.body.append('<span class="optional">[</span>')
def depart_desc_optional(self, node):
+ self.optional_param_level -= 1
self.body.append('<span class="optional">]</span>')
def visit_desc_annotation(self, node):
@@ -492,6 +508,11 @@ class HTMLTranslator(BaseTranslator):
def depart_literal_emphasis(self, node):
return self.depart_emphasis(node)
+ def visit_literal_strong(self, node):
+ return self.visit_strong(node)
+ def depart_literal_strong(self, node):
+ return self.depart_strong(node)
+
def visit_abbreviation(self, node):
attrs = {}
if node.hasattr('explanation'):
@@ -551,6 +572,13 @@ class HTMLTranslator(BaseTranslator):
node['classes'].append('field-odd')
self.body.append(self.starttag(node, 'tr', '', CLASS='field'))
+ def visit_math(self, node, math_env=''):
+ self.builder.warn('using "math" markup without a Sphinx math extension '
+ 'active, please use one of the math extensions '
+ 'described at http://sphinx-doc.org/ext/math.html',
+ (self.builder.current_docname, node.line))
+ raise nodes.SkipNode
+
def unknown_visit(self, node):
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
@@ -595,6 +623,14 @@ class SmartyPantsHTMLTranslator(HTMLTranslator):
self.depart_emphasis(node)
self.no_smarty -= 1
+ def visit_literal_strong(self, node):
+ self.no_smarty += 1
+ self.visit_strong(node)
+
+ def depart_literal_strong(self, node):
+ self.depart_strong(node)
+ self.no_smarty -= 1
+
def visit_desc_signature(self, node):
self.no_smarty += 1
HTMLTranslator.visit_desc_signature(self, node)
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 5e2bf93f..5429bcbb 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -263,7 +263,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.next_figure_ids = set()
self.next_table_ids = set()
# flags
- self.verbatim = None
self.in_title = 0
self.in_production_list = 0
self.in_footnote = 0
@@ -1247,6 +1246,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_strong(self, node):
self.body.append('}')
+ def visit_literal_strong(self, node):
+ self.body.append(r'\textbf{\texttt{')
+ self.no_contractions += 1
+ def depart_literal_strong(self, node):
+ self.body.append('}}')
+ self.no_contractions -= 1
+
def visit_abbreviation(self, node):
abbr = node.astext()
self.body.append(r'\textsc{')
@@ -1317,36 +1323,40 @@ class LaTeXTranslator(nodes.NodeVisitor):
raise UnsupportedError('%s:%s: literal blocks in footnotes are '
'not supported by LaTeX' %
(self.curfilestack[-1], node.line))
- self.verbatim = ''
+ if node.rawsource != node.astext():
+ # most probably a parsed-literal block -- don't highlight
+ self.body.append('\\begin{alltt}\n')
+ else:
+ code = node.astext().rstrip('\n')
+ lang = self.hlsettingstack[-1][0]
+ linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
+ highlight_args = node.get('highlight_args', {})
+ if 'language' in node:
+ # code-block directives
+ lang = node['language']
+ highlight_args['force'] = True
+ if 'linenos' in node:
+ linenos = node['linenos']
+ def warner(msg):
+ self.builder.warn(msg, (self.curfilestack[-1], node.line))
+ hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
+ linenos=linenos, **highlight_args)
+ # workaround for Unicode issue
+ hlcode = hlcode.replace(u'€', u'@texteuro[]')
+ # must use original Verbatim environment and "tabular" environment
+ if self.table:
+ hlcode = hlcode.replace('\\begin{Verbatim}',
+ '\\begin{OriginalVerbatim}')
+ self.table.has_problematic = True
+ self.table.has_verbatim = True
+ # get consistent trailer
+ hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim}
+ hlcode = hlcode.rstrip() + '\n'
+ self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' %
+ (self.table and 'Original' or ''))
+ raise nodes.SkipNode
def depart_literal_block(self, node):
- code = self.verbatim.rstrip('\n')
- lang = self.hlsettingstack[-1][0]
- linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
- highlight_args = node.get('highlight_args', {})
- if 'language' in node:
- # code-block directives
- lang = node['language']
- highlight_args['force'] = True
- if 'linenos' in node:
- linenos = node['linenos']
- def warner(msg):
- self.builder.warn(msg, (self.curfilestack[-1], node.line))
- hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
- linenos=linenos, **highlight_args)
- # workaround for Unicode issue
- hlcode = hlcode.replace(u'€', u'@texteuro[]')
- # must use original Verbatim environment and "tabular" environment
- if self.table:
- hlcode = hlcode.replace('\\begin{Verbatim}',
- '\\begin{OriginalVerbatim}')
- self.table.has_problematic = True
- self.table.has_verbatim = True
- # get consistent trailer
- hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim}
- hlcode = hlcode.rstrip() + '\n'
- self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' %
- (self.table and 'Original' or ''))
- self.verbatim = None
+ self.body.append('\n\\end{alltt}\n')
visit_doctest_block = visit_literal_block
depart_doctest_block = depart_literal_block
@@ -1509,13 +1519,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
return self.encode(text).replace('\\textasciitilde{}', '~')
def visit_Text(self, node):
- if self.verbatim is not None:
- self.verbatim += node.astext()
- else:
- text = self.encode(node.astext())
- if not self.no_contractions:
- text = educate_quotes_latex(text)
- self.body.append(text)
+ text = self.encode(node.astext())
+ if not self.no_contractions:
+ text = educate_quotes_latex(text)
+ self.body.append(text)
def depart_Text(self, node):
pass
@@ -1531,5 +1538,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_system_message(self, node):
self.body.append('\n')
+ def visit_math(self, node):
+ self.builder.warn('using "math" markup without a Sphinx math extension '
+ 'active, please use one of the math extensions '
+ 'described at http://sphinx-doc.org/ext/math.html',
+ (self.curfilestack[-1], node.line))
+ raise nodes.SkipNode
+
+ visit_math_block = visit_math
+
def unknown_visit(self, node):
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py
index f652e918..0aa0058c 100644
--- a/sphinx/writers/manpage.py
+++ b/sphinx/writers/manpage.py
@@ -304,6 +304,11 @@ class ManualPageTranslator(BaseTranslator):
def depart_literal_emphasis(self, node):
return self.depart_emphasis(node)
+ def visit_literal_strong(self, node):
+ return self.visit_strong(node)
+ def depart_literal_strong(self, node):
+ return self.depart_strong(node)
+
def visit_abbreviation(self, node):
pass
def depart_abbreviation(self, node):
@@ -342,5 +347,13 @@ class ManualPageTranslator(BaseTranslator):
def depart_inline(self, node):
pass
+ def visit_math(self, node):
+ self.builder.warn('using "math" markup without a Sphinx math extension '
+ 'active, please use one of the math extensions '
+ 'described at http://sphinx-doc.org/ext/math.html')
+ raise nodes.SkipNode
+
+ visit_math_block = visit_math
+
def unknown_visit(self, node):
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py
index 66a0e039..a930a525 100644
--- a/sphinx/writers/texinfo.py
+++ b/sphinx/writers/texinfo.py
@@ -1207,6 +1207,11 @@ class TexinfoTranslator(nodes.NodeVisitor):
def depart_literal_emphasis(self, node):
self.body.append('}')
+ def visit_literal_strong(self, node):
+ self.body.append('@code{')
+ def depart_literal_strong(self, node):
+ self.body.append('}')
+
def visit_index(self, node):
# terminate the line but don't prevent paragraph breaks
if isinstance(node.parent, nodes.paragraph):
@@ -1393,3 +1398,11 @@ class TexinfoTranslator(nodes.NodeVisitor):
pass
def depart_pending_xref(self, node):
pass
+
+ def visit_math(self, node):
+ self.builder.warn('using "math" markup without a Sphinx math extension '
+ 'active, please use one of the math extensions '
+ 'described at http://sphinx-doc.org/ext/math.html')
+ raise nodes.SkipNode
+
+ visit_math_block = visit_math
diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py
index 3bf7588a..a174bc26 100644
--- a/sphinx/writers/text.py
+++ b/sphinx/writers/text.py
@@ -152,6 +152,7 @@ class TextTranslator(nodes.NodeVisitor):
def __init__(self, document, builder):
nodes.NodeVisitor.__init__(self, document)
+ self.builder = builder
newlines = builder.config.text_newlines
if newlines == 'windows':
@@ -761,6 +762,11 @@ class TextTranslator(nodes.NodeVisitor):
def depart_strong(self, node):
self.add_text('**')
+ def visit_literal_strong(self, node):
+ self.add_text('**')
+ def depart_literal_strong(self, node):
+ self.add_text('**')
+
def visit_abbreviation(self, node):
self.add_text('')
def depart_abbreviation(self, node):
@@ -838,5 +844,14 @@ class TextTranslator(nodes.NodeVisitor):
self.body.append(node.astext())
raise nodes.SkipNode
+ def visit_math(self, node):
+ self.builder.warn('using "math" markup without a Sphinx math extension '
+ 'active, please use one of the math extensions '
+ 'described at http://sphinx-doc.org/ext/math.html',
+ (self.builder.current_docname, node.line))
+ raise nodes.SkipNode
+
+ visit_math_block = visit_math
+
def unknown_visit(self, node):
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)