summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2017-10-23 18:49:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2017-10-23 18:49:38 +0000
commitc05b021e3bd9f20155f9e1c49513c1e572cb5a28 (patch)
tree00095ceb747221f174da39088cd43dfcd0f9c813
parentReleasing progress-linux version 1.6.4-2~dschinn1. (diff)
downloadsphinx-c05b021e3bd9f20155f9e1c49513c1e572cb5a28.zip
sphinx-c05b021e3bd9f20155f9e1c49513c1e572cb5a28.tar.xz
Merging upstream version 1.6.5.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--AUTHORS1
-rw-r--r--CHANGES34
-rw-r--r--EXAMPLES2
-rw-r--r--PKG-INFO2
-rw-r--r--Sphinx.egg-info/PKG-INFO2
-rw-r--r--Sphinx.egg-info/SOURCES.txt5
-rw-r--r--doc/config.rst39
-rw-r--r--doc/latex.rst7
-rw-r--r--sphinx/__init__.py6
-rw-r--r--sphinx/builders/html.py15
-rw-r--r--sphinx/domains/cpp.py4
-rw-r--r--sphinx/domains/python.py10
-rw-r--r--sphinx/environment/__init__.py27
-rw-r--r--sphinx/ext/autodoc.py3
-rw-r--r--sphinx/ext/intersphinx.py2
-rw-r--r--sphinx/ext/todo.py25
-rw-r--r--sphinx/quickstart.py4
-rw-r--r--sphinx/search/__init__.py5
-rw-r--r--sphinx/templates/quickstart/Makefile.new_t2
-rw-r--r--sphinx/templates/quickstart/Makefile_t6
-rw-r--r--sphinx/templates/quickstart/conf.py_t3
-rw-r--r--sphinx/templates/quickstart/make.bat.new_t10
-rw-r--r--sphinx/templates/quickstart/make.bat_t23
-rw-r--r--sphinx/themes/basic/static/basic.css_t6
-rw-r--r--sphinx/themes/basic/static/doctools.js_t52
-rw-r--r--sphinx/themes/basic/static/searchtools.js_t3
-rw-r--r--sphinx/transforms/i18n.py62
-rw-r--r--sphinx/util/docutils.py6
-rw-r--r--sphinx/util/i18n.py8
-rw-r--r--sphinx/util/logging.py16
-rw-r--r--sphinx/util/matching.py2
-rw-r--r--sphinx/util/pycompat.py2
-rw-r--r--sphinx/writers/html.py1
-rw-r--r--sphinx/writers/latex.py6
-rw-r--r--tests/roots/test-domain-cpp/roles2.rst5
-rw-r--r--tests/roots/test-domain-py/module_option.rst25
-rw-r--r--tests/roots/test-ext-todo/conf.py5
-rw-r--r--tests/roots/test-image-in-parsed-literal/conf.py13
-rw-r--r--tests/roots/test-image-in-parsed-literal/index.rst9
-rw-r--r--tests/roots/test-image-in-parsed-literal/pic.pngbin0 -> 120 bytes
-rw-r--r--tests/roots/test-intl/refs_inconsistency.po8
-rw-r--r--tests/roots/test-intl/refs_inconsistency.txt4
-rw-r--r--tests/test_build_latex.py10
-rw-r--r--tests/test_domain_cpp.py7
-rw-r--r--tests/test_domain_py.py9
-rw-r--r--tests/test_ext_todo.py28
-rw-r--r--tests/test_intl.py38
-rw-r--r--tests/test_search.py12
-rw-r--r--tests/test_util_logging.py6
-rw-r--r--tests/test_writer_latex.py2
50 files changed, 458 insertions, 124 deletions
diff --git a/AUTHORS b/AUTHORS
index 580feeb..13ce2df 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -29,6 +29,7 @@ Other contributors, listed alphabetically, are:
* Kevin Dunn -- MathJax extension
* Josip Dzolonga -- coverage builder
* Buck Evan -- dummy builder
+* Matthew Fernandez -- todo extension fix
* Hernan Grecco -- search improvements
* Horst Gutmann -- internationalization support
* Martin Hans -- autodoc improvements
diff --git a/CHANGES b/CHANGES
index 25f6363..70652ce 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,37 @@
+Release 1.6.5 (released Oct 23, 2017)
+=====================================
+
+Features added
+--------------
+
+* #4107: Make searchtools.js compatible with pre-Sphinx1.5 templates
+* #4112: Don't override the smart_quotes setting if it was already set
+* #4125: Display reference texts of original and translated passages on
+ i18n warning message
+* #4147: Include the exception when logging PO/MO file read/write
+
+Bugs fixed
+----------
+
+* #4085: Failed PDF build from image in parsed-literal using ``:align:`` option
+* #4100: Remove debug print from autodoc extension
+* #3987: Changing theme from alabaster causes HTML build to fail
+* #4096: C++, don't crash when using the wrong role type. Thanks to mitya57.
+* #4070, #4111: crashes when the warning message contains format strings (again)
+* #4108: Search word highlighting breaks SVG images
+* #3692: Unable to build HTML if writing .buildinfo failed
+* #4152: HTML writer crashes if a field list is placed on top of the document
+* #4063: Sphinx crashes when labeling directive ``.. todolist::``
+* #4134: [doc] :file:`docutils.conf` is not documented explicitly
+* #4169: Chinese language doesn't trigger Chinese search automatically
+* #1020: ext.todo todolist not linking to the page in pdflatex
+* #3965: New quickstart generates wrong SPHINXBUILD in Makefile
+* #3739: ``:module:`` option is ignored at content of pyobjects
+* #4149: Documentation: Help choosing :confval:`latex_engine`
+* #4090: [doc] :confval:`latex_additional_files` with extra LaTeX macros should
+ not use ``.tex`` extension
+* Failed to convert reST parser error to warning (refs: #4132)
+
Release 1.6.4 (released Sep 26, 2017)
=====================================
diff --git a/EXAMPLES b/EXAMPLES
index 682c05c..fa91b20 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -218,7 +218,7 @@ Books produced using Sphinx
http://www.amazon.co.jp/dp/4048689525/
* "Python Professional Programming" (in Japanese):
http://www.amazon.co.jp/dp/4798032948/
-* "Die Wahrheit des Sehens. Der DEKALOG von Krzysztof Kie?lowski":
+* "Die Wahrheit des Sehens. Der DEKALOG von Krzysztof KieĊ›lowski":
http://www.hasecke.eu/Dekalog/
* The "Varnish Book":
http://book.varnish-software.com/4.0/
diff --git a/PKG-INFO b/PKG-INFO
index ba48857..dc7d8aa 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Sphinx
-Version: 1.6.4
+Version: 1.6.5
Summary: Python documentation generator
Home-page: http://sphinx-doc.org/
Author: Georg Brandl
diff --git a/Sphinx.egg-info/PKG-INFO b/Sphinx.egg-info/PKG-INFO
index ba48857..dc7d8aa 100644
--- a/Sphinx.egg-info/PKG-INFO
+++ b/Sphinx.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Sphinx
-Version: 1.6.4
+Version: 1.6.5
Summary: Python documentation generator
Home-page: http://sphinx-doc.org/
Author: Georg Brandl
diff --git a/Sphinx.egg-info/SOURCES.txt b/Sphinx.egg-info/SOURCES.txt
index cf5d6a6..62786bb 100644
--- a/Sphinx.egg-info/SOURCES.txt
+++ b/Sphinx.egg-info/SOURCES.txt
@@ -756,6 +756,7 @@ tests/roots/test-domain-cpp/any-role.rst
tests/roots/test-domain-cpp/conf.py
tests/roots/test-domain-cpp/index.rst
tests/roots/test-domain-cpp/roles.rst
+tests/roots/test-domain-cpp/roles2.rst
tests/roots/test-domain-js/conf.py
tests/roots/test-domain-js/index.rst
tests/roots/test-domain-js/module.rst
@@ -763,6 +764,7 @@ tests/roots/test-domain-js/roles.rst
tests/roots/test-domain-py/conf.py
tests/roots/test-domain-py/index.rst
tests/roots/test-domain-py/module.rst
+tests/roots/test-domain-py/module_option.rst
tests/roots/test-domain-py/roles.rst
tests/roots/test-double-inheriting-theme/conf.py
tests/roots/test-double-inheriting-theme/index.rst
@@ -836,6 +838,9 @@ tests/roots/test-html_assets/subdir/background.png
tests/roots/test-html_assets/subdir/_build/index.html
tests/roots/test-html_entity/conf.py
tests/roots/test-html_entity/index.rst
+tests/roots/test-image-in-parsed-literal/conf.py
+tests/roots/test-image-in-parsed-literal/index.rst
+tests/roots/test-image-in-parsed-literal/pic.png
tests/roots/test-image-in-section/conf.py
tests/roots/test-image-in-section/index.rst
tests/roots/test-image-in-section/pic.png
diff --git a/doc/config.rst b/doc/config.rst
index a094195..b615dc4 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -9,8 +9,20 @@ The build configuration file
:synopsis: Build configuration file.
The :term:`configuration directory` must contain a file named :file:`conf.py`.
-This file (containing Python code) is called the "build configuration file" and
-contains all configuration needed to customize Sphinx input and output behavior.
+This file (containing Python code) is called the "build configuration file"
+and contains (almost) all configuration needed to customize Sphinx input
+and output behavior.
+
+ An optional file `docutils.conf`_ can be added to the configuration
+ directory to adjust `Docutils`_ configuration if not otherwise overriden or
+ set by Sphinx; this applies in particular to the `Docutils smart_quotes
+ setting`_ (Note that Sphinx applies smart quotes transform by default.)
+
+ .. _`docutils`: http://docutils.sourceforge.net/
+
+ .. _`docutils.conf`: http://docutils.sourceforge.net/docs/user/config.html
+
+ .. _`Docutils smart_quotes setting`: http://docutils.sourceforge.net/docs/user/config.html#smart-quotes
The configuration file is executed as Python code at build time (using
:func:`execfile`, and with the current directory set to its containing
@@ -769,8 +781,8 @@ that use Sphinx's HTMLWriter class.
entities. Default: ``True``.
.. deprecated:: 1.6
- Use the `smart_quotes option`_ in the Docutils configuration file
- (``docutils.conf``) instead.
+ To disable or customize smart quotes, use the Docutils configuration file
+ (``docutils.conf``) instead to set there its `smart_quotes option`_.
.. _`smart_quotes option`: http://docutils.sourceforge.net/docs/user/config.html#smart-quotes
@@ -1530,6 +1542,25 @@ These options influence LaTeX output. See further :doc:`latex`.
* ``'lualatex'`` -- LuaLaTeX
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
+ PDFLaTeX's support for Unicode characters covers those from the document
+ language (the LaTeX ``babel`` and ``inputenc`` packages map them to glyph
+ slots in the document font, at various encodings allowing each only 256
+ characters; Sphinx uses by default (except for Cyrillic languages) the
+ ``times`` package), but stray characters from other scripts or special
+ symbols may require adding extra LaTeX packages or macros to the LaTeX
+ preamble.
+
+ If your project uses such extra Unicode characters, switching the engine to
+ XeLaTeX or LuaLaTeX often provides a quick fix. They only work with UTF-8
+ encoded sources and can (in fact, should) use OpenType fonts, either from
+ the system or the TeX install tree. Recent LaTeX releases will default with
+ these engines to the Latin Modern OpenType font, which has good coverage of
+ Latin and Cyrillic scripts (it is provided by standard LaTeX installation),
+ and Sphinx does not modify this default. Refer to the documentation of the
+ LaTeX ``polyglossia`` package to see how to instruct LaTeX to use some
+ other OpenType font if Unicode coverage proves insufficient (or use
+ directly ``\setmainfont`` et. al. as in :ref:`this example <latex-basic>`.)
+
.. confval:: latex_documents
This value determines how to group the document tree into LaTeX source files.
diff --git a/doc/latex.rst b/doc/latex.rst
index 61689bd..0cd91fa 100644
--- a/doc/latex.rst
+++ b/doc/latex.rst
@@ -29,6 +29,7 @@ The *latex* target does not benefit from pre-prepared themes like the
cautionBgColor={named}{LightCyan}}
\relax
+.. _latex-basic:
Basic customization
-------------------
@@ -61,17 +62,17 @@ It is achieved via usage of the
.. highlight:: latex
If the size of the ``'preamble'`` contents becomes inconvenient, one may move
-all needed macros into some file :file:`mystyle.tex` of the project source
+all needed macros into some file :file:`mystyle.tex.txt` of the project source
repertory, and get LaTeX to import it at run time::
- 'preamble': r'\input{mystyle.tex}',
+ 'preamble': r'\input{mystyle.tex.txt}',
# or, if the \ProvidesPackage LaTeX macro is used in a file mystyle.sty
'preamble': r'\usepackage{mystyle}',
It is needed to set appropriately :confval:`latex_additional_files`, for
example::
- latex_additional_files = ["mystyle.tex"]
+ latex_additional_files = ["mystyle.sty"]
.. _latexsphinxsetup:
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index be114cf..91e1f90 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -34,13 +34,13 @@ if 'PYTHONWARNINGS' not in os.environ:
warnings.filterwarnings('ignore', "'U' mode is deprecated",
DeprecationWarning, module='docutils.io')
-__version__ = '1.6.4'
-__released__ = '1.6.4' # used when Sphinx builds its own docs
+__version__ = '1.6.5'
+__released__ = '1.6.5' # used when Sphinx builds its own docs
# version info for better programmatic use
# possible values for 3rd element: 'alpha', 'beta', 'rc', 'final'
# 'final' has 0 as the last element
-version_info = (1, 6, 4, 'final', 0)
+version_info = (1, 6, 5, 'final', 0)
package_dir = path.abspath(path.dirname(__file__))
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 90e4574..ead51a9 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -776,12 +776,15 @@ class StandaloneHTMLBuilder(Builder):
def write_buildinfo(self):
# type: () -> None
# write build info file
- with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
- fp.write('# Sphinx build info version 1\n'
- '# This file hashes the configuration used when building'
- ' these files. When it is not found, a full rebuild will'
- ' be done.\nconfig: %s\ntags: %s\n' %
- (self.config_hash, self.tags_hash))
+ try:
+ with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
+ fp.write('# Sphinx build info version 1\n'
+ '# This file hashes the configuration used when building'
+ ' these files. When it is not found, a full rebuild will'
+ ' be done.\nconfig: %s\ntags: %s\n' %
+ (self.config_hash, self.tags_hash))
+ except IOError as exc:
+ logger.warning('Failed to write build info file: %r', exc)
def cleanup(self):
# type: () -> None
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index f8a77ce..f55018b 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -4963,8 +4963,8 @@ class CPPDomain(Domain):
if declTyp == 'templateParam':
return True
objtypes = self.objtypes_for_role(typ)
- if objtypes and declTyp in objtypes:
- return True
+ if objtypes:
+ return declTyp in objtypes
print("Type is %s, declType is %s" % (typ, declTyp))
assert False
if not checkType():
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index eb6fe76..6aa00a8 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -348,6 +348,10 @@ class PyObject(ObjectDescription):
if self.allow_nesting:
classes = self.env.ref_context.setdefault('py:classes', [])
classes.append(prefix)
+ if 'module' in self.options:
+ modules = self.env.ref_context.setdefault('py:modules', [])
+ modules.append(self.env.ref_context.get('py:module'))
+ self.env.ref_context['py:module'] = self.options['module']
def after_content(self):
# type: () -> None
@@ -368,6 +372,12 @@ class PyObject(ObjectDescription):
pass
self.env.ref_context['py:class'] = (classes[-1] if len(classes) > 0
else None)
+ if 'module' in self.options:
+ modules = self.env.ref_context.setdefault('py:modules', [])
+ if modules:
+ self.env.ref_context['py:module'] = modules.pop()
+ else:
+ self.env.ref_context.pop('py:module')
class PyModulelevel(PyObject):
diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py
index 126a962..f522bd5 100644
--- a/sphinx/environment/__init__.py
+++ b/sphinx/environment/__init__.py
@@ -676,19 +676,20 @@ class BuildEnvironment(object):
language = self.config.language or 'en'
self.settings['language_code'] = language
- self.settings['smart_quotes'] = True
- if self.config.html_use_smartypants is not None:
- warnings.warn("html_use_smartypants option is deprecated. Smart "
- "quotes are on by default; if you want to disable "
- "or customize them, use the smart_quotes option in "
- "docutils.conf.",
- RemovedInSphinx17Warning)
- self.settings['smart_quotes'] = self.config.html_use_smartypants
- for tag in normalize_language_tag(language):
- if tag in smartchars.quotes:
- break
- else:
- self.settings['smart_quotes'] = False
+ if 'smart_quotes' not in self.settings:
+ self.settings['smart_quotes'] = True
+ if self.config.html_use_smartypants is not None:
+ warnings.warn("html_use_smartypants option is deprecated. Smart "
+ "quotes are on by default; if you want to disable "
+ "or customize them, use the smart_quotes option in "
+ "docutils.conf.",
+ RemovedInSphinx17Warning)
+ self.settings['smart_quotes'] = self.config.html_use_smartypants
+ for tag in normalize_language_tag(language):
+ if tag in smartchars.quotes:
+ break
+ else:
+ self.settings['smart_quotes'] = False
docutilsconf = path.join(self.srcdir, 'docutils.conf')
# read docutils.conf from source dir, not from current dir
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index bb5f783..d6e61b2 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -368,7 +368,7 @@ def format_annotation(annotation):
Displaying complex types from ``typing`` relies on its private API.
"""
- if typing and isinstance(annotation, typing.TypeVar): # type: ignore
+ if typing and isinstance(annotation, typing.TypeVar):
return annotation.__name__
if annotation == Ellipsis:
return '...'
@@ -971,7 +971,6 @@ class Documenter(object):
# keep documented attributes
keep = True
isattr = True
- print(membername, keep)
elif want_all and membername.startswith('_'):
# ignore members whose name starts with _ by default
keep = self.options.private_members and \
diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py
index d018603..ad50542 100644
--- a/sphinx/ext/intersphinx.py
+++ b/sphinx/ext/intersphinx.py
@@ -217,7 +217,7 @@ def load_mappings(app):
if isinstance(value, (list, tuple)):
# new format
- name, (uri, inv) = key, value # type: ignore
+ name, (uri, inv) = key, value
if not isinstance(name, string_types):
logger.warning('intersphinx identifier %r is not string. Ignored', name)
continue
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index 24e9bee..a584227 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -69,6 +69,8 @@ class Todo(BaseAdmonition):
env = self.state.document.settings.env
targetid = 'index-%s' % env.new_serialno('index')
+ # Stash the target to be retrieved later in latex_visit_todo_node.
+ todo['targetref'] = '%s:%s' % (env.docname, targetid)
targetnode = nodes.target('', '', ids=[targetid])
return [targetnode, todo]
@@ -137,12 +139,15 @@ def process_todo_nodes(app, doctree, fromdocname):
env.todo_all_todos = [] # type: ignore
for node in doctree.traverse(todolist):
+ if node.get('ids'):
+ content = [nodes.target()]
+ else:
+ content = []
+
if not app.config['todo_include_todos']:
- node.replace_self([])
+ node.replace_self(content)
continue
- content = []
-
for todo_info in env.todo_all_todos: # type: ignore
para = nodes.paragraph(classes=['todo-source'])
if app.config['todo_link_only']:
@@ -170,8 +175,12 @@ def process_todo_nodes(app, doctree, fromdocname):
para += newnode
para += nodes.Text(desc2, desc2)
- # (Recursively) resolve references in the todo content
todo_entry = todo_info['todo']
+ # Remove targetref from the (copied) node to avoid emitting a
+ # duplicate label of the original entry when we walk this node.
+ del todo_entry['targetref']
+
+ # (Recursively) resolve references in the todo content
env.resolve_references(todo_entry, todo_info['docname'],
app.builder)
@@ -213,7 +222,13 @@ def depart_todo_node(self, node):
def latex_visit_todo_node(self, node):
# type: (nodes.NodeVisitor, todo_node) -> None
title = node.pop(0).astext().translate(tex_escape_map)
- self.body.append(u'\n\\begin{sphinxadmonition}{note}{%s:}' % title)
+ self.body.append(u'\n\\begin{sphinxadmonition}{note}{')
+ # If this is the original todo node, emit a label that will be referenced by
+ # a hyperref in the todolist.
+ target = node.get('targetref')
+ if target is not None:
+ self.body.append(u'\\label{%s}' % target)
+ self.body.append('%s:}' % title)
def latex_depart_todo_node(self, node):
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index e70de64..67a59b0 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -534,7 +534,7 @@ def valid_dir(d):
if not path.isdir(dir):
return False
- if set(['Makefile', 'make.bat']) & set(os.listdir(dir)):
+ if set(['Makefile', 'make.bat']) & set(os.listdir(dir)): # type: ignore
return False
if d['sep']:
@@ -550,7 +550,7 @@ def valid_dir(d):
d['dot'] + 'templates',
d['master'] + d['suffix'],
]
- if set(reserved_names) & set(os.listdir(dir)):
+ if set(reserved_names) & set(os.listdir(dir)): # type: ignore
return False
return True
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index ef74d3b..1756021 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -265,6 +265,11 @@ class IndexBuilder(object):
# objtype index -> (domain, type, objname (localized))
lang_class = languages.get(lang) # type: Type[SearchLanguage]
# add language-specific SearchLanguage instance
+
+ # fallback; try again with language-code
+ if lang_class is None and '_' in lang:
+ lang_class = languages.get(lang.split('_')[0])
+
if lang_class is None:
self.lang = SearchEnglish(options) # type: SearchLanguage
elif isinstance(lang_class, str):
diff --git a/sphinx/templates/quickstart/Makefile.new_t b/sphinx/templates/quickstart/Makefile.new_t
index bba767a..c7cd62d 100644
--- a/sphinx/templates/quickstart/Makefile.new_t
+++ b/sphinx/templates/quickstart/Makefile.new_t
@@ -3,7 +3,7 @@
# You can set these variables from the command line.
SPHINXOPTS =
-SPHINXBUILD = python -msphinx
+SPHINXBUILD = sphinx-build
SPHINXPROJ = {{ project_fn }}
SOURCEDIR = {{ rsrcdir }}
BUILDDIR = {{ rbuilddir }}
diff --git a/sphinx/templates/quickstart/Makefile_t b/sphinx/templates/quickstart/Makefile_t
index fdcf056..4639a98 100644
--- a/sphinx/templates/quickstart/Makefile_t
+++ b/sphinx/templates/quickstart/Makefile_t
@@ -2,9 +2,9 @@
#
# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = python -msphinx
-PAPER =
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+PAPER ?=
BUILDDIR = {{ rbuilddir }}
# Internal variables.
diff --git a/sphinx/templates/quickstart/conf.py_t b/sphinx/templates/quickstart/conf.py_t
index 2821704..70683f8 100644
--- a/sphinx/templates/quickstart/conf.py_t
+++ b/sphinx/templates/quickstart/conf.py_t
@@ -114,11 +114,8 @@ html_static_path = ['{{ dot }}static']
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
- 'about.html',
- 'navigation.html',
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
- 'donate.html',
]
}
diff --git a/sphinx/templates/quickstart/make.bat.new_t b/sphinx/templates/quickstart/make.bat.new_t
index a52951e..e49ffbe 100644
--- a/sphinx/templates/quickstart/make.bat.new_t
+++ b/sphinx/templates/quickstart/make.bat.new_t
@@ -5,7 +5,7 @@ pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=python -msphinx
+ set SPHINXBUILD=sphinx-build
)
set SOURCEDIR={{ rsrcdir }}
set BUILDDIR={{ rbuilddir }}
@@ -16,10 +16,10 @@ if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
- echo.The Sphinx module was not found. Make sure you have Sphinx installed,
- echo.then set the SPHINXBUILD environment variable to point to the full
- echo.path of the 'sphinx-build' executable. Alternatively you may add the
- echo.Sphinx directory to PATH.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
diff --git a/sphinx/templates/quickstart/make.bat_t b/sphinx/templates/quickstart/make.bat_t
index 03ae9d4..8438b5f 100644
--- a/sphinx/templates/quickstart/make.bat_t
+++ b/sphinx/templates/quickstart/make.bat_t
@@ -5,7 +5,7 @@ REM Command file for Sphinx documentation
pushd %~dp0
if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=python -msphinx
+ set SPHINXBUILD=sphinx-build
)
set BUILDDIR={{ rbuilddir }}
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% {{ rsrcdir }}
@@ -52,20 +52,29 @@ if "%1" == "clean" (
)
-REM Check if sphinx-build is available
+REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
-if errorlevel 1 (
+if errorlevel 9009 goto sphinx_python
+goto sphinx_ok
+
+:sphinx_python
+
+set SPHINXBUILD=python -m sphinx.__init__
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
echo.
- echo.The Sphinx module was not found. Make sure you have Sphinx installed,
- echo.then set the SPHINXBUILD environment variable to point to the full
- echo.path of the 'sphinx-build' executable. Alternatively you may add the
- echo.Sphinx directory to PATH.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
+:sphinx_ok
+
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t
index 1cbc649..d16c760 100644
--- a/sphinx/themes/basic/static/basic.css_t
+++ b/sphinx/themes/basic/static/basic.css_t
@@ -445,10 +445,14 @@ dd {
margin-left: 30px;
}
-dt:target, .highlighted {
+dt:target, span.highlighted {
background-color: #fbe54e;
}
+rect.highlighted {
+ fill: #fbe54e;
+}
+
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
diff --git a/sphinx/themes/basic/static/doctools.js_t b/sphinx/themes/basic/static/doctools.js_t
index 41830e4..9ceecef 100644
--- a/sphinx/themes/basic/static/doctools.js_t
+++ b/sphinx/themes/basic/static/doctools.js_t
@@ -45,7 +45,7 @@ jQuery.urlencode = encodeURIComponent;
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
- if (typeof s == 'undefined')
+ if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
@@ -66,29 +66,53 @@ jQuery.getQueryParameters = function(s) {
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
- function highlight(node) {
- if (node.nodeType == 3) {
+ function highlight(node, addItems) {
+ if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
- var span = document.createElement("span");
- span.className = className;
+ var span;
+ var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.className = className;
+ }
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
+ if (isInSVG) {
+ var bbox = span.getBBox();
+ var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+ rect.x.baseVal.value = bbox.x;
+ rect.y.baseVal.value = bbox.y;
+ rect.width.baseVal.value = bbox.width;
+ rect.height.baseVal.value = bbox.height;
+ rect.setAttribute('class', className);
+ var parentOfText = node.parentNode.parentNode;
+ addItems.push({
+ "parent": node.parentNode,
+ "target": rect});
+ }
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
- highlight(this);
+ highlight(this, addItems);
});
}
}
- return this.each(function() {
- highlight(this);
+ var addItems = [];
+ var result = this.each(function() {
+ highlight(this, addItems);
});
+ for (var i = 0; i < addItems.length; ++i) {
+ jQuery(addItems[i].parent).before(addItems[i].target);
+ }
+ return result;
};
/*
@@ -133,21 +157,21 @@ var Documentation = {
* i18n support
*/
TRANSLATIONS : {},
- PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+ PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
- if (typeof translated == 'undefined')
+ if (typeof translated === 'undefined')
return string;
- return (typeof translated == 'string') ? translated : translated[0];
+ return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
- if (typeof translated == 'undefined')
+ if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
@@ -218,7 +242,7 @@ var Documentation = {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
- if (src.substr(-9) == 'minus.png')
+ if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
@@ -250,7 +274,7 @@ var Documentation = {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
- if (this == '..')
+ if (this === '..')
parts.pop();
});
var url = parts.join('/');
diff --git a/sphinx/themes/basic/static/searchtools.js_t b/sphinx/themes/basic/static/searchtools.js_t
index 149d162..306fdf5 100644
--- a/sphinx/themes/basic/static/searchtools.js_t
+++ b/sphinx/themes/basic/static/searchtools.js_t
@@ -269,6 +269,9 @@ var Search = {
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
+ if (suffix === undefined) {
+ suffix = '.txt';
+ }
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
dataType: "text",
complete: function(jqxhr, textstatus) {
diff --git a/sphinx/transforms/i18n.py b/sphinx/transforms/i18n.py
index 2618c72..4c1fbc2 100644
--- a/sphinx/transforms/i18n.py
+++ b/sphinx/transforms/i18n.py
@@ -273,7 +273,11 @@ class Locale(SphinxTransform):
old_foot_refs = node.traverse(is_autonumber_footnote_ref)
new_foot_refs = patch.traverse(is_autonumber_footnote_ref)
if len(old_foot_refs) != len(new_foot_refs):
- logger.warning('inconsistent footnote references in translated message',
+ old_foot_ref_rawsources = [ref.rawsource for ref in old_foot_refs]
+ new_foot_ref_rawsources = [ref.rawsource for ref in new_foot_refs]
+ logger.warning('inconsistent footnote references in translated message.' +
+ ' original: {0}, translated: {1}'
+ .format(old_foot_ref_rawsources, new_foot_ref_rawsources),
location=node)
old_foot_namerefs = {} # type: Dict[unicode, List[nodes.footnote_reference]]
for r in old_foot_refs:
@@ -309,7 +313,11 @@ class Locale(SphinxTransform):
old_refs = node.traverse(is_refnamed_ref)
new_refs = patch.traverse(is_refnamed_ref)
if len(old_refs) != len(new_refs):
- logger.warning('inconsistent references in translated message',
+ old_ref_rawsources = [ref.rawsource for ref in old_refs]
+ new_ref_rawsources = [ref.rawsource for ref in new_refs]
+ logger.warning('inconsistent references in translated message.' +
+ ' original: {0}, translated: {1}'
+ .format(old_ref_rawsources, new_ref_rawsources),
location=node)
old_ref_names = [r['refname'] for r in old_refs]
new_ref_names = [r['refname'] for r in new_refs]
@@ -327,22 +335,46 @@ class Locale(SphinxTransform):
self.document.note_refname(new)
- # refnamed footnote and citation should use original 'ids'.
+ # refnamed footnote should use original 'ids'.
def is_refnamed_footnote_ref(node):
# type: (nodes.Node) -> bool
- footnote_ref_classes = (nodes.footnote_reference,
- nodes.citation_reference)
- return isinstance(node, footnote_ref_classes) and \
+ return isinstance(node, nodes.footnote_reference) and \
'refname' in node
- old_refs = node.traverse(is_refnamed_footnote_ref)
- new_refs = patch.traverse(is_refnamed_footnote_ref)
+ old_foot_refs = node.traverse(is_refnamed_footnote_ref)
+ new_foot_refs = patch.traverse(is_refnamed_footnote_ref)
refname_ids_map = {}
- if len(old_refs) != len(new_refs):
- logger.warning('inconsistent references in translated message',
+ if len(old_foot_refs) != len(new_foot_refs):
+ old_foot_ref_rawsources = [ref.rawsource for ref in old_foot_refs]
+ new_foot_ref_rawsources = [ref.rawsource for ref in new_foot_refs]
+ logger.warning('inconsistent footnote references in translated message.' +
+ ' original: {0}, translated: {1}'
+ .format(old_foot_ref_rawsources, new_foot_ref_rawsources),
location=node)
- for old in old_refs:
+ for old in old_foot_refs:
refname_ids_map[old["refname"]] = old["ids"]
- for new in new_refs:
+ for new in new_foot_refs:
+ refname = new["refname"]
+ if refname in refname_ids_map:
+ new["ids"] = refname_ids_map[refname]
+
+ # citation should use original 'ids'.
+ def is_citation_ref(node):
+ # type: (nodes.Node) -> bool
+ return isinstance(node, nodes.citation_reference) and \
+ 'refname' in node
+ old_cite_refs = node.traverse(is_citation_ref)
+ new_cite_refs = patch.traverse(is_citation_ref)
+ refname_ids_map = {}
+ if len(old_cite_refs) != len(new_cite_refs):
+ old_cite_ref_rawsources = [ref.rawsource for ref in old_cite_refs]
+ new_cite_ref_rawsources = [ref.rawsource for ref in new_cite_refs]
+ logger.warning('inconsistent citation references in translated message.' +
+ ' original: {0}, translated: {1}'
+ .format(old_cite_ref_rawsources, new_cite_ref_rawsources),
+ location=node)
+ for old in old_cite_refs:
+ refname_ids_map[old["refname"]] = old["ids"]
+ for new in new_cite_refs:
refname = new["refname"]
if refname in refname_ids_map:
new["ids"] = refname_ids_map[refname]
@@ -354,7 +386,11 @@ class Locale(SphinxTransform):
new_refs = patch.traverse(addnodes.pending_xref)
xref_reftarget_map = {}
if len(old_refs) != len(new_refs):
- logger.warning('inconsistent term references in translated message',
+ old_ref_rawsources = [ref.rawsource for ref in old_refs]
+ new_ref_rawsources = [ref.rawsource for ref in new_refs]
+ logger.warning('inconsistent term references in translated message.' +
+ ' original: {0}, translated: {1}'
+ .format(old_ref_rawsources, new_ref_rawsources),
location=node)
def get_ref_key(node):
diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py
index c984bcf..92e6c8c 100644
--- a/sphinx/util/docutils.py
+++ b/sphinx/util/docutils.py
@@ -26,8 +26,7 @@ from sphinx.locale import __
from sphinx.util import logging
logger = logging.getLogger(__name__)
-report_re = re.compile('^(.+?:(?:\\d+)?): \\((DEBUG|INFO|WARNING|ERROR|SEVERE)/(\\d+)?\\) '
- '(.+?)\n?$')
+report_re = re.compile('^(.+?:(?:\\d+)?): \\((DEBUG|INFO|WARNING|ERROR|SEVERE)/(\\d+)?\\) ')
if False:
# For type annotation
@@ -162,7 +161,8 @@ class WarningStream(object):
if not matched:
logger.warning(text.rstrip("\r\n"))
else:
- location, type, level, message = matched.groups()
+ location, type, level = matched.groups()
+ message = report_re.sub('', text).rstrip() # type: ignore
logger.log(type, message, location=location)
diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py
index 218fac1..09b53b4 100644
--- a/sphinx/util/i18n.py
+++ b/sphinx/util/i18n.py
@@ -67,15 +67,15 @@ class CatalogInfo(LocaleFileInfoBase):
with io.open(self.po_path, 'rt', encoding=self.charset) as file_po:
try:
po = read_po(file_po, locale)
- except Exception:
- logger.warning('reading error: %s', self.po_path)
+ except Exception as exc:
+ logger.warning('reading error: %s, %s', self.po_path, exc)
return
with io.open(self.mo_path, 'wb') as file_mo:
try:
write_mo(file_mo, po)
- except Exception:
- logger.warning('writing error: %s', self.mo_path)
+ except Exception as exc:
+ logger.warning('writing error: %s, %s', self.mo_path, exc)
def find_catalog(docname, compaction):
diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py
index 2cdac6c..17ee88a 100644
--- a/sphinx/util/logging.py
+++ b/sphinx/util/logging.py
@@ -136,13 +136,13 @@ class NewLineStreamHandlerPY2(logging.StreamHandler):
# type: (logging.LogRecord) -> None
try:
self.acquire()
- stream = self.stream # type: ignore
+ stream = self.stream
if getattr(record, 'nonl', False):
# remove return code forcely when nonl=True
self.stream = StringIO()
super(NewLineStreamHandlerPY2, self).emit(record)
- stream.write(self.stream.getvalue()[:-1])
- stream.flush()
+ stream.write(self.stream.getvalue()[:-1]) # type: ignore
+ stream.flush() # type: ignore
else:
super(NewLineStreamHandlerPY2, self).emit(record)
finally:
@@ -356,11 +356,15 @@ class WarningIsErrorFilter(logging.Filter):
return True
elif self.app.warningiserror:
location = getattr(record, 'location', '')
- message = record.msg.replace('%', '%%')
+ try:
+ message = record.msg % record.args
+ except TypeError:
+ message = record.msg # use record.msg itself
+
if location:
- raise SphinxWarning(location + ":" + message % record.args)
+ raise SphinxWarning(location + ":" + message)
else:
- raise SphinxWarning(message % record.args)
+ raise SphinxWarning(message)
else:
return True
diff --git a/sphinx/util/matching.py b/sphinx/util/matching.py
index 3990e0e..401f5f0 100644
--- a/sphinx/util/matching.py
+++ b/sphinx/util/matching.py
@@ -96,7 +96,7 @@ _pat_cache = {} # type: Dict[unicode, Pattern]
def patmatch(name, pat):
- # type: (unicode, unicode) -> re.Match
+ # type: (unicode, unicode) -> Match[unicode]
"""Return if name matches pat. Adapted from fnmatch module."""
if pat not in _pat_cache:
_pat_cache[pat] = re.compile(_translate_pattern(pat))
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 6122c16..7f7ee4e 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -36,7 +36,7 @@ if PY3:
from io import TextIOWrapper
else:
def TextIOWrapper(stream, encoding):
- # type: (file, str) -> unicode
+ # type: (file, str) -> Any
return codecs.lookup(encoding or 'ascii')[2](stream)
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index 6dd8baf..8d02793 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -89,6 +89,7 @@ class HTMLTranslator(BaseTranslator):
self.param_separator = ''
self.optional_param_level = 0
self._table_row_index = 0
+ self._fieldlist_row_index = 0
self.required_params_left = 0
def visit_start_of_file(self, node):
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 0e2a726..83ccd54 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -1702,9 +1702,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
pre = [] # type: List[unicode]
# in reverse order
post = [] # type: List[unicode]
- if self.in_parsed_literal:
- pre = ['\\begingroup\\sphinxunactivateextrasandspace\\relax ']
- post = ['\\endgroup ']
include_graphics_options = []
is_inline = self.is_inline(node)
if 'width' in attrs:
@@ -1744,6 +1741,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
post.append(align_prepost[is_inline, attrs['align']][1])
except KeyError:
pass
+ if self.in_parsed_literal:
+ pre.append('{\\sphinxunactivateextrasandspace ')
+ post.append('}')
if not is_inline:
pre.append('\n\\noindent')
post.append('\n')
diff --git a/tests/roots/test-domain-cpp/roles2.rst b/tests/roots/test-domain-cpp/roles2.rst
new file mode 100644
index 0000000..644b827
--- /dev/null
+++ b/tests/roots/test-domain-cpp/roles2.rst
@@ -0,0 +1,5 @@
+Check that we don't crash just because we misuse a role.
+
+.. cpp:class:: A
+
+:cpp:func:`A`
diff --git a/tests/roots/test-domain-py/module_option.rst b/tests/roots/test-domain-py/module_option.rst
new file mode 100644
index 0000000..1dec2ce
--- /dev/null
+++ b/tests/roots/test-domain-py/module_option.rst
@@ -0,0 +1,25 @@
+module_option
+=============
+
+.. py:class:: B
+ :module: test.extra
+
+ This is also a test.
+
+
+ .. py:method:: B.baz()
+ :module: test.extra
+
+ Does something similar to :meth:`foo`.
+
+
+ .. py:method:: B.foo()
+ :module: test.extra
+
+ Does something.
+
+
+ .. py:method:: B.test()
+ :module: test.extra
+
+ Does something completely unrelated to :meth:`foo`
diff --git a/tests/roots/test-ext-todo/conf.py b/tests/roots/test-ext-todo/conf.py
index c67a86c..5d56192 100644
--- a/tests/roots/test-ext-todo/conf.py
+++ b/tests/roots/test-ext-todo/conf.py
@@ -2,3 +2,8 @@
extensions = ['sphinx.ext.todo']
master_doc = 'index'
+
+latex_documents = [
+ (master_doc, 'TodoTests.tex', 'Todo Tests Documentation',
+ 'Robin Banks', 'manual'),
+]
diff --git a/tests/roots/test-image-in-parsed-literal/conf.py b/tests/roots/test-image-in-parsed-literal/conf.py
new file mode 100644
index 0000000..d208b83
--- /dev/null
+++ b/tests/roots/test-image-in-parsed-literal/conf.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+
+master_doc = 'index'
+exclude_patterns = ['_build']
+
+rst_epilog = '''
+.. |picture| image:: pic.png
+ :height: 1cm
+ :scale: 200%
+ :align: middle
+ :alt: alternative_text
+'''
+
diff --git a/tests/roots/test-image-in-parsed-literal/index.rst b/tests/roots/test-image-in-parsed-literal/index.rst
new file mode 100644
index 0000000..80e1008
--- /dev/null
+++ b/tests/roots/test-image-in-parsed-literal/index.rst
@@ -0,0 +1,9 @@
+test-image-in-parsed-literal
+============================
+
+Dummy text
+
+.. parsed-literal::
+
+ |picture|\ AFTER
+
diff --git a/tests/roots/test-image-in-parsed-literal/pic.png b/tests/roots/test-image-in-parsed-literal/pic.png
new file mode 100644
index 0000000..fda6cd2
--- /dev/null
+++ b/tests/roots/test-image-in-parsed-literal/pic.png
Binary files differ
diff --git a/tests/roots/test-intl/refs_inconsistency.po b/tests/roots/test-intl/refs_inconsistency.po
index cb2de9a..9d8d13f 100644
--- a/tests/roots/test-intl/refs_inconsistency.po
+++ b/tests/roots/test-intl/refs_inconsistency.po
@@ -19,8 +19,8 @@ msgstr ""
msgid "i18n with refs inconsistency"
msgstr "I18N WITH REFS INCONSISTENCY"
-msgid "[100]_ for [#]_ footnote [ref2]_."
-msgstr "FOR FOOTNOTE [ref2]_."
+msgid "[100]_ for [#]_ citation [ref2]_."
+msgstr "FOR CITATION [ref3]_."
msgid "for reference_."
msgstr "reference_ FOR reference_."
@@ -31,8 +31,8 @@ msgstr "ORPHAN REFERENCE: `I18N WITH REFS INCONSISTENCY`_."
msgid "This is a auto numbered footnote."
msgstr "THIS IS A AUTO NUMBERED FOOTNOTE."
-msgid "This is a named footnote."
-msgstr "THIS IS A NAMED FOOTNOTE."
+msgid "This is a citation."
+msgstr "THIS IS A CITATION."
msgid "This is a numbered footnote."
msgstr "THIS IS A NUMBERED FOOTNOTE."
diff --git a/tests/roots/test-intl/refs_inconsistency.txt b/tests/roots/test-intl/refs_inconsistency.txt
index c65c5b4..b16623a 100644
--- a/tests/roots/test-intl/refs_inconsistency.txt
+++ b/tests/roots/test-intl/refs_inconsistency.txt
@@ -3,11 +3,11 @@
i18n with refs inconsistency
=============================
-* [100]_ for [#]_ footnote [ref2]_.
+* [100]_ for [#]_ citation [ref2]_.
* for reference_.
* normal text.
.. [#] This is a auto numbered footnote.
-.. [ref2] This is a named footnote.
+.. [ref2] This is a citation.
.. [100] This is a numbered footnote.
.. _reference: http://www.example.com
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index a53c146..f36aa35 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -1029,3 +1029,13 @@ def test_latex_index(app, status, warning):
result = (app.outdir / 'Python.tex').text(encoding='utf8')
assert 'A \\index{famous}famous \\index{equation}equation:\n' in result
assert '\n\\index{Einstein}\\index{relativity}\\ignorespaces \nand' in result
+
+
+@pytest.mark.sphinx('latex', testroot='image-in-parsed-literal')
+def test_latex_image_in_parsed_literal(app, status, warning):
+ app.builder.build_all()
+
+ result = (app.outdir / 'Python.tex').text(encoding='utf8')
+ assert ('{\\sphinxunactivateextrasandspace \\raisebox{-0.5\height}'
+ '{\\scalebox{2.000000}{\\sphinxincludegraphics[height=1cm]{{pic}.png}}}'
+ '}AFTER') in result
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
index 08ca6f9..2932f35 100644
--- a/tests/test_domain_cpp.py
+++ b/tests/test_domain_cpp.py
@@ -508,6 +508,13 @@ def test_attributes():
# raise DefinitionError("")
+@pytest.mark.sphinx(testroot='domain-cpp')
+def test_build_domain_cpp_misuse_of_roles(app, status, warning):
+ app.builder.build_all()
+
+ # TODO: properly check for the warnings we expect
+
+
@pytest.mark.sphinx(testroot='domain-cpp', confoverrides={'add_function_parentheses': True})
def test_build_domain_cpp_with_add_function_parentheses_is_True(app, status, warning):
app.builder.build_all()
diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py
index 28743f9..5596950 100644
--- a/tests/test_domain_py.py
+++ b/tests/test_domain_py.py
@@ -115,6 +115,15 @@ def test_domain_py_xrefs(app, status, warning):
assert_refnode(refnodes[10], False, False, 'float', 'obj')
assert len(refnodes) == 11
+ doctree = app.env.get_doctree('module_option')
+ refnodes = list(doctree.traverse(addnodes.pending_xref))
+ print(refnodes)
+ print(refnodes[0])
+ print(refnodes[1])
+ assert_refnode(refnodes[0], 'test.extra', 'B', 'foo', 'meth')
+ assert_refnode(refnodes[1], 'test.extra', 'B', 'foo', 'meth')
+ assert len(refnodes) == 2
+
@pytest.mark.sphinx('dummy', testroot='domain-py')
def test_domain_py_objects(app, status, warning):
diff --git a/tests/test_ext_todo.py b/tests/test_ext_todo.py
index 77d657a..4f01a07 100644
--- a/tests/test_ext_todo.py
+++ b/tests/test_ext_todo.py
@@ -84,3 +84,31 @@ def test_todo_not_included(app, status, warning):
# check handled event
assert len(todos) == 2
assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
+
+@pytest.mark.sphinx('latex', testroot='ext-todo', freshenv=True,
+ confoverrides={'todo_include_todos': True, 'todo_emit_warnings': True})
+def test_todo_valid_link(app, status, warning):
+ """
+ Test that the inserted "original entry" links for todo items have a target
+ that exists in the LaTeX output. The target was previously incorrectly
+ omitted (GitHub issue #1020).
+ """
+
+ # Ensure the LaTeX output is built.
+ app.builder.build_all()
+
+ content = (app.outdir / 'TodoTests.tex').text()
+
+ # Look for the link to foo. We could equally well look for the link to bar.
+ link = r'\{\\hyperref\[\\detokenize\{(.*?foo.*?)}]\{\\sphinxcrossref{' \
+ r'\\sphinxstyleemphasis{original entry}}}}'
+ m = re.findall(link, content)
+ assert len(m) == 1
+ target = m[0]
+
+ # Look for the targets of this link.
+ labels = [m for m in re.findall(r'\\label\{([^}]*)}', content)
+ if m == target]
+
+ # If everything is correct we should have exactly one target.
+ assert len(labels) == 1
diff --git a/tests/test_intl.py b/tests/test_intl.py
index 413276e..f3952e9 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -182,23 +182,45 @@ def test_text_inconsistency_warnings(app, warning):
result = (app.outdir / 'refs_inconsistency.txt').text(encoding='utf-8')
expect = (u"I18N WITH REFS INCONSISTENCY"
u"\n****************************\n"
- u"\n* FOR FOOTNOTE [ref2].\n"
+ u"\n* FOR CITATION [ref3].\n"
u"\n* reference FOR reference.\n"
u"\n* ORPHAN REFERENCE: I18N WITH REFS INCONSISTENCY.\n"
u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n"
- u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n"
+ u"\n[ref2] THIS IS A CITATION.\n"
u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n")
assert result == expect
warnings = getwarning(warning)
warning_fmt = u'.*/refs_inconsistency.txt:\\d+: ' \
- u'WARNING: inconsistent %s in translated message\n'
+ u'WARNING: inconsistent %(reftype)s in translated message.' \
+ u' original: %(original)s, translated: %(translated)s\n'
expected_warning_expr = (
- warning_fmt % 'footnote references' +
- warning_fmt % 'references' +
- warning_fmt % 'references')
+ warning_fmt % {
+ u'reftype': u'footnote references',
+ u'original': u"\[u?'\[#\]_'\]",
+ u'translated': u"\[\]"
+ } +
+ warning_fmt % {
+ u'reftype': u'footnote references',
+ u'original': u"\[u?'\[100\]_'\]",
+ u'translated': u"\[\]"
+ } +
+ warning_fmt % {
+ u'reftype': u'references',
+ u'original': u"\[u?'reference_'\]",
+ u'translated': u"\[u?'reference_', u?'reference_'\]"
+ } +
+ warning_fmt % {
+ u'reftype': u'references',
+ u'original': u"\[\]",
+ u'translated': u"\[u?'`I18N WITH REFS INCONSISTENCY`_'\]"
+ })
assert_re_search(expected_warning_expr, warnings)
+ expected_citation_warning_expr = (
+ u'.*/refs_inconsistency.txt:\\d+: WARNING: Citation \[ref2\] is not referenced.\n' +
+ u'.*/refs_inconsistency.txt:\\d+: WARNING: citation not found: ref3')
+ assert_re_search(expected_citation_warning_expr, warnings)
@sphinx_intl
@pytest.mark.sphinx('text')
@@ -277,7 +299,9 @@ def test_text_glossary_term_inconsistencies(app, warning):
warnings = getwarning(warning)
expected_warning_expr = (
u'.*/glossary_terms_inconsistency.txt:\\d+: '
- u'WARNING: inconsistent term references in translated message\n')
+ u'WARNING: inconsistent term references in translated message.'
+ u" original: \[u?':term:`Some term`', u?':term:`Some other term`'\],"
+ u" translated: \[u?':term:`SOME NEW TERM`'\]\n")
assert_re_search(expected_warning_expr, warnings)
diff --git a/tests/test_search.py b/tests/test_search.py
index 21c0bad..f1825df 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -228,3 +228,15 @@ def test_IndexBuilder():
}
assert index._objtypes == {('dummy', 'objtype'): 0}
assert index._objnames == {0: ('dummy', 'objtype', 'objtype')}
+
+
+def test_IndexBuilder_lookup():
+ env = DummyEnvironment('1.0', {})
+
+ # zh
+ index = IndexBuilder(env, 'zh', {}, None)
+ assert index.lang.lang == 'zh'
+
+ # zh_CN
+ index = IndexBuilder(env, 'zh_CN', {}, None)
+ assert index.lang.lang == 'zh'
diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py
index 717aa6c..7ae0868 100644
--- a/tests/test_util_logging.py
+++ b/tests/test_util_logging.py
@@ -165,7 +165,11 @@ def test_warningiserror(app, status, warning):
# if True, warning raises SphinxWarning exception
app.warningiserror = True
with pytest.raises(SphinxWarning):
- logger.warning('message')
+ logger.warning('message: %s', 'arg')
+
+ # message contains format string (refs: #4070)
+ with pytest.raises(SphinxWarning):
+ logger.warning('%s')
def test_warning_location(app, status, warning):
diff --git a/tests/test_writer_latex.py b/tests/test_writer_latex.py
index 2281618..b026f8d 100644
--- a/tests/test_writer_latex.py
+++ b/tests/test_writer_latex.py
@@ -27,7 +27,7 @@ def test_rstdim_to_latexdim():
assert rstdim_to_latexdim('30%') == '0.300\\linewidth'
assert rstdim_to_latexdim('160') == '160\\sphinxpxdimen'
- # flaot values
+ # float values
assert rstdim_to_latexdim('160.0em') == '160.0em'
assert rstdim_to_latexdim('.5em') == '.5em'