summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2019-12-16 00:05:35 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2019-12-16 00:05:35 +0900
commit712c20a3d91cd80247c5625782ba8ada2b2c2378 (patch)
treed151c391d9bc18aa2ceffa455efa658bafc1ec29
parent5a03cac7d369ea71e1414792df62668ca5fd8190 (diff)
parentcb5fab5db90c2177ede34af876b19e58b9dc1263 (diff)
downloadsphinx-git-712c20a3d91cd80247c5625782ba8ada2b2c2378.tar.gz
Merge branch '2.0'
-rw-r--r--.travis.yml3
-rw-r--r--CHANGES54
-rw-r--r--doc/develop.rst2
-rw-r--r--doc/extdev/deprecated.rst5
-rw-r--r--doc/usage/restructuredtext/directives.rst2
-rw-r--r--sphinx/builders/__init__.py2
-rw-r--r--sphinx/builders/gettext.py4
-rw-r--r--sphinx/builders/latex/__init__.py13
-rw-r--r--sphinx/config.py6
-rw-r--r--sphinx/domains/std.py12
-rw-r--r--sphinx/highlighting.py1
-rw-r--r--sphinx/templates/gettext/message.pot_t4
-rw-r--r--sphinx/texinputs/sphinx.sty28
-rw-r--r--sphinx/texinputs/sphinx.xdy6
-rw-r--r--sphinx/util/nodes.py2
-rw-r--r--sphinx/util/texescape.py37
-rw-r--r--sphinx/writers/html.py20
-rw-r--r--sphinx/writers/html5.py23
-rw-r--r--sphinx/writers/latex.py26
-rw-r--r--tests/roots/test-latex-table/expects/complex_spanning_cell.tex18
-rw-r--r--tests/roots/test-latex-table/expects/gridtable.tex16
-rw-r--r--tests/roots/test-latex-table/expects/longtable.tex12
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_align.tex12
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_caption.tex12
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex10
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex14
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_verbatim.tex10
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_widths.tex12
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex10
-rw-r--r--tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex12
-rw-r--r--tests/roots/test-latex-table/expects/simple_table.tex12
-rw-r--r--tests/roots/test-latex-table/expects/table_having_caption.tex12
-rw-r--r--tests/roots/test-latex-table/expects/table_having_problematic_cell.tex10
-rw-r--r--tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex14
-rw-r--r--tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex6
-rw-r--r--tests/roots/test-latex-table/expects/table_having_verbatim.tex10
-rw-r--r--tests/roots/test-latex-table/expects/table_having_widths.tex12
-rw-r--r--tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex10
-rw-r--r--tests/roots/test-latex-table/expects/tabular_having_widths.tex12
-rw-r--r--tests/roots/test-latex-table/expects/tabularcolumn.tex12
-rw-r--r--tests/roots/test-latex-table/expects/tabulary_having_widths.tex12
-rw-r--r--tests/test_build_html.py71
-rw-r--r--tests/test_build_latex.py36
-rw-r--r--tests/test_config.py14
-rw-r--r--tests/test_directive_code.py2
-rw-r--r--tests/test_markup.py6
-rw-r--r--tox.ini2
47 files changed, 376 insertions, 265 deletions
diff --git a/.travis.yml b/.travis.yml
index b145ceb8a..008f4e442 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,7 +25,8 @@ matrix:
- TOXENV=du15
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
- python: 'nightly'
- env: TOXENV=py38
+ env:
+ - TOXENV=du16
- python: '3.6'
env: TOXENV=docs
- python: '3.6'
diff --git a/CHANGES b/CHANGES
index ac8d2ddc2..8fbca5bc9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -30,7 +30,7 @@ Bugs fixed
Testing
--------
-Release 2.3.0 (in development)
+Release 2.4.0 (in development)
==============================
Dependencies
@@ -39,6 +39,24 @@ Dependencies
Incompatible changes
--------------------
+Deprecated
+----------
+
+Features added
+--------------
+
+Bugs fixed
+----------
+
+Testing
+--------
+
+Release 2.3.0 (released Dec 15, 2019)
+=====================================
+
+Incompatible changes
+--------------------
+
* #6742: ``end-before`` option of :rst:dir:`literalinclude` directive does not
match the first line of the code block.
* #1331: Change default User-Agent header to ``"Sphinx/X.Y.Z requests/X.Y.Z
@@ -53,6 +71,7 @@ Deprecated
* ``sphinx.io.SphinxStandaloneReader.env``
* ``sphinx.util.texescape.tex_escape_map``
* ``sphinx.util.texescape.tex_hl_escape_map_new``
+* ``sphinx.writers.latex.LaTeXTranslator.no_contractions``
Features added
--------------
@@ -76,6 +95,9 @@ Features added
* #6816: linkcheck: Add :confval:`linkcheck_auth` option to provide
authentication information when doing ``linkcheck`` builds
* #6872: linkcheck: Handles HTTP 308 Permanent Redirect
+* #6613: html: Wrap section number in span tag
+* #6781: gettext: Add :confval:`gettext_last_translator' and
+ :confval:`gettext_language_team` to customize headers of POT file
Bugs fixed
----------
@@ -115,31 +137,13 @@ Bugs fixed
* #6867: text: extra spaces are inserted to hyphenated words on folding lines
* #6886: LaTeX: xelatex converts straight double quotes into right curly ones
(shows when :confval:`smartquotes` is ``False``)
+* #6890: LaTeX: even with smartquotes off, PDF output transforms straight
+ quotes and consecutive hyphens into curly quotes and dashes
* #6876: LaTeX: multi-line display of authors on title page has ragged edges
-
-Testing
---------
-
-Release 2.2.3 (in development)
-==============================
-
-Dependencies
-------------
-
-Incompatible changes
---------------------
-
-Deprecated
-----------
-
-Features added
---------------
-
-Bugs fixed
-----------
-
-Testing
---------
+* #6887: Sphinx crashes with docutils-0.16b0
+* #6920: sphinx-build: A console message is wrongly highlighted
+* #6900: sphinx-build: ``-D`` option does not considers ``0`` and ``1`` as a
+ boolean value
Release 2.2.2 (released Dec 03, 2019)
=====================================
diff --git a/doc/develop.rst b/doc/develop.rst
index 0612c7113..d4b9a0e5d 100644
--- a/doc/develop.rst
+++ b/doc/develop.rst
@@ -36,6 +36,7 @@ This is the current list of contributed extensions in that repository:
- astah: embed diagram by using astah
- autoanysrc: Gather reST documentation from any source files
- autorun: Execute code in a ``runblock`` directive
+- beamer_: A builder for Beamer (LaTeX) output.
- blockdiag: embed block diagrams by using blockdiag_
- cacoo: embed diagram from Cacoo
- cf3domain: a domain for CFEngine 3 policies
@@ -148,3 +149,4 @@ started with writing your own extensions.
.. _domaintools: https://bitbucket.org/klorenz/sphinxcontrib-domaintools
.. _restbuilder: https://pypi.org/project/sphinxcontrib-restbuilder/
.. _Lasso: http://www.lassosoft.com/
+.. _beamer: https://pypi.org/project/sphinxcontrib-beamer/
diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst
index 958f4ee4d..482cb50bb 100644
--- a/doc/extdev/deprecated.rst
+++ b/doc/extdev/deprecated.rst
@@ -51,6 +51,11 @@ The following is a list of deprecated interfaces.
- 4.0
- ``sphinx.util.texescape.hlescape()``
+ * - ``sphinx.writers.latex.LaTeXTranslator.no_contractions``
+ - 2.3
+ - 4.0
+ - N/A
+
* - ``sphinx.domains.math.MathDomain.add_equation()``
- 2.2
- 4.0
diff --git a/doc/usage/restructuredtext/directives.rst b/doc/usage/restructuredtext/directives.rst
index f546036d0..92ca3eae2 100644
--- a/doc/usage/restructuredtext/directives.rst
+++ b/doc/usage/restructuredtext/directives.rst
@@ -522,7 +522,7 @@ __ http://pygments.org/docs/lexers
.. rst:directive:option:: emphasize-lines: line numbers
:type: comma separated numbers
- Empahsize particular lines of the code block::
+ Emphasize particular lines of the code block::
.. code-block:: python
:emphasize-lines: 3,5
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index d2040498e..777536d3e 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -304,7 +304,7 @@ class Builder:
First updates the environment, and then calls :meth:`write`.
"""
if summary:
- logger.info(bold(__('building [%s]') % self.name) + ': ' + summary)
+ logger.info(bold(__('building [%s]: ') % self.name) + summary)
# while reading, collect all warnings from docutils
with logging.pending_warnings():
diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py
index ea6fa61a9..e7adb0b8c 100644
--- a/sphinx/builders/gettext.py
+++ b/sphinx/builders/gettext.py
@@ -282,6 +282,8 @@ class MessageCatalogBuilder(I18nBuilder):
'version': self.config.version,
'copyright': self.config.copyright,
'project': self.config.project,
+ 'last_translator': self.config.gettext_last_translator,
+ 'language_team': self.config.gettext_language_team,
'ctime': datetime.fromtimestamp(timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
'display_location': self.config.gettext_location,
'display_uuid': self.config.gettext_uuid,
@@ -311,6 +313,8 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('gettext_uuid', False, 'gettext')
app.add_config_value('gettext_auto_build', True, 'env')
app.add_config_value('gettext_additional_targets', [], 'env')
+ app.add_config_value('gettext_last_translator', 'FULL NAME <EMAIL@ADDRESS>', 'gettext')
+ app.add_config_value('gettext_language_team', 'LANGUAGE <LL@li.org>', 'gettext')
return {
'version': 'builtin',
diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py
index c24e87a13..de4223a0e 100644
--- a/sphinx/builders/latex/__init__.py
+++ b/sphinx/builders/latex/__init__.py
@@ -234,14 +234,13 @@ class LaTeXBuilder(Builder):
destination = SphinxFileOutput(destination_path=path.join(self.outdir, targetname),
encoding='utf-8', overwrite_if_changed=True)
with progress_message(__("processing %s") % targetname):
- toctrees = self.env.get_doctree(docname).traverse(addnodes.toctree)
- if toctrees:
- if toctrees[0].get('maxdepth') > 0:
- tocdepth = toctrees[0].get('maxdepth')
- else:
- tocdepth = None
+ doctree = self.env.get_doctree(docname)
+ toctree = next(iter(doctree.traverse(addnodes.toctree)), None)
+ if toctree and toctree.get('maxdepth') > 0:
+ tocdepth = toctree.get('maxdepth')
else:
tocdepth = None
+
doctree = self.assemble_doctree(
docname, toctree_only,
appendices=((docclass != 'howto') and self.config.latex_appendices or []))
@@ -465,7 +464,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('latex_logo', None, None, [str])
app.add_config_value('latex_appendices', [], None)
app.add_config_value('latex_use_latex_multicolumn', False, None)
- app.add_config_value('latex_use_xindy', default_latex_use_xindy, None)
+ app.add_config_value('latex_use_xindy', default_latex_use_xindy, None, [bool])
app.add_config_value('latex_toplevel_sectioning', None, None,
ENUM(None, 'part', 'chapter', 'section'))
app.add_config_value('latex_domain_indices', True, None, [list])
diff --git a/sphinx/config.py b/sphinx/config.py
index 691cdac11..c12841acb 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -186,6 +186,12 @@ class Config:
defvalue = self.values[name][0]
if self.values[name][2] == Any:
return value
+ elif type(defvalue) is bool or self.values[name][2] == [bool]:
+ if value == '0':
+ # given falsy string from command line option
+ return False
+ else:
+ return bool(value)
elif isinstance(defvalue, dict):
raise ValueError(__('cannot override dictionary config setting %r, '
'ignoring (use %r to set individual elements)') %
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index 1e4f1b10f..10ca58c5b 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -611,15 +611,13 @@ class StandardDomain(Domain):
sectname = self.get_numfig_title(node)
if not sectname:
continue
- elif node.traverse(addnodes.toctree):
- n = node.traverse(addnodes.toctree)[0]
- if n.get('caption'):
- sectname = n['caption']
+ else:
+ toctree = next(iter(node.traverse(addnodes.toctree)), None)
+ if toctree and toctree.get('caption'):
+ sectname = toctree.get('caption')
else:
+ # anonymous-only labels
continue
- else:
- # anonymous-only labels
- continue
self.labels[name] = docname, labelid, sectname
def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None:
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index ca2bdc48f..c659114d8 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -164,6 +164,7 @@ class PygmentsBridge:
if self.dest == 'html':
return hlsource
else:
+ # MEMO: this is done to escape Unicode chars with non-Unicode engines
return texescape.hlescape(hlsource, self.latex_engine)
def get_stylesheet(self):
diff --git a/sphinx/templates/gettext/message.pot_t b/sphinx/templates/gettext/message.pot_t
index 90df27175..6bec78729 100644
--- a/sphinx/templates/gettext/message.pot_t
+++ b/sphinx/templates/gettext/message.pot_t
@@ -10,8 +10,8 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: {{ ctime|e }}\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Last-Translator: {{ last_translator|e }}\n"
+"Language-Team: {{ language_team|e }}\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index 5d9adb5bb..3e67b5610 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -1078,7 +1078,7 @@
}
\def\sphinx@verbatim@nolig@list {\do \`}%
-% Some characters . , ; ? ! / are not pygmentized.
+% Some characters . , ; ? ! / are neither pygmentized nor "tex-escaped".
% This macro makes them "active" and they will insert potential linebreaks.
% Not compatible with math mode (cf \sphinxunactivateextras).
\newcommand*\sphinxbreaksbeforeactivelist {}% none
@@ -1369,7 +1369,6 @@
}
\newcommand*\sphinxbreaksviaactiveinparsedliteral{%
\sphinxbreaksviaactive % by default handles . , ; ? ! /
- \do\-% we need also the hyphen character (ends up "as is" in parsed-literal)
\lccode`\~`\~ %
% update \dospecials as it is used by \url
% but deactivation will already have been done hence this is unneeded:
@@ -1380,7 +1379,7 @@
\lccode`~32 \lowercase{\let~}\spx@verbatim@space\lccode`\~`\~
}
\newcommand*{\sphinxunactivateextras}{\let\do\@makeother
- \sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist\do\-}%
+ \sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist}%
% the \catcode13=5\relax (deactivate end of input lines) is left to callers
\newcommand*{\sphinxunactivateextrasandspace}{\catcode32=10\relax
\sphinxunactivateextras}%
@@ -1805,12 +1804,20 @@
% break also at \
\let\sphinx@textbackslash\textbackslash
\let\textbackslash\sphinxtextbackslash
- % do not typeset a continuation symbol on next line
+ % by default, no continuation symbol on next line but may be added
\let\sphinxafterbreak\sphinxafterbreakofinlineliteral
% do not overwrite the comma set-up
\let\verbatim@nolig@list\sphinx@literal@nolig@list
\fi
% fix a space-gobbling issue due to LaTeX's original \do@noligs
+% TODO: using \@noligs as patched by upquote.sty is now unneeded because
+% either ` and ' are escaped (non-unicode engines) or they don't build
+% ligatures (unicode engines). Thus remove this and unify handling of `, <, >,
+% ' and - with the characters . , ; ? ! / as handled via
+% \sphinxbreaksviaactive.
+% Hence \sphinx@do@noligs will be removed, or rather replaced with code
+% inserting discretionaries, as they allow a continuation symbol on start of
+% next line to achieve common design with code-blocks.
\let\do@noligs\sphinx@do@noligs
\@noligs\endlinechar\m@ne\everyeof{}% (<- in case inside \sphinxhref)
\expandafter\scantokens
@@ -1866,6 +1873,7 @@
% reduce hyperref "Token not allowed in a PDF string" warnings on PDF builds
\AtBeginDocument{\pdfstringdefDisableCommands{%
% all "protected" macros possibly ending up in section titles should be here
+% TODO: examine if \sphinxhref, \sphinxurl, \sphinnolinkurl should be handled
\let\sphinxstyleemphasis \@firstofone
\let\sphinxstyleliteralemphasis \@firstofone
\let\sphinxstylestrong \@firstofone
@@ -1879,8 +1887,20 @@
\let\sphinxemail \@firstofone
\let\sphinxcrossref \@firstofone
\let\sphinxtermref \@firstofone
+ \let\sphinxhyphen\sphinxhyphenforbookmarks
}}
+% Special characters
+%
+% This definition prevents en-dash and em-dash TeX ligatures.
+%
+% It inserts a potential breakpoint after the hyphen. This is to keep in sync
+% with behavior in code-blocks, parsed and inline literals. For a breakpoint
+% before the hyphen use \leavevmode\kern\z@- (within \makeatletter/\makeatother)
+\protected\def\sphinxhyphen#1{-\kern\z@}
+% The {} from texescape mark-up is kept, else -- gives en-dash in PDF bookmark
+\def\sphinxhyphenforbookmarks{-}
+
% For curly braces inside \index macro
\def\sphinxleftcurlybrace{\{}
\def\sphinxrightcurlybrace{\}}
diff --git a/sphinx/texinputs/sphinx.xdy b/sphinx/texinputs/sphinx.xdy
index 1c0794cd9..edca17874 100644
--- a/sphinx/texinputs/sphinx.xdy
+++ b/sphinx/texinputs/sphinx.xdy
@@ -112,12 +112,14 @@
(merge-rule "\_" "_" :string)
(merge-rule "{[}" "[" :string)
(merge-rule "{]}" "]" :string)
-(merge-rule "{}`" "`" :string)
(merge-rule "\textbackslash{}" "\" :string) ; " for Emacs syntax highlighting
(merge-rule "\textasciitilde{}" "~~" :string); the ~~ escape is needed here
+(merge-rule "\textasciicircum{}" "^" :string)
+(merge-rule "\sphinxhyphen{}" "-" :string)
+(merge-rule "\textquotesingle{}" "'" :string)
+(merge-rule "\textasciigrave{}" "`" :string)
(merge-rule "\textless{}" "<" :string)
(merge-rule "\textgreater{}" ">" :string)
-(merge-rule "\textasciicircum{}" "^" :string)
(merge-rule "\P{}" "¶" :string)
(merge-rule "\S{}" "§" :string)
(merge-rule "\texteuro{}" "€" :string)
diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py
index 52e43c2e2..53b4d056e 100644
--- a/sphinx/util/nodes.py
+++ b/sphinx/util/nodes.py
@@ -148,7 +148,7 @@ def apply_source_workaround(node: Element) -> None:
logger.debug('[i18n] PATCH: %r to have rawsource: %s',
get_full_module_name(node), repr_domxml(node))
# strip classifier from rawsource of term
- for classifier in reversed(node.parent.traverse(nodes.classifier)):
+ for classifier in reversed(list(node.parent.traverse(nodes.classifier))):
node.rawsource = re.sub(r'\s*:\s*%s' % re.escape(classifier.astext()),
'', node.rawsource)
diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py
index b7928ce37..734809d1f 100644
--- a/sphinx/util/texescape.py
+++ b/sphinx/util/texescape.py
@@ -29,12 +29,6 @@ tex_replacements = [
# map chars to avoid mis-interpretation in LaTeX
('[', r'{[}'),
(']', r'{]}'),
- # map chars to avoid TeX ligatures
- # 1. ' - and , not here for some legacy reason
- # 2. no effect with lualatex (done otherwise: #5790)
- ('`', r'{}`'),
- ('<', r'\textless{}'),
- ('>', r'\textgreater{}'),
# map special Unicode characters to TeX commands
('✓', r'\(\checkmark\)'),
('✔', r'\(\pmb{\checkmark}\)'),
@@ -49,6 +43,23 @@ tex_replacements = [
# OHM SIGN U+2126 is handled by LaTeX textcomp package
]
+# A map to avoid TeX ligatures or character replacements in PDF output
+# xelatex/lualatex/uplatex are handled differently (#5790, #6888)
+ascii_tex_replacements = [
+ # Note: the " renders curly in OT1 encoding but straight in T1, T2A, LY1...
+ # escaping it to \textquotedbl would break documents using OT1
+ # Sphinx does \shorthandoff{"} to avoid problems with some languages
+ # There is no \text... LaTeX escape for the hyphen character -
+ ('-', r'\sphinxhyphen{}'), # -- and --- are TeX ligatures
+ # ,, is a TeX ligature in T1 encoding, but escaping the comma adds
+ # complications (whether by {}, or a macro) and is not done
+ # the next two require textcomp package
+ ("'", r'\textquotesingle{}'), # else ' renders curly, and '' is a ligature
+ ('`', r'\textasciigrave{}'), # else \` and \`\` render curly
+ ('<', r'\textless{}'), # < is inv. exclam in OT1, << is a T1-ligature
+ ('>', r'\textgreater{}'), # > is inv. quest. mark in 0T1, >> a T1-ligature
+]
+
# A map Unicode characters to LaTeX representation
# (for LaTeX engines which don't support unicode)
unicode_tex_replacements = [
@@ -85,6 +96,11 @@ unicode_tex_replacements = [
('₉', r'\(\sb{\text{9}}\)'),
]
+# TODO: this should be called tex_idescape_map because its only use is in
+# sphinx.writers.latex.LaTeXTranslator.idescape()
+# %, {, }, \, #, and ~ are the only ones which must be replaced by _ character
+# It would be simpler to define it entirely here rather than in init().
+# Unicode replacements are superfluous, as idescape() uses backslashreplace
tex_replace_map = {} # type: Dict[int, str]
_tex_escape_map = {} # type: Dict[int, str]
@@ -130,8 +146,17 @@ def init() -> None:
_tex_escape_map_without_unicode[ord(a)] = b
tex_replace_map[ord(a)] = '_'
+ # no reason to do this for _tex_escape_map_without_unicode
+ for a, b in ascii_tex_replacements:
+ _tex_escape_map[ord(a)] = b
+
+ # but the hyphen has a specific PDF bookmark problem
+ # https://github.com/latex3/hyperref/issues/112
+ _tex_escape_map_without_unicode[ord('-')] = r'\sphinxhyphen{}'
+
for a, b in unicode_tex_replacements:
_tex_escape_map[ord(a)] = b
+ # This is actually unneeded:
tex_replace_map[ord(a)] = '_'
for a, b in tex_replacements:
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index 0cbaef527..eac446793 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -13,7 +13,7 @@ import os
import posixpath
import warnings
from typing import cast
-from typing import Iterable
+from typing import Iterable, Tuple
from docutils import nodes
from docutils.nodes import Element, Node, Text
@@ -271,10 +271,9 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
def depart_seealso(self, node: Element) -> None:
self.depart_admonition(node)
- def add_secnumber(self, node: Element) -> None:
+ def get_secnumber(self, node: Element) -> Tuple[int, ...]:
if node.get('secnumber'):
- self.body.append('.'.join(map(str, node['secnumber'])) +
- self.secnumber_suffix)
+ return node['secnumber']
elif isinstance(node.parent, nodes.section):
if self.builder.name == 'singlehtml':
docname = self.docnames[-1]
@@ -285,10 +284,17 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
anchorname = '#' + node.parent['ids'][0]
if anchorname not in self.builder.secnumbers:
anchorname = '' # try first heading which has no anchor
+
if self.builder.secnumbers.get(anchorname):
- numbers = self.builder.secnumbers[anchorname]
- self.body.append('.'.join(map(str, numbers)) +
- self.secnumber_suffix)
+ return self.builder.secnumbers[anchorname]
+
+ return None
+
+ def add_secnumber(self, node: Element) -> None:
+ secnumber = self.get_secnumber(node)
+ if secnumber:
+ self.body.append('<span class="section-number">%s</span>' %
+ ('.'.join(map(str, secnumber)) + self.secnumber_suffix))
def add_fignumber(self, node: Element) -> None:
def append_fignumber(figtype: str, figure_id: str) -> None:
diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py
index 3e67e4d1c..438f161f7 100644
--- a/sphinx/writers/html5.py
+++ b/sphinx/writers/html5.py
@@ -12,7 +12,7 @@ import os
import posixpath
import warnings
from typing import cast
-from typing import Iterable
+from typing import Iterable, Tuple
from docutils import nodes
from docutils.nodes import Element, Node, Text
@@ -242,11 +242,11 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
def depart_seealso(self, node: Element) -> None:
self.depart_admonition(node)
- def add_secnumber(self, node: Element) -> None:
+ def get_secnumber(self, node: Element) -> Tuple[int, ...]:
if node.get('secnumber'):
- self.body.append('.'.join(map(str, node['secnumber'])) +
- self.secnumber_suffix)
- elif isinstance(node.parent, nodes.section):
+ return node['secnumber']
+
+ if isinstance(node.parent, nodes.section):
if self.builder.name == 'singlehtml':
docname = self.docnames[-1]
anchorname = "%s/#%s" % (docname, node.parent['ids'][0])
@@ -256,10 +256,17 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
anchorname = '#' + node.parent['ids'][0]
if anchorname not in self.builder.secnumbers:
anchorname = '' # try first heading which has no anchor
+
if self.builder.secnumbers.get(anchorname):
- numbers = self.builder.secnumbers[anchorname]
- self.body.append('.'.join(map(str, numbers)) +
- self.secnumber_suffix)
+ return self.builder.secnumbers[anchorname]
+
+ return None
+
+ def add_secnumber(self, node: Element) -> None:
+ secnumber = self.get_secnumber(node)
+ if secnumber:
+ self.body.append('<span class="section-number">%s</span>' %
+ ('.'.join(map(str, secnumber)) + self.secnumber_suffix))
def add_fignumber(self, node: Element) -> None:
def append_fignumber(figtype: str, figure_id: str) -> None:
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 4f22851c9..e5573c182 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -473,7 +473,6 @@ class LaTeXTranslator(SphinxTranslator):
self.first_document = 1
self.this_is_the_title = 1
self.literal_whitespace = 0
- self.no_contractions = 0
self.in_parsed_literal = 0
self.compact_list = 0
self.first_param = 0
@@ -958,13 +957,11 @@ class LaTeXTranslator(SphinxTranslator):
def visit_desc_name(self, node: Element) -> None:
self.body.append(r'\sphinxbfcode{\sphinxupquote{')
- self.no_contractions += 1
self.literal_whitespace += 1
def depart_desc_name(self, node: Element) -> None:
self.body.append('}}')
self.literal_whitespace -= 1
- self.no_contractions -= 1
def visit_desc_parameterlist(self, node: Element) -> None:
# close name, open parameterlist
@@ -1806,11 +1803,9 @@ class LaTeXTranslator(SphinxTranslator):
def visit_literal_emphasis(self, node: Element) -> None:
self.body.append(r'\sphinxstyleliteralemphasis{\sphinxupquote{')
- self.no_contractions += 1
def depart_literal_emphasis(self, node: Element) -> None:
self.body.append('}}')
- self.no_contractions -= 1
def visit_strong(self, node: Element) -> None:
self.body.append(r'\sphinxstylestrong{')
@@ -1820,11 +1815,9 @@ class LaTeXTranslator(SphinxTranslator):
def visit_literal_strong(self, node: Element) -> None:
self.body.append(r'\sphinxstyleliteralstrong{\sphinxupquote{')
- self.no_contractions += 1
def depart_literal_strong(self, node: Element) -> None:
self.body.append('}}')
- self.no_contractions -= 1
def visit_abbreviation(self, node: Element) -> None:
abbr = node.astext()
@@ -1884,14 +1877,12 @@ class LaTeXTranslator(SphinxTranslator):
pass
def visit_literal(self, node: Element) -> None:
- self.no_contractions += 1
if self.in_title:
self.body.append(r'\sphinxstyleliteralintitle{\sphinxupquote{')
else:
self.body.append(r'\sphinxcode{\sphinxupquote{')
def depart_literal(self, node: Element) -> None:
- self.no_contractions -= 1
self.body.append('}}')
def visit_footnote_reference(self, node: Element) -> None:
@@ -2065,9 +2056,7 @@ class LaTeXTranslator(SphinxTranslator):
def visit_option_string(self, node: Element) -> None:
ostring = node.astext()
- self.no_contractions += 1
self.body.append(self.encode(ostring))
- self.no_contractions -= 1
raise nodes.SkipNode
def visit_description(self, node: Element) -> None:
@@ -2151,14 +2140,15 @@ class LaTeXTranslator(SphinxTranslator):
# Insert a blank before the newline, to avoid
# ! LaTeX Error: There's no line here to end.
text = text.replace('\n', '~\\\\\n').replace(' ', '~')
- if self.no_contractions:
- text = text.replace('--', '-{-}')
- text = text.replace("''", "'{'}")
return text
def encode_uri(self, text: str) -> str:
+ # TODO: it is probably wrong that this uses texescape.escape()
+ # this must be checked against hyperref package exact dealings
+ # mainly, %, #, {, } and \ need escaping via a \ escape
# in \href, the tilde is allowed and must be represented literally
- return self.encode(text).replace('\\textasciitilde{}', '~')
+ return self.encode(text).replace('\\textasciitilde{}', '~').\
+ replace('\\sphinxhyphen{}', '-')
def visit_Text(self, node: Text) -> None:
text = self.encode(node.astext())
@@ -2247,6 +2237,12 @@ class LaTeXTranslator(SphinxTranslator):
fnotes[num] = [newnode, False]
return fnotes
+ @property
+ def no_contractions(self) -> int:
+ warnings.warn('LaTeXTranslator.no_contractions is deprecated.',
+ RemovedInSphinx40Warning, stacklevel=2)
+ return 0
+
def babel_defmacro(self, name: str, definition: str) -> str:
warnings.warn('babel_defmacro() is deprecated.',
RemovedInSphinx40Warning)
diff --git a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex
index 3d9e5cae1..5d524c257 100644
--- a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex
+++ b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex
@@ -2,10 +2,10 @@
table having …
\begin{itemize}
\item {}
-consecutive multirow at top of row (1-1 and 1-2)
+consecutive multirow at top of row (1\sphinxhyphen{}1 and 1\sphinxhyphen{}2)
\item {}
-consecutive multirow at end of row (1-4 and 1-5)
+consecutive multirow at end of row (1\sphinxhyphen{}4 and 1\sphinxhyphen{}5)
\end{itemize}
@@ -16,40 +16,40 @@ consecutive multirow at end of row (1-4 and 1-5)
\hline
\sphinxmultirow{3}{1}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
-cell1-1
+cell1\sphinxhyphen{}1
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxmultirow{3}{2}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
-cell1-2
+cell1\sphinxhyphen{}2
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&
-cell1-3
+cell1\sphinxhyphen{}3
&\sphinxmultirow{3}{4}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
-cell1-4
+cell1\sphinxhyphen{}4
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxmultirow{2}{5}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
-cell1-5
+cell1\sphinxhyphen{}5
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
\\
\cline{3-3}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxmultirow{2}{6}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
-cell2-3
+cell2\sphinxhyphen{}3
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxtablestrut{4}&\sphinxtablestrut{5}\\
\cline{5-5}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxtablestrut{6}&\sphinxtablestrut{4}&
-cell3-5
+cell3\sphinxhyphen{}5
\\
\hline
\end{tabulary}
diff --git a/tests/roots/test-latex-table/expects/gridtable.tex b/tests/roots/test-latex-table/expects/gridtable.tex
index cb74bea77..28b0b086b 100644
--- a/tests/roots/test-latex-table/expects/gridtable.tex
+++ b/tests/roots/test-latex-table/expects/gridtable.tex
@@ -12,40 +12,40 @@ header2
header3
\\
\hline
-cell1-1
+cell1\sphinxhyphen{}1
&\sphinxmultirow{2}{5}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{3}}
-cell1-2
+cell1\sphinxhyphen{}2
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&
-cell1-3
+cell1\sphinxhyphen{}3
\\
\cline{1-1}\cline{3-3}\sphinxmultirow{2}{7}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{3}}
-cell2-1
+cell2\sphinxhyphen{}1
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxtablestrut{5}&
-cell2-3
+cell2\sphinxhyphen{}3
\\
\cline{2-3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}%
\sphinxmultirow{2}{9}{%
\begin{varwidth}[t]{\sphinxcolwidth{2}{3}}
-cell3-2
+cell3\sphinxhyphen{}2
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
\sphinxstopmulticolumn
\\
\cline{1-1}
-cell4-1
+cell4\sphinxhyphen{}1
&\multicolumn{2}{l|}{\sphinxtablestrut{9}}\\
\hline\sphinxstartmulticolumn{3}%
\begin{varwidth}[t]{\sphinxcolwidth{3}{3}}
-cell5-1
+cell5\sphinxhyphen{}1
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
\sphinxstopmulticolumn
diff --git a/tests/roots/test-latex-table/expects/longtable.tex b/tests/roots/test-latex-table/expects/longtable.tex
index 50124ad8a..9febfcef5 100644
--- a/tests/roots/test-latex-table/expects/longtable.tex
+++ b/tests/roots/test-latex-table/expects/longtable.tex
@@ -27,19 +27,19 @@ header2
\endlastfoot
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_align.tex b/tests/roots/test-latex-table/expects/longtable_having_align.tex
index 55ea7ea1b..1969e19d2 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_align.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex
@@ -27,19 +27,19 @@ header2
\endlastfoot
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_caption.tex b/tests/roots/test-latex-table/expects/longtable_having_caption.tex
index d28836ad0..f0041e9ec 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex
@@ -29,19 +29,19 @@ header2
\endlastfoot
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex
index e38d8ae5f..050527b69 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex
@@ -35,17 +35,17 @@ item2
\end{itemize}
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex
index 28f9a09e5..68e74c5f4 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex
@@ -32,23 +32,23 @@ header3
\endlastfoot
\sphinxstyletheadfamily \begin{itemize}
\item {}
-instub1-1a
+instub1\sphinxhyphen{}1a
\item {}
-instub1-1b
+instub1\sphinxhyphen{}1b
\end{itemize}
&\sphinxstyletheadfamily
-instub1-2
+instub1\sphinxhyphen{}2
&
-notinstub1-3
+notinstub1\sphinxhyphen{}3
\\
\hline\sphinxstyletheadfamily
-cell2-1
+cell2\sphinxhyphen{}1
&\sphinxstyletheadfamily
-cell2-2
+cell2\sphinxhyphen{}2
&
-cell2-3
+cell2\sphinxhyphen{}3
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
index c9e018e66..c7213b906 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
@@ -31,17 +31,17 @@ header2
\PYG{n}{hello} \PYG{n}{world}
\end{sphinxVerbatimintable}
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths.tex b/tests/roots/test-latex-table/expects/longtable_having_widths.tex
index 9c449cc48..884fd9f8a 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_widths.tex
@@ -27,19 +27,19 @@ header2
\endlastfoot
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex
index 8eee72125..17c5ec4cc 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex
@@ -35,17 +35,17 @@ item2
\end{itemize}
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex
index d4633886d..2fbbbc4ef 100644
--- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex
+++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex
@@ -27,19 +27,19 @@ header2
\endlastfoot
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/simple_table.tex b/tests/roots/test-latex-table/expects/simple_table.tex
index 9ad911588..8044a6cc4 100644
--- a/tests/roots/test-latex-table/expects/simple_table.tex
+++ b/tests/roots/test-latex-table/expects/simple_table.tex
@@ -10,19 +10,19 @@ header1
header2
\\
\hline
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}
diff --git a/tests/roots/test-latex-table/expects/table_having_caption.tex b/tests/roots/test-latex-table/expects/table_having_caption.tex
index fe0055233..d4423a05d 100644
--- a/tests/roots/test-latex-table/expects/table_having_caption.tex
+++ b/tests/roots/test-latex-table/expects/table_having_caption.tex
@@ -14,19 +14,19 @@ header1
header2
\\
\hline
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}
diff --git a/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex
index 561a98010..7a9b0f293 100644
--- a/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex
@@ -18,17 +18,17 @@ item2
\end{itemize}
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}
diff --git a/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex
index 6904c43c3..700fc4663 100644
--- a/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex
@@ -13,23 +13,23 @@ header3
\\
\hline\sphinxstyletheadfamily \begin{itemize}
\item {}
-instub1-1a
+instub1\sphinxhyphen{}1a
\item {}
-instub1-1b
+instub1\sphinxhyphen{}1b
\end{itemize}
&\sphinxstyletheadfamily
-instub1-2
+instub1\sphinxhyphen{}2
&
-notinstub1-3
+notinstub1\sphinxhyphen{}3
\\
\hline\sphinxstyletheadfamily
-cell2-1
+cell2\sphinxhyphen{}1
&\sphinxstyletheadfamily
-cell2-2
+cell2\sphinxhyphen{}2
&
-cell2-3
+cell2\sphinxhyphen{}3
\\
\hline
\end{tabular}
diff --git a/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex b/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex
index 20d949493..6d3e81021 100644
--- a/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex
+++ b/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex
@@ -8,11 +8,11 @@
header1
\\
\hline
-cell1-1-par1
+cell1\sphinxhyphen{}1\sphinxhyphen{}par1
-cell1-1-par2
+cell1\sphinxhyphen{}1\sphinxhyphen{}par2
-cell1-1-par3
+cell1\sphinxhyphen{}1\sphinxhyphen{}par3
\\
\hline
\end{tabulary}
diff --git a/tests/roots/test-latex-table/expects/table_having_verbatim.tex b/tests/roots/test-latex-table/expects/table_having_verbatim.tex
index 2e2b1dc9a..f66bb8001 100644
--- a/tests/roots/test-latex-table/expects/table_having_verbatim.tex
+++ b/tests/roots/test-latex-table/expects/table_having_verbatim.tex
@@ -14,17 +14,17 @@ header2
\PYG{n}{hello} \PYG{n}{world}
\end{sphinxVerbatimintable}
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}
diff --git a/tests/roots/test-latex-table/expects/table_having_widths.tex b/tests/roots/test-latex-table/expects/table_having_widths.tex
index b4fcea04e..094596bec 100644
--- a/tests/roots/test-latex-table/expects/table_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/table_having_widths.tex
@@ -11,19 +11,19 @@ header1
header2
\\
\hline
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}
diff --git a/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex
index d3e2e8144..a636b022e 100644
--- a/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex
@@ -18,17 +18,17 @@ item2
\end{itemize}
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}
diff --git a/tests/roots/test-latex-table/expects/tabular_having_widths.tex b/tests/roots/test-latex-table/expects/tabular_having_widths.tex
index ae67fe924..5ee1542d4 100644
--- a/tests/roots/test-latex-table/expects/tabular_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/tabular_having_widths.tex
@@ -10,19 +10,19 @@ header1
header2
\\
\hline
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}
diff --git a/tests/roots/test-latex-table/expects/tabularcolumn.tex b/tests/roots/test-latex-table/expects/tabularcolumn.tex
index 78d31058f..02e9af440 100644
--- a/tests/roots/test-latex-table/expects/tabularcolumn.tex
+++ b/tests/roots/test-latex-table/expects/tabularcolumn.tex
@@ -10,19 +10,19 @@ header1
header2
\\
\hline
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}
diff --git a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex
index 53f1f2aaa..06d347fa3 100644
--- a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex
@@ -10,19 +10,19 @@ header1
header2
\\
\hline
-cell1-1
+cell1\sphinxhyphen{}1
&
-cell1-2
+cell1\sphinxhyphen{}2
\\
\hline
-cell2-1
+cell2\sphinxhyphen{}1
&
-cell2-2
+cell2\sphinxhyphen{}2
\\
\hline
-cell3-1
+cell3\sphinxhyphen{}1
&
-cell3-2
+cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index 3255bb71e..66164dd1c 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -97,14 +97,11 @@ def check_xpath(etree, fname, path, check, be_found=True):
else:
def get_text(node):
if node.text is not None:
+ # the node has only one text
return node.text
else:
- # Since pygments-2.1.1, empty <span> tag is inserted at top of
- # highlighting block
- if len(node) == 1 and node[0].tag == 'span' and node[0].text is None:
- if node[0].tail is not None:
- return node[0].tail
- return ''
+ # the node has tags and text; gather texts just under the node
+ return ''.join(n.tail or '' for n in node)
rex = re.compile(check)
if be_found:
@@ -491,28 +488,40 @@ def test_html_translator(app):
(".//li[@class='toctree-l3']/a", '2.2.1. Bar B1', False),
],
'foo.html': [
- (".//h1", '1. Foo', True),
- (".//h2", '1.1. Foo A', True),
- (".//h3", '1.1.1. Foo A1', True),
- (".//h2", '1.2. Foo B', True),
- (".//h3", '1.2.1. Foo B1', True),
+ (".//h1", 'Foo', True),
+ (".//h2", 'Foo A', True),
+ (".//h3", 'Foo A1', True),
+ (".//h2", 'Foo B', True),
+ (".//h3", 'Foo B1', True),
+
+ (".//h1//span[@class='section-number']", '1. ', True),
+ (".//h2//span[@class='section-number']", '1.1. ', True),
+ (".//h3//span[@class='section-number']", '1.1.1. ', True),
+ (".//h2//span[@class='section-number']", '1.2. ', True),
+ (".//h3//span[@class='section-number']", '1.2.1. ', True),
+
(".//div[@class='sphinxsidebarwrapper']//li/a", '1.1. Foo A', True),
(".//div[@class='sphinxsidebarwrapper']//li/a", '1.1.1. Foo A1', True),
(".//div[@class='sphinxsidebarwrapper']//li/a", '1.2. Foo B', True),
(".//div[@class='sphinxsidebarwrapper']//li/a", '1.2.1. Foo B1', True),
],
'bar.html': [
- (".//h1", '2. Bar', True),
- (".//h2", '2.1. Bar A', True),
- (".//h2", '2.2. Bar B', True),
- (".//h3", '2.2.1. Bar B1', True),
+ (".//h1", 'Bar', True),
+ (".//h2", 'Bar A', True),
+ (".//h2", 'Bar B', True),
+ (".//h3", 'Bar B1', True),
+ (".//h1//span[@class='section-number']", '2. ', True),
+ (".//h2//span[@class='section-number']", '2.1. ', True),
+ (".//h2//span[@class='section-number']", '2.2. ', True),
+ (".//h3//span[@class='section-number']", '2.2.1. ', True),
(".//div[@class='sphinxsidebarwrapper']//li/a", '2. Bar', True),
(".//div[@class='sphinxsidebarwrapper']//li/a", '2.1. Bar A', True),
(".//div[@class='sphinxsidebarwrapper']//li/a", '2.2. Bar B', True),
(".//div[@class='sphinxsidebarwrapper']//li/a", '2.2.1. Bar B1', False),
],
'baz.html': [
- (".//h1", '2.1.1. Baz A', True),
+ (".//h1", 'Baz A', True),
+ (".//h1//span[@class='section-number']", '2.1.1. ', True),
],
}))
@pytest.mark.skipif(docutils.__version_info__ < (0, 13),
@@ -536,20 +545,30 @@ def test_tocdepth(app, cached_etree_parse, fname, expect):
(".//h1", 'test-tocdepth', True),
# foo.rst
- (".//h2", '1. Foo', True),
- (".//h3", '1.1. Foo A', True),
- (".//h4", '1.1.1. Foo A1', True),
- (".//h3", '1.2. Foo B', True),
- (".//h4", '1.2.1. Foo B1', True),
+ (".//h2", 'Foo', True),
+ (".//h3", 'Foo A', True),
+ (".//h4", 'Foo A1', True),
+ (".//h3", 'Foo B', True),
+ (".//h4", 'Foo B1', True),
+ (".//h2//span[@class='section-number']", '1. ', True),
+ (".//h3//span[@class='section-number']", '1.1. ', True),
+ (".//h4//span[@class='section-number']", '1.1.1. ', True),
+ (".//h3//span[@class='section-number']", '1.2. ', True),
+ (".//h4//span[@class='section-number']", '1.2.1. ', True),
# bar.rst
- (".//h2", '2. Bar', True),
- (".//h3", '2.1. Bar A', True),
- (".//h3", '2.2. Bar B', True),
- (".//h4", '2.2.1. Bar B1', True),
+ (".//h2", 'Bar', True),
+ (".//h3", 'Bar A', True),
+ (".//h3", 'Bar B', True),
+ (".//h4", 'Bar B1', True),
+ (".//h2//span[@class='section-number']", '2. ', True),
+ (".//h3//span[@class='section-number']", '2.1. ', True),
+ (".//h3//span[@class='section-number']", '2.2. ', True),
+ (".//h4//span[@class='section-number']", '2.2.1. ', True),
# baz.rst
- (".//h4", '2.1.1. Baz A', True),
+ (".//h4", 'Baz A', True),
+ (".//h4//span[@class='section-number']", '2.1.1. ', True),
],
}))
@pytest.mark.skipif(docutils.__version_info__ < (0, 13),
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index 8c023b8e4..a64805be3 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -193,7 +193,7 @@ def test_latex_title_after_admonitions(app, status, warning):
print(result)
print(status.getvalue())
print(warning.getvalue())
- assert '\\title{test-latex-title}' in result
+ assert '\\title{test\\sphinxhyphen{}latex\\sphinxhyphen{}title}' in result
@pytest.mark.sphinx('latex', testroot='basic',
@@ -227,7 +227,7 @@ def test_numref(app, status, warning):
assert ('\\hyperref[\\detokenize{index:code-1}]'
'{Listing \\ref{\\detokenize{index:code-1}}}') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
- '{Code-\\ref{\\detokenize{baz:code22}}}') in result
+ '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
'{Section \\ref{\\detokenize{foo:foo}}}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
@@ -273,13 +273,13 @@ def test_numref_with_prefix1(app, status, warning):
assert ('\\hyperref[\\detokenize{baz:table22}]'
'{Table:\\ref{\\detokenize{baz:table22}}}') in result
assert ('\\hyperref[\\detokenize{index:code-1}]'
- '{Code-\\ref{\\detokenize{index:code-1}}}') in result
+ '{Code\\sphinxhyphen{}\\ref{\\detokenize{index:code-1}}}') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
- '{Code-\\ref{\\detokenize{baz:code22}}}') in result
+ '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
- '{SECTION-\\ref{\\detokenize{foo:foo}}}') in result
+ '{SECTION\\sphinxhyphen{}\\ref{\\detokenize{foo:foo}}}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
- '{SECTION-\\ref{\\detokenize{bar:bar-a}}}') in result
+ '{SECTION\\sphinxhyphen{}\\ref{\\detokenize{bar:bar-a}}}') in result
assert ('\\hyperref[\\detokenize{index:fig1}]{Fig.\\ref{\\detokenize{index:fig1}} '
'\\nameref{\\detokenize{index:fig1}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]{Sect.\\ref{\\detokenize{foo:foo}} '
@@ -314,10 +314,10 @@ def test_numref_with_prefix2(app, status, warning):
'{Tab\\_\\ref{\\detokenize{index:table-1}}:}') in result
assert ('\\hyperref[\\detokenize{baz:table22}]'
'{Table:\\ref{\\detokenize{baz:table22}}}') in result
- assert ('\\hyperref[\\detokenize{index:code-1}]{Code-\\ref{\\detokenize{index:code-1}} '
+ assert ('\\hyperref[\\detokenize{index:code-1}]{Code\\sphinxhyphen{}\\ref{\\detokenize{index:code-1}} '
'| }') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
- '{Code-\\ref{\\detokenize{baz:code22}}}') in result
+ '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
'{SECTION\\_\\ref{\\detokenize{foo:foo}}\\_}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
@@ -357,7 +357,7 @@ def test_numref_with_language_ja(app, status, warning):
assert ('\\hyperref[\\detokenize{index:code-1}]'
'{\u30ea\u30b9\u30c8 \\ref{\\detokenize{index:code-1}}}') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
- '{Code-\\ref{\\detokenize{baz:code22}}}') in result
+ '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
'{\\ref{\\detokenize{foo:foo}} \u7ae0}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
@@ -692,7 +692,7 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'Second footnote in caption of longtable\n') in result
- assert ('This is a reference to the code-block in the footnote:\n'
+ assert ('This is a reference to the code\\sphinxhyphen{}block in the footnote:\n'
'{\\hyperref[\\detokenize{index:codeblockinfootnote}]'
'{\\sphinxcrossref{\\DUrole{std,std-ref}{I am in a footnote}}}}') in result
assert ('&\nThis is one more footnote with some code in it %\n'
@@ -727,24 +727,24 @@ def test_latex_show_urls_is_inline(app, status, warning):
'First\n%\n\\end{footnote}') in result
assert ('Second footnote: %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'Second\n%\n\\end{footnote}') in result
- assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx-doc.org/)' in result
+ assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx\\sphinxhyphen{}doc.org/)' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} '
- '(http://sphinx-doc.org/\\textasciitilde{}test/)') in result
+ '(http://sphinx\\sphinxhyphen{}doc.org/\\textasciitilde{}test/)') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term} '
- '(http://sphinx-doc.org/)}] \\leavevmode\nDescription' in result)
+ '(http://sphinx\\sphinxhyphen{}doc.org/)}] \\leavevmode\nDescription' in result)
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces \n'
'Description') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} '
- '(http://sphinx-doc.org/)}] \\leavevmode\nDescription') in result
+ '(http://sphinx\\sphinxhyphen{}doc.org/)}] \\leavevmode\nDescription') in result
assert '\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result
assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}'
- '{sphinx-dev@googlegroups.com}') in result
+ '{sphinx\\sphinxhyphen{}dev@googlegroups.com}') in result
@pytest.mark.sphinx(
@@ -798,7 +798,7 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'\\end{footnotetext}\\ignorespaces \nDescription') in result
assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}'
- '{sphinx-dev@googlegroups.com}\n') in result
+ '{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result
@pytest.mark.sphinx(
@@ -841,7 +841,7 @@ def test_latex_show_urls_is_no(app, status, warning):
'\\leavevmode\nDescription') in result
assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}'
- '{sphinx-dev@googlegroups.com}\n') in result
+ '{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result
@pytest.mark.sphinx(
@@ -1416,7 +1416,7 @@ def test_default_latex_documents():
config.init_values()
config.add('latex_engine', None, True, None)
expected = [('index', 'stasi.tex', 'STASI™ Documentation',
- r"Wolfgang Schäuble \& G'Beckstein.\@{}", 'manual')]
+ r"Wolfgang Schäuble \& G\textquotesingle{}Beckstein.\@{}", 'manual')]
assert default_latex_documents(config) == expected
diff --git a/tests/test_config.py b/tests/test_config.py
index a5da0d6ec..1d3a49e95 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -119,6 +119,20 @@ def test_overrides():
assert config.value8 == ['abc', 'def', 'ghi']
+def test_overrides_boolean():
+ config = Config({}, {'value1': '1',
+ 'value2': '0',
+ 'value3': '0'})
+ config.add('value1', None, 'env', [bool])
+ config.add('value2', None, 'env', [bool])
+ config.add('value3', True, 'env', ())
+ config.init_values()
+
+ assert config.value1 is True
+ assert config.value2 is False
+ assert config.value3 is False
+
+
@mock.patch("sphinx.config.logger")
def test_errors_warnings(logger, tempdir):
# test the error for syntax errors in the config file
diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py
index ecf5423c2..5d93449f1 100644
--- a/tests/test_directive_code.py
+++ b/tests/test_directive_code.py
@@ -573,7 +573,7 @@ def test_literalinclude_pydecorators(app, status, warning):
def test_code_block_highlighted(app, status, warning):
app.builder.build(['highlight'])
doctree = app.env.get_doctree('highlight')
- codeblocks = doctree.traverse(nodes.literal_block)
+ codeblocks = list(doctree.traverse(nodes.literal_block))
assert codeblocks[0]['language'] == 'default'
assert codeblocks[1]['language'] == 'python2'
diff --git a/tests/test_markup.py b/tests/test_markup.py
index 94d1af951..8e00764fc 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -213,7 +213,7 @@ def get_verifier(verify, verify_re):
':menuselection:`&Foo -&&- &Bar`',
('<p><span class="menuselection"><span class="accelerator">F</span>oo '
'-&amp;- <span class="accelerator">B</span>ar</span></p>'),
- r'\sphinxmenuselection{\sphinxaccelerator{F}oo -\&- \sphinxaccelerator{B}ar}',
+ r'\sphinxmenuselection{\sphinxaccelerator{F}oo \sphinxhyphen{}\&\sphinxhyphen{} \sphinxaccelerator{B}ar}',
),
(
# interpolation of ampersands in guilabel
@@ -221,7 +221,7 @@ def get_verifier(verify, verify_re):
':guilabel:`&Foo -&&- &Bar`',
('<p><span class="guilabel"><span class="accelerator">F</span>oo '
'-&amp;- <span class="accelerator">B</span>ar</span></p>'),
- r'\sphinxguilabel{\sphinxaccelerator{F}oo -\&- \sphinxaccelerator{B}ar}',
+ r'\sphinxguilabel{\sphinxaccelerator{F}oo \sphinxhyphen{}\&\sphinxhyphen{} \sphinxaccelerator{B}ar}',
),
(
# no ampersands in guilabel
@@ -236,7 +236,7 @@ def get_verifier(verify, verify_re):
':option:`--with-option`',
('<p><code( class="xref std std-option docutils literal notranslate")?>'
'<span class="pre">--with-option</span></code></p>$'),
- r'\\sphinxcode{\\sphinxupquote{-{-}with-option}}$',
+ r'\\sphinxcode{\\sphinxupquote{\\sphinxhyphen{}\\sphinxhyphen{}with\\sphinxhyphen{}option}}$',
),
(
# verify smarty-pants quotes
diff --git a/tox.ini b/tox.ini
index c4ffe33cb..922432d67 100644
--- a/tox.ini
+++ b/tox.ini
@@ -10,10 +10,12 @@ description =
py{35,36,37,38}: Run unit tests against {envname}.
du{12,13,14}: Run unit tests with the given version of docutils.
deps =
+ coverage < 5.0 # refs: https://github.com/sphinx-doc/sphinx/pull/6924
du12: docutils==0.12
du13: docutils==0.13.1
du14: docutils==0.14
du15: docutils==0.15
+ du16: docutils==0.16b0.dev0
extras =
test
setenv =