summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES13
-rw-r--r--EXAMPLES1
-rw-r--r--doc/config.rst32
-rw-r--r--doc/ext/math.rst2
-rw-r--r--doc/latex.rst20
-rw-r--r--doc/markup/code.rst6
-rw-r--r--doc/markup/inline.rst18
-rw-r--r--sphinx/apidoc.py7
-rw-r--r--sphinx/application.py4
-rw-r--r--sphinx/builders/__init__.py6
-rw-r--r--sphinx/builders/html.py2
-rw-r--r--sphinx/builders/htmlhelp.py2
-rw-r--r--sphinx/builders/qthelp.py4
-rw-r--r--sphinx/config.py2
-rw-r--r--sphinx/domains/cpp.py2
-rw-r--r--sphinx/environment/collectors/toctree.py2
-rw-r--r--sphinx/ext/napoleon/docstring.py22
-rw-r--r--sphinx/pycode/nodes.py2
-rw-r--r--sphinx/quickstart.py25
-rw-r--r--sphinx/setup_command.py10
-rw-r--r--sphinx/texinputs/sphinx.sty76
-rw-r--r--sphinx/transforms/__init__.py4
-rw-r--r--sphinx/transforms/compact_bullet_list.py6
-rw-r--r--sphinx/util/__init__.py8
-rw-r--r--sphinx/util/logging.py31
-rw-r--r--sphinx/writers/latex.py49
-rw-r--r--tests/roots/test-builder-gettext-dont-rebuild-mo/bom.po (renamed from tests/roots/test-root/bom.po)0
-rw-r--r--tests/roots/test-builder-gettext-dont-rebuild-mo/bom.rst5
-rw-r--r--tests/roots/test-builder-gettext-dont-rebuild-mo/conf.py7
-rw-r--r--tests/roots/test-builder-gettext-dont-rebuild-mo/index.rst6
-rw-r--r--tests/roots/test-directive-code/emphasize.rst7
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_verbatim.tex1
-rw-r--r--tests/roots/test-latex-table/expects/table_having_verbatim.tex1
-rw-r--r--tests/roots/test-root/_static/README1
-rw-r--r--tests/roots/test-root/_static/excluded.css1
-rw-r--r--tests/roots/test-root/_static/subdir/foo.css1
-rw-r--r--tests/roots/test-root/conf.py5
-rw-r--r--tests/roots/test-root/robots.txt2
-rw-r--r--tests/roots/test-root/subdir.po9
-rw-r--r--tests/roots/test-root/templated.css_t2
-rw-r--r--tests/roots/test-theming/test_theme/staticfiles/layout.html (renamed from tests/roots/test-root/testtheme/layout.html)0
-rw-r--r--tests/roots/test-theming/test_theme/staticfiles/static/staticimg.png (renamed from tests/roots/test-root/testtheme/static/staticimg.png)bin120 -> 120 bytes
-rw-r--r--tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html_t (renamed from tests/roots/test-root/testtheme/static/statictmpl.html_t)0
-rw-r--r--tests/roots/test-theming/test_theme/staticfiles/theme.conf (renamed from tests/roots/test-root/testtheme/theme.conf)0
-rw-r--r--tests/roots/test-theming/ziptheme.zip (renamed from tests/roots/test-root/ziptheme.zip)bin1039 -> 1039 bytes
-rw-r--r--tests/test_build.py8
-rw-r--r--tests/test_build_html.py57
-rw-r--r--tests/test_build_html5.py4
-rw-r--r--tests/test_build_latex.py50
-rw-r--r--tests/test_directive_code.py8
-rw-r--r--tests/test_intl.py4
-rw-r--r--tests/test_markup.py3
-rw-r--r--tests/test_theming.py23
53 files changed, 349 insertions, 212 deletions
diff --git a/CHANGES b/CHANGES
index 28df20245..6d70f8e5f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -14,6 +14,9 @@ Features added
--------------
* #4181: autodoc: Sort dictionary keys when possible
+* ``VerbatimHighlightColor`` is a new
+ :ref:`LaTeX 'sphinxsetup' <latexsphinxsetup>` key (refs: #4285)
+* Easier customizability of LaTeX macros involved in rendering of code-blocks
Bugs fixed
----------
@@ -23,6 +26,16 @@ Bugs fixed
* #4221: napoleon depends on autodoc, but users need to load it manually
* #2298: automodule fails to document a class attribute
* #4099: C++: properly link class reference to class from inside constructor
+* #4267: PDF build broken by Unicode U+2116 NUMERO SIGN character
+* #4249: PDF output: Pygments error highlighting increases line spacing in
+ code blocks
+* #1238: Support ``:emphasize-lines:`` in PDF output
+* #4279: Sphinx crashes with pickling error when run with multiple processes and
+ remote image
+* #1421: Respect the quiet flag in sphinx-quickstart
+* #4281: Race conditions when creating output directory
+* #4315: For PDF 'howto' documents, ``latex_toplevel_sectioning='part'`` generates
+ ``\chapter`` commands
* #4214: Two todolist directives break sphinx-1.6.5
Testing
diff --git a/EXAMPLES b/EXAMPLES
index fa91b206e..9d3b24311 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -111,6 +111,7 @@ Documentation using the sphinxdoc theme
Documentation using another builtin theme
-----------------------------------------
+* Arcade: http://arcade.academy/ (sphinx_rtd_theme)
* ASE: https://wiki.fysik.dtu.dk/ase/ (sphinx_rtd_theme)
* C/C++ Development with Eclipse: http://eclipsebook.in/ (agogo)
* ESWP3 (http://eswp3.org) (sphinx_rtd_theme)
diff --git a/doc/config.rst b/doc/config.rst
index 7a6d20147..1f222451d 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -311,8 +311,8 @@ General configuration
.. confval:: numfig
If true, figures, tables and code-blocks are automatically numbered if they
- have a caption. At same time, the `numref` role is enabled. For now, it
- works only with the HTML builder and LaTeX builder. Default is ``False``.
+ have a caption. The :rst:role:`numref` role is enabled.
+ Obeyed so far only by HTML and LaTeX builders. Default is ``False``.
.. note::
@@ -335,10 +335,21 @@ General configuration
.. confval:: numfig_secnum_depth
- The scope of figure numbers, that is, the numfig feature numbers figures
- in which scope. ``0`` means "whole document". ``1`` means "in a section".
- Sphinx numbers like x.1, x.2, x.3... ``2`` means "in a subsection". Sphinx
- numbers like x.x.1, x.x.2, x.x.3..., and so on. Default is ``1``.
+ - if set to ``0``, figures, tables and code-blocks are continuously numbered
+ starting at ``1``.
+ - if ``1`` (default) numbers will be ``x.1``, ``x.2``, ... with ``x``
+ the section number (top level sectioning; no ``x.`` if no section).
+ This naturally applies only if section numbering has been activated via
+ the ``:numbered:`` option of the :rst:dir:`toctree` directive.
+ - ``2`` means that numbers will be ``x.y.1``, ``x.y.2``, ... if located in
+ a sub-section (but still ``x.1``, ``x.2``, ... if located directly under a
+ section and ``1``, ``2``, ... if not in any top level section.)
+ - etc...
+
+ .. note::
+
+ The LaTeX builder currently ignores this configuration setting. It will
+ obey it at Sphinx 1.7.
.. versionadded:: 1.3
@@ -1606,10 +1617,15 @@ These options influence LaTeX output. See further :doc:`latex`.
.. confval:: latex_toplevel_sectioning
This value determines the topmost sectioning unit. It should be chosen from
- ``part``, ``chapter`` or ``section``. The default is ``None``; the topmost
- sectioning unit is switched by documentclass. ``section`` is used if
+ ``'part'``, ``'chapter'`` or ``'section'``. The default is ``None``;
+ the topmost
+ sectioning unit is switched by documentclass: ``section`` is used if
documentclass will be ``howto``, otherwise ``chapter`` will be used.
+ Note that if LaTeX uses ``\part`` command, then the numbering of sectioning
+ units one level deep gets off-sync with HTML numbering, because LaTeX
+ numbers continuously ``\chapter`` (or ``\section`` for ``howto``.)
+
.. versionadded:: 1.4
.. confval:: latex_appendices
diff --git a/doc/ext/math.rst b/doc/ext/math.rst
index 3d25d09ba..ca53f3a8e 100644
--- a/doc/ext/math.rst
+++ b/doc/ext/math.rst
@@ -78,7 +78,7 @@ or use Python raw strings (``r"raw"``).
Normally, equations are not numbered. If you want your equation to get a
number, use the ``label`` option. When given, it selects an internal label
for the equation, by which it can be cross-referenced, and causes an equation
- number to be issued. See :rst:role:`eqref` for an example. The numbering
+ number to be issued. See :rst:role:`eq` for an example. The numbering
style depends on the output format.
There is also an option ``nowrap`` that prevents any wrapping of the given
diff --git a/doc/latex.rst b/doc/latex.rst
index 0cd91fa97..2197efcd6 100644
--- a/doc/latex.rst
+++ b/doc/latex.rst
@@ -256,6 +256,16 @@ The available styling options
``VerbatimBorderColor``
default ``{rgb}{0,0,0}``. The frame color, defaults to black.
+``VerbatimHighlightColor``
+ default ``{rgb}{0.878,1,1}``. The color for highlighted lines.
+
+ .. versionadded:: 1.6.6
+
+.. note::
+
+ Starting with this colour key, and for all others coming next, the actual
+ names declared to "color" or "xcolor" are prefixed with "sphinx".
+
``verbatimsep``
default ``\fboxsep``. The separation between code lines and the frame.
@@ -277,11 +287,6 @@ The available styling options
default ``{rgb}{0,0,0}`` (black). The colour for the two horizontal rules
used by Sphinx in LaTeX for styling a :dudir:`note` type admonition.
-.. note::
-
- The actual colour names declared to "color" or "xcolor" are prefixed with
- "sphinx".
-
``noteborder``, ``hintborder``, ``importantborder``, ``tipborder``
default ``0.5pt``. The width of the two horizontal rules.
@@ -443,6 +448,11 @@ Environments
.. versionadded:: 1.5
options ``verbatimwithframe``, ``verbatimwrapslines``,
``verbatimsep``, ``verbatimborder``.
+ .. versionadded:: 1.6.6
+ support for ``:emphasize-lines:`` option
+ .. versionadded:: 1.6.6
+ easier customizability of the formatting via exposed to user LaTeX macros
+ such as ``\sphinxVerbatimHighlightLine``.
- the bibliography uses ``sphinxthebibliography`` and the Python Module index
as well as the general index both use ``sphinxtheindex``; these environments
are wrappers of the ``thebibliography`` and respectively ``theindex``
diff --git a/doc/markup/code.rst b/doc/markup/code.rst
index cb3e55bdc..0021af501 100644
--- a/doc/markup/code.rst
+++ b/doc/markup/code.rst
@@ -121,6 +121,8 @@ emphasize particular lines::
.. versionchanged:: 1.3
``lineno-start`` has been added.
+.. versionchanged:: 1.6.6
+ LaTeX supports the ``emphasize-lines`` option.
Includes
^^^^^^^^
@@ -188,8 +190,8 @@ Includes
``lines``, the first allowed line having by convention the line number ``1``.
When lines have been selected in any of the ways described above, the
- line numbers in ``emphasize-lines`` also refer to the selection, with the
- first selected line having number ``1``.
+ line numbers in ``emphasize-lines`` refer to those selected lines, counted
+ consecutively starting at ``1``.
When specifying particular parts of a file to display, it can be useful to
display the original line numbers. This can be done using the
diff --git a/doc/markup/inline.rst b/doc/markup/inline.rst
index a59585bab..7ed3e7207 100644
--- a/doc/markup/inline.rst
+++ b/doc/markup/inline.rst
@@ -222,15 +222,15 @@ Cross-referencing figures by figure number
reST labels are used. When you use this role, it will insert a reference to
the figure with link text by its figure number like "Fig. 1.1".
- If an explicit link text is given (like usual: ``:numref:`Image of Sphinx (Fig.
- %s) <my-figure>```), the link caption will be the title of the reference.
- As a special character, `%s` and `{number}` will be replaced to figure
- number. `{name}` will be replaced to figure caption.
- If no explicit link text is given, the value of :confval:`numfig_format` is
- used to default value of link text.
-
- If :confval:`numfig` is ``False``, figures are not numbered.
- so this role inserts not a reference but labels or link text.
+ If an explicit link text is given (as usual: ``:numref:`Image of Sphinx (Fig.
+ %s) <my-figure>```), the link caption will serve as title of the reference.
+ As placeholders, `%s` and `{number}` get replaced by the figure
+ number and `{name}` by the figure caption.
+ If no explicit link text is given, the :confval:`numfig_format` setting is
+ used as fall-back default.
+
+ If :confval:`numfig` is ``False``, figures are not numbered,
+ so this role inserts not a reference but the label or the link text.
Cross-referencing other items of interest
-----------------------------------------
diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py
index 24ed874b0..b764cfc35 100644
--- a/sphinx/apidoc.py
+++ b/sphinx/apidoc.py
@@ -26,7 +26,7 @@ from fnmatch import fnmatch
from sphinx import __display_version__
from sphinx.quickstart import EXTENSIONS
from sphinx.util import rst
-from sphinx.util.osutil import FileAvoidWrite, walk
+from sphinx.util.osutil import FileAvoidWrite, ensuredir, walk
if False:
# For type annotation
@@ -375,9 +375,8 @@ Note: By default this script will not overwrite already created files.""")
if not path.isdir(rootpath):
print('%s is not a directory.' % rootpath, file=sys.stderr)
sys.exit(1)
- if not path.isdir(opts.destdir):
- if not opts.dryrun:
- os.makedirs(opts.destdir)
+ if not opts.dryrun:
+ ensuredir(opts.destdir)
rootpath = path.abspath(rootpath)
excludes = normalize_excludes(rootpath, excludes)
modules = recurse_tree(rootpath, excludes, opts)
diff --git a/sphinx/application.py b/sphinx/application.py
index 0d6d3d0b3..b5705face 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -41,7 +41,7 @@ from sphinx.util import import_object
from sphinx.util import logging
from sphinx.util import status_iterator, old_status_iterator, display_chunk
from sphinx.util.tags import Tags
-from sphinx.util.osutil import ENOENT
+from sphinx.util.osutil import ENOENT, ensuredir
from sphinx.util.console import bold, darkgreen # type: ignore
from sphinx.util.docutils import is_html5_writer_available, directive_helper
from sphinx.util.i18n import find_catalog_source_files
@@ -160,7 +160,7 @@ class Sphinx(object):
if not path.isdir(outdir):
logger.info('making output directory...')
- os.makedirs(outdir)
+ ensuredir(outdir)
# read config
self.tags = Tags(tags)
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index 007964e82..a1d5c5d22 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -9,7 +9,6 @@
:license: BSD, see LICENSE for details.
"""
-import os
from os import path
import warnings
@@ -24,7 +23,7 @@ from docutils import nodes
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.util import i18n, path_stabilize, logging, status_iterator
-from sphinx.util.osutil import SEP, relative_uri
+from sphinx.util.osutil import SEP, ensuredir, relative_uri
from sphinx.util.i18n import find_catalog
from sphinx.util.console import bold # type: ignore
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
@@ -79,8 +78,7 @@ class Builder(object):
self.confdir = app.confdir
self.outdir = app.outdir
self.doctreedir = app.doctreedir
- if not path.isdir(self.doctreedir):
- os.makedirs(self.doctreedir)
+ ensuredir(self.doctreedir)
self.app = app # type: Sphinx
self.env = None # type: BuildEnvironment
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index ead51a983..e50d2abe4 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -274,7 +274,7 @@ class StandaloneHTMLBuilder(Builder):
# type: () -> Iterator[unicode]
cfgdict = dict((confval.name, confval.value) for confval in self.config.filter('html'))
self.config_hash = get_stable_hash(cfgdict)
- self.tags_hash = get_stable_hash(sorted(self.tags)) # type: ignore
+ self.tags_hash = get_stable_hash(sorted(self.tags))
old_config_hash = old_tags_hash = ''
try:
with open(path.join(self.outdir, '.buildinfo')) as fp:
diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py
index 764b01aae..c2e3bbe2c 100644
--- a/sphinx/builders/htmlhelp.py
+++ b/sphinx/builders/htmlhelp.py
@@ -246,7 +246,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
olen = len(outdir)
for root, dirs, files in os.walk(outdir):
staticdir = root.startswith(path.join(outdir, '_static'))
- for fn in files:
+ for fn in sorted(files):
if (staticdir and not fn.endswith('.js')) or \
fn.endswith('.html'):
print(path.join(root, fn)[olen:].replace(os.sep, '\\'),
diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py
index b1c94c548..12a50d140 100644
--- a/sphinx/builders/qthelp.py
+++ b/sphinx/builders/qthelp.py
@@ -188,7 +188,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
for root, dirs, files in os.walk(outdir):
resourcedir = root.startswith(staticdir) or \
root.startswith(imagesdir)
- for fn in files:
+ for fn in sorted(files):
if (resourcedir and not fn.endswith('.js')) or \
fn.endswith('.html'):
filename = path.join(root, fn)[olen:]
@@ -264,7 +264,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
link = node['refuri']
title = htmlescape(node.astext()).replace('"', '&quot;')
item = section_template % {'title': title, 'ref': link}
- item = u' ' * 4 * indentlevel + item # type: ignore
+ item = u' ' * 4 * indentlevel + item
parts.append(item.encode('ascii', 'xmlcharrefreplace'))
elif isinstance(node, nodes.bullet_list):
for subnode in node:
diff --git a/sphinx/config.py b/sphinx/config.py
index 02ee529a3..cc5f57e8e 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -288,7 +288,7 @@ class Config(object):
logger.warning("%s", exc)
for name in config:
if name in self.values:
- self.__dict__[name] = config[name]
+ self.__dict__[name] = config[name] # type: ignore
if isinstance(self.source_suffix, string_types): # type: ignore
self.source_suffix = [self.source_suffix] # type: ignore
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 23c398e13..aa97481ab 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -528,7 +528,7 @@ class ASTBase(UnicodeMixin):
if type(self) is not type(other):
return False
try:
- for key, value in iteritems(self.__dict__): # type: ignore
+ for key, value in iteritems(self.__dict__):
if value != getattr(other, key):
return False
except AttributeError:
diff --git a/sphinx/environment/collectors/toctree.py b/sphinx/environment/collectors/toctree.py
index f19fd5d26..91aa21f2e 100644
--- a/sphinx/environment/collectors/toctree.py
+++ b/sphinx/environment/collectors/toctree.py
@@ -262,7 +262,7 @@ class TocTreeCollector(EnvironmentCollector):
continue
- figtype = env.get_domain('std').get_figtype(subnode) # type: ignore
+ figtype = env.get_domain('std').get_figtype(subnode)
if figtype and subnode['ids']:
register_fignumber(docname, secnum, figtype, subnode)
diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py
index c77598ef1..d3a64049b 100644
--- a/sphinx/ext/napoleon/docstring.py
+++ b/sphinx/ext/napoleon/docstring.py
@@ -194,7 +194,7 @@ class GoogleDocstring(UnicodeMixin):
line = self._line_iter.peek()
while(not self._is_section_break() and
(not line or self._is_indented(line, indent))):
- lines.append(next(self._line_iter)) # type: ignore
+ lines.append(next(self._line_iter))
line = self._line_iter.peek()
return lines
@@ -204,7 +204,7 @@ class GoogleDocstring(UnicodeMixin):
while (self._line_iter.has_next() and
self._line_iter.peek() and
not self._is_section_header()):
- lines.append(next(self._line_iter)) # type: ignore
+ lines.append(next(self._line_iter))
return lines
def _consume_empty(self):
@@ -212,13 +212,13 @@ class GoogleDocstring(UnicodeMixin):
lines = []
line = self._line_iter.peek()
while self._line_iter.has_next() and not line:
- lines.append(next(self._line_iter)) # type: ignore
+ lines.append(next(self._line_iter))
line = self._line_iter.peek()
return lines
def _consume_field(self, parse_type=True, prefer_type=False):
# type: (bool, bool) -> Tuple[unicode, unicode, List[unicode]]
- line = next(self._line_iter) # type: ignore
+ line = next(self._line_iter)
before, colon, after = self._partition_field_on_colon(line)
_name, _type, _desc = before, '', after # type: unicode, unicode, unicode
@@ -250,7 +250,7 @@ class GoogleDocstring(UnicodeMixin):
def _consume_inline_attribute(self):
# type: () -> Tuple[unicode, List[unicode]]
- line = next(self._line_iter) # type: ignore
+ line = next(self._line_iter)
_type, colon, _desc = self._partition_field_on_colon(line)
if not colon:
_type, _desc = _desc, _type
@@ -285,7 +285,7 @@ class GoogleDocstring(UnicodeMixin):
def _consume_section_header(self):
# type: () -> unicode
- section = next(self._line_iter) # type: ignore
+ section = next(self._line_iter)
stripped_section = section.strip(':')
if stripped_section.lower() in self._sections:
section = stripped_section
@@ -295,7 +295,7 @@ class GoogleDocstring(UnicodeMixin):
# type: () -> List[unicode]
lines = []
while self._line_iter.has_next():
- lines.append(next(self._line_iter)) # type: ignore
+ lines.append(next(self._line_iter))
return lines
def _consume_to_next_section(self):
@@ -303,7 +303,7 @@ class GoogleDocstring(UnicodeMixin):
self._consume_empty()
lines = []
while not self._is_section_break():
- lines.append(next(self._line_iter)) # type: ignore
+ lines.append(next(self._line_iter))
return lines + self._consume_empty()
def _dedent(self, lines, full=False):
@@ -886,7 +886,7 @@ class NumpyDocstring(GoogleDocstring):
def _consume_field(self, parse_type=True, prefer_type=False):
# type: (bool, bool) -> Tuple[unicode, unicode, List[unicode]]
- line = next(self._line_iter) # type: ignore
+ line = next(self._line_iter)
if parse_type:
_name, _, _type = self._partition_field_on_colon(line)
else:
@@ -907,10 +907,10 @@ class NumpyDocstring(GoogleDocstring):
def _consume_section_header(self):
# type: () -> unicode
- section = next(self._line_iter) # type: ignore
+ section = next(self._line_iter)
if not _directive_regex.match(section):
# Consume the header underline
- next(self._line_iter) # type: ignore
+ next(self._line_iter)
return section
def _is_section_break(self):
diff --git a/sphinx/pycode/nodes.py b/sphinx/pycode/nodes.py
index cecde9bd0..ea3b3e9ad 100644
--- a/sphinx/pycode/nodes.py
+++ b/sphinx/pycode/nodes.py
@@ -208,5 +208,5 @@ class NodeVisitor(object):
def generic_visit(self, node):
"""Called if no explicit visitor function exists for a node."""
if isinstance(node, Node):
- for child in node: # type: ignore
+ for child in node:
self.visit(child)
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index 67a59b059..5d8738996 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -35,7 +35,7 @@ from six.moves.urllib.parse import quote as urlquote
from docutils.utils import column_width
from sphinx import __display_version__, package_dir
-from sphinx.util.osutil import make_filename
+from sphinx.util.osutil import ensuredir, make_filename
from sphinx.util.console import ( # type: ignore
purple, bold, red, turquoise, nocolor, color_terminal
)
@@ -69,13 +69,6 @@ EXTENSIONS = ('autodoc', 'doctest', 'intersphinx', 'todo', 'coverage',
PROMPT_PREFIX = '> '
-def mkdir_p(dir):
- # type: (unicode) -> None
- if path.isdir(dir):
- return
- os.makedirs(dir)
-
-
# function to get input from terminal -- overridden by the test suite
def term_input(prompt):
# type: (unicode) -> unicode
@@ -433,11 +426,11 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
d[key + '_str'] = d[key].replace('\\', '\\\\').replace("'", "\\'")
if not path.isdir(d['path']):
- mkdir_p(d['path'])
+ ensuredir(d['path'])
srcdir = d['sep'] and path.join(d['path'], 'source') or d['path']
- mkdir_p(srcdir)
+ ensuredir(srcdir)
if d['sep']:
builddir = path.join(d['path'], 'build')
d['exclude_patterns'] = ''
@@ -448,18 +441,20 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
'Thumbs.db', '.DS_Store',
])
d['exclude_patterns'] = ', '.join(exclude_patterns)
- mkdir_p(builddir)
- mkdir_p(path.join(srcdir, d['dot'] + 'templates'))
- mkdir_p(path.join(srcdir, d['dot'] + 'static'))
+ ensuredir(builddir)
+ ensuredir(path.join(srcdir, d['dot'] + 'templates'))
+ ensuredir(path.join(srcdir, d['dot'] + 'static'))
def write_file(fpath, content, newline=None):
# type: (unicode, unicode, unicode) -> None
if overwrite or not path.isfile(fpath):
- print('Creating file %s.' % fpath)
+ if 'quiet' not in d:
+ print('Creating file %s.' % fpath)
with open(fpath, 'wt', encoding='utf-8', newline=newline) as f:
f.write(content)
else:
- print('File %s already exists, skipping.' % fpath)
+ if 'quiet' not in d:
+ print('File %s already exists, skipping.' % fpath)
conf_path = os.path.join(templatedir, 'conf.py_t') if templatedir else None
if not conf_path or not path.isfile(conf_path):
diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py
index d219a14d9..8c00a2ff8 100644
--- a/sphinx/setup_command.py
+++ b/sphinx/setup_command.py
@@ -136,8 +136,8 @@ class BuildDoc(Command):
# type: () -> None
if self.source_dir is None:
self.source_dir = self._guess_source_dir()
- self.announce('Using source directory %s' % self.source_dir) # type: ignore
- self.ensure_dirname('source_dir') # type: ignore
+ self.announce('Using source directory %s' % self.source_dir)
+ self.ensure_dirname('source_dir')
if self.source_dir is None:
self.source_dir = os.curdir
self.source_dir = abspath(self.source_dir)
@@ -145,10 +145,10 @@ class BuildDoc(Command):
self.config_dir = self.source_dir
self.config_dir = abspath(self.config_dir)
- self.ensure_string_list('builder') # type: ignore
+ self.ensure_string_list('builder')
if self.build_dir is None:
- build = self.get_finalized_command('build') # type: ignore
- self.build_dir = os.path.join(abspath(build.build_base), 'sphinx')
+ build = self.get_finalized_command('build')
+ self.build_dir = os.path.join(abspath(build.build_base), 'sphinx') # type: ignore
self.mkpath(self.build_dir) # type: ignore
self.build_dir = abspath(self.build_dir)
self.doctree_dir = os.path.join(self.build_dir, 'doctrees')
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index a28220cbc..5ceb05e19 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -6,7 +6,7 @@
%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\ProvidesPackage{sphinx}[2017/07/24 v1.6.4 LaTeX package (Sphinx markup)]
+\ProvidesPackage{sphinx}[2017/12/12 v1.6.6 LaTeX package (Sphinx markup)]
% provides \ltx@ifundefined
% (many packages load ltxcmds: graphicx does for pdftex and lualatex but
@@ -39,7 +39,7 @@
\@ifclassloaded{memoir}{}{\RequirePackage{fancyhdr}}
% for \text macro and \iffirstchoice@ conditional even if amsmath not loaded
\RequirePackage{amstext}
-\RequirePackage{textcomp}
+\RequirePackage[warn]{textcomp}
\RequirePackage{titlesec}
\@ifpackagelater{titlesec}{2016/03/15}%
{\@ifpackagelater{titlesec}{2016/03/21}%
@@ -159,6 +159,7 @@
% For highlighted code.
\RequirePackage{fancyvrb}
\fvset{fontsize=\small}
+\define@key{FV}{hllines}{\def\sphinx@verbatim@checkifhl##1{\in@{, ##1,}{#1}}}
% For hyperlinked footnotes in tables; also for gathering footnotes from
% topic and warning blocks. Also to allow code-blocks in footnotes.
\RequirePackage{footnotehyper-sphinx}
@@ -208,6 +209,17 @@
% stylesheet for highlighting with pygments
\RequirePackage{sphinxhighlight}
+% fix baseline increase from Pygments latex formatter in case of error tokens
+% and keep \fboxsep's scope local via added braces
+\def\PYG@tok@err{%
+ \def\PYG@bc##1{{\setlength{\fboxsep}{-\fboxrule}%
+ \fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}%
+}
+\def\PYG@tok@cs{%
+ \def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}%
+ \def\PYG@bc##1{{\setlength{\fboxsep}{0pt}%
+ \colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}%
+}%
%% OPTIONS
@@ -306,6 +318,8 @@
% set the key handler. The "value" ##1 must be acceptable by \definecolor.
\define@key{sphinx}{#1}{\definecolor{sphinx#1}##1}%
}%
+% Default color chosen to be as in minted.sty LaTeX package!
+\sphinxDeclareSphinxColorOption{VerbatimHighlightColor}{{rgb}{0.878,1,1}}
% admonition boxes, "light" style
\sphinxDeclareSphinxColorOption{noteBorderColor}{{rgb}{0,0,0}}
\sphinxDeclareSphinxColorOption{hintBorderColor}{{rgb}{0,0,0}}
@@ -362,7 +376,7 @@
\expandafter\let
\csname @list\romannumeral\the\count@\expandafter\endcsname
\csname @list\romannumeral\the\numexpr\count@-\@ne\endcsname
- % work around 2.6--3.2d babel-french issue (fixed in 3.2e; no change needed)
+ % workaround 2.6--3.2d babel-french issue (fixed in 3.2e; no change needed)
\ltx@ifundefined{leftmargin\romannumeral\the\count@}
{\expandafter\let
\csname leftmargin\romannumeral\the\count@\expandafter\endcsname
@@ -837,6 +851,34 @@
% needed to create wrapper environments of fancyvrb's Verbatim
\newcommand*{\sphinxVerbatimEnvironment}{\gdef\FV@EnvironName{sphinxVerbatim}}
+% serves to implement line highlighting and line wrapping
+\newcommand\sphinxFancyVerbFormatLine[1]{%
+ \expandafter\sphinx@verbatim@checkifhl\expandafter{\the\FV@CodeLineNo}%
+ \ifin@
+ \sphinxVerbatimHighlightLine{#1}%
+ \else
+ \sphinxVerbatimFormatLine{#1}%
+ \fi
+}%
+\newcommand\sphinxVerbatimHighlightLine[1]{%
+ \edef\sphinxrestorefboxsep{\fboxsep\the\fboxsep\relax}%
+ \fboxsep0pt\relax % cf LaTeX bug graphics/4524
+ \colorbox{sphinxVerbatimHighlightColor}%
+ {\sphinxrestorefboxsep\sphinxVerbatimFormatLine{#1}}%
+ % no need to restore \fboxsep here, as this ends up in a \hbox from fancyvrb
+}%
+% \sphinxVerbatimFormatLine will be set locally to one of those two:
+\newcommand\sphinxVerbatimFormatLineWrap[1]{%
+ \hsize\linewidth
+ \vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@
+ \doublehyphendemerits\z@\finalhyphendemerits\z@
+ \strut #1\strut}%
+}%
+\newcommand\sphinxVerbatimFormatLineNoWrap[1]{\hb@xt@\linewidth{\strut #1\hss}}%
+\g@addto@macro\FV@SetupFont{%
+ \sbox\sphinxcontinuationbox {\spx@opt@verbatimcontinued}%
+ \sbox\sphinxvisiblespacebox {\spx@opt@verbatimvisiblespace}%
+}%
% Sphinx <1.5 optional argument was in fact mandatory. It is now really
% optional and handled by original Verbatim.
\newenvironment{sphinxVerbatim}{%
@@ -883,23 +925,19 @@
% to achieve this without extensive rewrite of fancyvrb.
% - The (not used in sphinx) obeytabs option to Verbatim is
% broken by this change (showtabs and tabspace work).
- \expandafter\def\expandafter\FV@SetupFont\expandafter
- {\FV@SetupFont\sbox\sphinxcontinuationbox {\spx@opt@verbatimcontinued}%
- \sbox\sphinxvisiblespacebox {\spx@opt@verbatimvisiblespace}}%
- \def\FancyVerbFormatLine ##1{\hsize\linewidth
- \vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@
- \doublehyphendemerits\z@\finalhyphendemerits\z@
- \strut ##1\strut}%
- }%
- \let\FV@Space\spx@verbatim@space
+ \let\sphinxVerbatimFormatLine\sphinxVerbatimFormatLineWrap
+ \let\FV@Space\spx@verbatim@space
% Allow breaks at special characters using \PYG... macros.
- \sphinxbreaksatspecials
+ \sphinxbreaksatspecials
% Breaks at punctuation characters . , ; ? ! and / (needs catcode activation)
- \def\FancyVerbCodes{\sphinxbreaksviaactive}%
- \fi % end of conditional code for wrapping long code lines
- % go around fancyvrb's check of \@currenvir
+ \fvset{codes*=\sphinxbreaksviaactive}%
+ \else % end of conditional code for wrapping long code lines
+ \let\sphinxVerbatimFormatLine\sphinxVerbatimFormatLineNoWrap
+ \fi
+ \let\FancyVerbFormatLine\sphinxFancyVerbFormatLine
+ % workaround to fancyvrb's check of \@currenvir
\let\VerbatimEnvironment\sphinxVerbatimEnvironment
- % go around fancyvrb's check of current list depth
+ % workaround to fancyvrb's check of current list depth
\def\@toodeep {\advance\@listdepth\@ne}%
% The list environment is needed to control perfectly the vertical space.
% Note: \OuterFrameSep used by framed.sty is later set to \topsep hence 0pt.
@@ -986,7 +1024,7 @@
\sphinxunactivateextras}%
% now for the modified alltt environment
\newenvironment{sphinxalltt}
-{% at start of next line to work around Emacs/AUCTeX issue with this file
+{% at start of next line to workaround Emacs/AUCTeX issue with this file
\begin{alltt}%
\ifspx@opt@parsedliteralwraps
\sbox\sphinxcontinuationbox {\spx@opt@verbatimcontinued}%
@@ -1212,7 +1250,7 @@
\spx@notice@border \dimexpr\csname spx@opt@#1border\endcsname\relax
% start specific environment, passing the heading as argument
\begin{sphinx#1}{#2}}
- % in end part, need to go around a LaTeX's "feature"
+ % workaround some LaTeX "feature" of \end command
{\edef\spx@temp{\noexpand\end{sphinx\spx@noticetype}}\spx@temp}
% use of ``notice'' is for backwards compatibility and will be removed in
% Sphinx 1.7.
diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py
index 0ceced214..c5fe7864e 100644
--- a/sphinx/transforms/__init__.py
+++ b/sphinx/transforms/__init__.py
@@ -346,5 +346,5 @@ class SphinxSmartQuotes(SmartQuotes):
texttype = {True: 'literal', # "literal" text is not changed:
False: 'plain'}
for txtnode in txtnodes:
- smartquotable = not is_smartquotable(txtnode)
- yield (texttype[smartquotable], txtnode.astext())
+ notsmartquotable = not is_smartquotable(txtnode)
+ yield (texttype[notsmartquotable], txtnode.astext())
diff --git a/sphinx/transforms/compact_bullet_list.py b/sphinx/transforms/compact_bullet_list.py
index 006ae7161..8c930c8bc 100644
--- a/sphinx/transforms/compact_bullet_list.py
+++ b/sphinx/transforms/compact_bullet_list.py
@@ -14,6 +14,10 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.transforms import SphinxTransform
+if False:
+ # For type annotation
+ from typing import List # NOQA
+
class RefOnlyListChecker(nodes.GenericNodeVisitor):
"""Raise `nodes.NodeFound` if non-simple list item is encountered.
@@ -32,7 +36,7 @@ class RefOnlyListChecker(nodes.GenericNodeVisitor):
def visit_list_item(self, node):
# type: (nodes.Node) -> None
- children = []
+ children = [] # type: List[nodes.Node]
for child in node.children:
if not isinstance(child, nodes.Invisible):
children.append(child)
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 03f8ce6a3..55fb9fcc1 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -398,10 +398,8 @@ def parselinenos(spec, total):
elif len(begend) == 1:
items.append(int(begend[0]) - 1)
elif len(begend) == 2:
- start = int(begend[0] or 1) # type: ignore
- # left half open (cf. -10)
- end = int(begend[1] or max(start, total)) # type: ignore
- # right half open (cf. 10-)
+ start = int(begend[0] or 1) # left half open (cf. -10)
+ end = int(begend[1] or max(start, total)) # right half open (cf. 10-)
if start > end: # invalid range (cf. 10-1)
raise ValueError
items.extend(range(start - 1, end))
@@ -528,7 +526,7 @@ class PeekableIterator(object):
def peek(self):
# type: () -> Any
"""Return the next item without changing the state of the iterator."""
- item = next(self) # type: ignore
+ item = next(self)
self.push(item)
return item
diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py
index 41dc6022f..00c12ec4f 100644
--- a/sphinx/util/logging.py
+++ b/sphinx/util/logging.py
@@ -82,6 +82,10 @@ def convert_serializable(records):
r.msg = r.getMessage()
r.args = ()
+ location = getattr(r, 'location', None)
+ if isinstance(location, nodes.Node):
+ r.location = get_node_location(location) # type: ignore
+
class SphinxWarningLogRecord(logging.LogRecord):
"""Log record class supporting location"""
@@ -152,8 +156,8 @@ class NewLineStreamHandlerPY2(logging.StreamHandler):
# remove return code forcely when nonl=True
self.stream = StringIO()
super(NewLineStreamHandlerPY2, self).emit(record)
- stream.write(self.stream.getvalue()[:-1]) # type: ignore
- stream.flush() # type: ignore
+ stream.write(self.stream.getvalue()[:-1])
+ stream.flush()
else:
super(NewLineStreamHandlerPY2, self).emit(record)
finally:
@@ -415,21 +419,26 @@ class WarningLogRecordTranslator(logging.Filter):
else:
record.location = None
elif isinstance(location, nodes.Node):
- (source, line) = get_source_line(location)
- if source and line:
- record.location = "%s:%s" % (source, line)
- elif source:
- record.location = "%s:" % source
- elif line:
- record.location = "<unknown>:%s" % line
- else:
- record.location = None
+ record.location = get_node_location(location)
elif location and ':' not in location:
record.location = '%s' % self.app.env.doc2path(location)
return True
+def get_node_location(node):
+ # type: (nodes.Node) -> str
+ (source, line) = get_source_line(node)
+ if source and line:
+ return "%s:%s" % (source, line)
+ elif source:
+ return "%s:" % source
+ elif line:
+ return "<unknown>:%s" % line
+ else:
+ return None
+
+
class ColorizeFormatter(logging.Formatter):
def format(self, record):
# type: (logging.LogRecord) -> str
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index df39c84fd..39c7bc81e 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -48,6 +48,8 @@ BEGIN_DOC = r'''
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
SECNUMDEPTH = 3
+LATEXSECTIONNAMES = ["part", "chapter", "section", "subsection",
+ "subsubsection", "paragraph", "subparagraph"]
DEFAULT_SETTINGS = {
'latex_engine': 'pdflatex',
@@ -501,8 +503,6 @@ def rstdim_to_latexdim(width_str):
class LaTeXTranslator(nodes.NodeVisitor):
- sectionnames = ["part", "chapter", "section", "subsection",
- "subsubsection", "paragraph", "subparagraph"]
ignore_missing_images = False
@@ -532,16 +532,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.compact_list = 0
self.first_param = 0
- # determine top section level
- if builder.config.latex_toplevel_sectioning:
- self.top_sectionlevel = \
- self.sectionnames.index(builder.config.latex_toplevel_sectioning)
- else:
- if document.settings.docclass == 'howto':
- self.top_sectionlevel = 2
- else:
- self.top_sectionlevel = 1
-
# sort out some elements
self.elements = DEFAULT_SETTINGS.copy()
self.elements.update(ADDITIONAL_SETTINGS.get(builder.config.latex_engine, {}))
@@ -564,11 +554,30 @@ class LaTeXTranslator(nodes.NodeVisitor):
})
if builder.config.latex_keep_old_macro_names:
self.elements['sphinxpkgoptions'] = ''
+
+ # we assume LaTeX class provides \chapter command except in case
+ # of non-Japanese 'howto' case
+ self.sectionnames = LATEXSECTIONNAMES[:]
if document.settings.docclass == 'howto':
docclass = builder.config.latex_docclass.get('howto', 'article')
+ if docclass[0] == 'j': # Japanese class...
+ pass
+ else:
+ self.sectionnames.remove('chapter')
else:
docclass = builder.config.latex_docclass.get('manual', 'report')
self.elements['docclass'] = docclass
+
+ # determine top section level
+ self.top_sectionlevel = 1
+ if builder.config.latex_toplevel_sectioning:
+ try:
+ self.top_sectionlevel = \
+ self.sectionnames.index(builder.config.latex_toplevel_sectioning)
+ except ValueError:
+ logger.warning('unknown %r toplevel_sectioning for class %r' %
+ (builder.config.latex_toplevel_sectioning, docclass))
+
if builder.config.today:
self.elements['date'] = builder.config.today
else:
@@ -631,21 +640,23 @@ class LaTeXTranslator(nodes.NodeVisitor):
usepackages = (declare_package(*p) for p in builder.usepackages)
self.elements['usepackages'] += "\n".join(usepackages)
if document.get('tocdepth'):
- # redece tocdepth if `part` or `chapter` is used for top_sectionlevel
+ # reduce tocdepth if `part` or `chapter` is used for top_sectionlevel
# tocdepth = -1: show only parts
# tocdepth = 0: show parts and chapters
# tocdepth = 1: show parts, chapters and sections
# tocdepth = 2: show parts, chapters, sections and subsections
# ...
+
tocdepth = document['tocdepth'] + self.top_sectionlevel - 2
- maxdepth = len(self.sectionnames) - self.top_sectionlevel
- if tocdepth > maxdepth:
+ if len(self.sectionnames) < 7 and self.top_sectionlevel > 0:
+ tocdepth += 1 # because top_sectionlevel is shifted by -1
+ if tocdepth > 5: # 5 corresponds to subparagraph
logger.warning('too large :maxdepth:, ignored.')
- tocdepth = maxdepth
+ tocdepth = 5
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
if tocdepth >= SECNUMDEPTH:
- # Increase secnumdepth if tocdepth is depther than default SECNUMDEPTH
+ # Increase secnumdepth if tocdepth is deeper than default SECNUMDEPTH
self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' % tocdepth
if getattr(document.settings, 'contentsname', None):
@@ -2270,6 +2281,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
lang = self.hlsettingstack[-1][0]
linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
highlight_args = node.get('highlight_args', {})
+ hllines = '\\fvset{hllines={, %s,}}%%' %\
+ str(highlight_args.get('hl_lines', []))[1:-1]
if 'language' in node:
# code-block directives
lang = node['language']
@@ -2308,7 +2321,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
hlcode += '\\end{sphinxVerbatimintable}'
else:
hlcode += '\\end{sphinxVerbatim}'
- self.body.append('\n' + hlcode + '\n')
+ self.body.append('\n' + hllines + '\n' + hlcode + '\n')
if ids:
self.body.append('\\let\\sphinxLiteralBlockLabel\\empty\n')
raise nodes.SkipNode
diff --git a/tests/roots/test-root/bom.po b/tests/roots/test-builder-gettext-dont-rebuild-mo/bom.po
index c6025eb1e..c6025eb1e 100644
--- a/tests/roots/test-root/bom.po
+++ b/tests/roots/test-builder-gettext-dont-rebuild-mo/bom.po
diff --git a/tests/roots/test-builder-gettext-dont-rebuild-mo/bom.rst b/tests/roots/test-builder-gettext-dont-rebuild-mo/bom.rst
new file mode 100644
index 000000000..3fea824f8
--- /dev/null
+++ b/tests/roots/test-builder-gettext-dont-rebuild-mo/bom.rst
@@ -0,0 +1,5 @@
+File with UTF-8 BOM
+===================
+
+This file has a UTF-8 "BOM".
+
diff --git a/tests/roots/test-builder-gettext-dont-rebuild-mo/conf.py b/tests/roots/test-builder-gettext-dont-rebuild-mo/conf.py
new file mode 100644
index 000000000..31e7a6ed4
--- /dev/null
+++ b/tests/roots/test-builder-gettext-dont-rebuild-mo/conf.py
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+
+master_doc = 'index'
+
+latex_documents = [
+ (master_doc, 'test.tex', 'The basic Sphinx documentation for testing', 'Sphinx', 'report')
+]
diff --git a/tests/roots/test-builder-gettext-dont-rebuild-mo/index.rst b/tests/roots/test-builder-gettext-dont-rebuild-mo/index.rst
new file mode 100644
index 000000000..7ff38c5a8
--- /dev/null
+++ b/tests/roots/test-builder-gettext-dont-rebuild-mo/index.rst
@@ -0,0 +1,6 @@
+The basic Sphinx documentation for testing
+==========================================
+
+.. toctree::
+
+ bom
diff --git a/tests/roots/test-directive-code/emphasize.rst b/tests/roots/test-directive-code/emphasize.rst
new file mode 100644
index 000000000..95db574ce
--- /dev/null
+++ b/tests/roots/test-directive-code/emphasize.rst
@@ -0,0 +1,7 @@
+Literal Includes with Highlighted Lines
+=======================================
+
+.. literalinclude:: target.py
+ :language: python
+ :emphasize-lines: 5-6, 13-15, 24-
+
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 979385785..7b4fb6964 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
@@ -27,6 +27,7 @@ header2
\endlastfoot
+\fvset{hllines={, ,}}%
\begin{sphinxVerbatimintable}[commandchars=\\\{\}]
\PYG{n}{hello} \PYG{n}{world}
\end{sphinxVerbatimintable}
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 d8231817a..4a49e4cbb 100644
--- a/tests/roots/test-latex-table/expects/table_having_verbatim.tex
+++ b/tests/roots/test-latex-table/expects/table_having_verbatim.tex
@@ -10,6 +10,7 @@ header1
header2
\unskip}\relax \\
\hline
+\fvset{hllines={, ,}}%
\begin{sphinxVerbatimintable}[commandchars=\\\{\}]
\PYG{n}{hello} \PYG{n}{world}
\end{sphinxVerbatimintable}
diff --git a/tests/roots/test-root/_static/README b/tests/roots/test-root/_static/README
deleted file mode 100644
index 9e1ec3569..000000000
--- a/tests/roots/test-root/_static/README
+++ /dev/null
@@ -1 +0,0 @@
-This whole directory is there to test html_static_path.
diff --git a/tests/roots/test-root/_static/excluded.css b/tests/roots/test-root/_static/excluded.css
deleted file mode 100644
index 03c941a44..000000000
--- a/tests/roots/test-root/_static/excluded.css
+++ /dev/null
@@ -1 +0,0 @@
-/* This file should be excluded from being copied over */
diff --git a/tests/roots/test-root/_static/subdir/foo.css b/tests/roots/test-root/_static/subdir/foo.css
deleted file mode 100644
index 9427981d6..000000000
--- a/tests/roots/test-root/_static/subdir/foo.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Stub file */
diff --git a/tests/roots/test-root/conf.py b/tests/roots/test-root/conf.py
index a23aec482..bd3cb9a9b 100644
--- a/tests/roots/test-root/conf.py
+++ b/tests/roots/test-root/conf.py
@@ -29,15 +29,10 @@ numfig = True
rst_epilog = '.. |subst| replace:: global substitution'
-html_theme = 'testtheme'
-html_theme_path = ['.']
-html_theme_options = {'testopt': 'testoverride'}
html_sidebars = {'**': 'customsb.html',
'contents': ['contentssb.html', 'localtoc.html',
'globaltoc.html']}
html_style = 'default.css'
-html_static_path = ['_static', 'templated.css_t']
-html_extra_path = ['robots.txt']
html_last_updated_fmt = '%b %d, %Y'
html_context = {'hckey': 'hcval', 'hckey_co': 'wrong_hcval_co'}
diff --git a/tests/roots/test-root/robots.txt b/tests/roots/test-root/robots.txt
deleted file mode 100644
index 1b425ee0f..000000000
--- a/tests/roots/test-root/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow: /cgi-bin/
diff --git a/tests/roots/test-root/subdir.po b/tests/roots/test-root/subdir.po
deleted file mode 100644
index f515f2207..000000000
--- a/tests/roots/test-root/subdir.po
+++ /dev/null
@@ -1,9 +0,0 @@
-#, fuzzy
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-msgid "Including in subdir"
-msgstr "translation"
diff --git a/tests/roots/test-root/templated.css_t b/tests/roots/test-root/templated.css_t
deleted file mode 100644
index 72ddb807c..000000000
--- a/tests/roots/test-root/templated.css_t
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Stub file, templated */
-{{ sphinx_version }}
diff --git a/tests/roots/test-root/testtheme/layout.html b/tests/roots/test-theming/test_theme/staticfiles/layout.html
index 81372be0f..81372be0f 100644
--- a/tests/roots/test-root/testtheme/layout.html
+++ b/tests/roots/test-theming/test_theme/staticfiles/layout.html
diff --git a/tests/roots/test-root/testtheme/static/staticimg.png b/tests/roots/test-theming/test_theme/staticfiles/static/staticimg.png
index fda6cd29e..fda6cd29e 100644
--- a/tests/roots/test-root/testtheme/static/staticimg.png
+++ b/tests/roots/test-theming/test_theme/staticfiles/static/staticimg.png
Binary files differ
diff --git a/tests/roots/test-root/testtheme/static/statictmpl.html_t b/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html_t
index 4ab292b42..4ab292b42 100644
--- a/tests/roots/test-root/testtheme/static/statictmpl.html_t
+++ b/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html_t
diff --git a/tests/roots/test-root/testtheme/theme.conf b/tests/roots/test-theming/test_theme/staticfiles/theme.conf
index a87767379..a87767379 100644
--- a/tests/roots/test-root/testtheme/theme.conf
+++ b/tests/roots/test-theming/test_theme/staticfiles/theme.conf
diff --git a/tests/roots/test-root/ziptheme.zip b/tests/roots/test-theming/ziptheme.zip
index 8a246ed98..8a246ed98 100644
--- a/tests/roots/test-root/ziptheme.zip
+++ b/tests/roots/test-theming/ziptheme.zip
Binary files differ
diff --git a/tests/test_build.py b/tests/test_build.py
index 2372b102b..c61fbb5c2 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -59,13 +59,13 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
return srcdir
+# note: this test skips building docs for some builders because they have independent testcase.
+# (html, latex, texinfo and manpage)
@pytest.mark.parametrize(
"buildername",
[
- # note: no 'html' - if it's ok with dirhtml it's ok with html
- 'dirhtml', 'singlehtml', 'latex', 'texinfo', 'pickle', 'json', 'text',
- 'htmlhelp', 'qthelp', 'epub2', 'epub', 'applehelp', 'changes', 'xml',
- 'pseudoxml', 'man', 'linkcheck',
+ 'dirhtml', 'singlehtml', 'pickle', 'json', 'text', 'htmlhelp', 'qthelp',
+ 'epub2', 'epub', 'applehelp', 'changes', 'xml', 'pseudoxml', 'linkcheck',
],
)
@mock.patch('sphinx.builders.linkcheck.requests.head',
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index ceeb5f01c..0ccd4da01 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -126,24 +126,6 @@ def check_xpath(etree, fname, path, check, be_found=True):
[node.text for node in nodes]))
-def check_static_entries(outdir):
- staticdir = outdir / '_static'
- assert staticdir.isdir()
- # a file from a directory entry in html_static_path
- assert (staticdir / 'README').isfile()
- # a directory from a directory entry in html_static_path
- assert (staticdir / 'subdir' / 'foo.css').isfile()
- # a file from a file entry in html_static_path
- assert (staticdir / 'templated.css').isfile()
- assert (staticdir / 'templated.css').text().splitlines()[1] == __display_version__
- # a file from _static, but matches exclude_patterns
- assert not (staticdir / 'excluded.css').exists()
-
-
-def check_extra_entries(outdir):
- assert (outdir / 'robots.txt').isfile()
-
-
@pytest.mark.sphinx('html', testroot='warnings')
def test_html_warnings(app, warning):
app.build()
@@ -156,15 +138,6 @@ def test_html_warnings(app, warning):
'--- Got:\n' + html_warnings
-@pytest.mark.sphinx('html', tags=['testtag'], confoverrides={
- 'html_context.hckey_co': 'hcval_co'})
-@pytest.mark.test_params(shared_result='test_build_html_output')
-def test_static_output(app):
- app.build()
- check_static_entries(app.builder.outdir)
- check_extra_entries(app.builder.outdir)
-
-
@pytest.mark.parametrize("fname,expect", flat_dict({
'images.html': [
(".//img[@src='_images/img.png']", ''),
@@ -377,7 +350,6 @@ def test_static_output(app):
'contents.html': [
(".//meta[@name='hc'][@content='hcval']", ''),
(".//meta[@name='hc_co'][@content='hcval_co']", ''),
- (".//meta[@name='testopt'][@content='testoverride']", ''),
(".//td[@class='label']", r'\[Ref1\]'),
(".//td[@class='label']", ''),
(".//li[@class='toctree-l1']/a", 'Testing various markup'),
@@ -410,9 +382,6 @@ def test_static_output(app):
(".//a[@href='http://bugs.python.org/issue1000']", "issue 1000"),
(".//a[@href='http://bugs.python.org/issue1042']", "explicit caption"),
],
- '_static/statictmpl.html': [
- (".//project", 'Sphinx <Tests>'),
- ],
'genindex.html': [
# index entries
(".//a/strong", "Main"),
@@ -1145,16 +1114,28 @@ def test_html_assets(app):
assert not (app.outdir / 'subdir' / '.htpasswd').exists()
-@pytest.mark.sphinx('html', confoverrides={'html_sourcelink_suffix': ''})
+@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_copy_source': False})
+def test_html_copy_source(app):
+ app.builder.build_all()
+ assert not (app.outdir / '_sources' / 'index.rst.txt').exists()
+
+
+@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_sourcelink_suffix': '.txt'})
def test_html_sourcelink_suffix(app):
app.builder.build_all()
- content_otherext = (app.outdir / 'otherext.html').text()
- content_images = (app.outdir / 'images.html').text()
+ assert (app.outdir / '_sources' / 'index.rst.txt').exists()
+
- assert '<a href="_sources/otherext.foo"' in content_otherext
- assert '<a href="_sources/images.txt"' in content_images
- assert (app.outdir / '_sources' / 'otherext.foo').exists()
- assert (app.outdir / '_sources' / 'images.txt').exists()
+@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_sourcelink_suffix': '.rst'})
+def test_html_sourcelink_suffix_same(app):
+ app.builder.build_all()
+ assert (app.outdir / '_sources' / 'index.rst').exists()
+
+
+@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_sourcelink_suffix': ''})
+def test_html_sourcelink_suffix_empty(app):
+ app.builder.build_all()
+ assert (app.outdir / '_sources' / 'index.rst').exists()
@pytest.mark.sphinx('html', testroot='html_entity')
diff --git a/tests/test_build_html5.py b/tests/test_build_html5.py
index 7fc91b9ec..4ad282973 100644
--- a/tests/test_build_html5.py
+++ b/tests/test_build_html5.py
@@ -252,7 +252,6 @@ def cached_etree_parse():
'contents.html': [
(".//meta[@name='hc'][@content='hcval']", ''),
(".//meta[@name='hc_co'][@content='hcval_co']", ''),
- (".//meta[@name='testopt'][@content='testoverride']", ''),
(".//dt[@class='label']/span[@class='brackets']", r'Ref1'),
(".//dt[@class='label']", ''),
(".//li[@class='toctree-l1']/a", 'Testing various markup'),
@@ -285,9 +284,6 @@ def cached_etree_parse():
(".//a[@href='http://bugs.python.org/issue1000']", "issue 1000"),
(".//a[@href='http://bugs.python.org/issue1042']", "explicit caption"),
],
- '_static/statictmpl.html': [
- (".//project", 'Sphinx <Tests>'),
- ],
'genindex.html': [
# index entries
(".//a/strong", "Main"),
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index b1ba73730..faa2f46a7 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -713,20 +713,16 @@ def test_latex_logo_if_not_found(app, status, warning):
assert isinstance(exc, SphinxError)
-@pytest.mark.sphinx('latex', testroot='toctree-maxdepth',
- confoverrides={'latex_documents': [
- ('index', 'SphinxTests.tex', 'Sphinx Tests Documentation',
- 'Georg Brandl', 'manual'),
- ]})
+@pytest.mark.sphinx('latex', testroot='toctree-maxdepth')
def test_toctree_maxdepth_manual(app, status, warning):
app.builder.build_all()
- result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
+ result = (app.outdir / 'Python.tex').text(encoding='utf8')
print(result)
print(status.getvalue())
print(warning.getvalue())
assert '\\setcounter{tocdepth}{1}' in result
assert '\\setcounter{secnumdepth}' not in result
-
+ assert '\\chapter{Foo}' in result
@pytest.mark.sphinx(
'latex', testroot='toctree-maxdepth',
@@ -742,7 +738,7 @@ def test_toctree_maxdepth_howto(app, status, warning):
print(warning.getvalue())
assert '\\setcounter{tocdepth}{2}' in result
assert '\\setcounter{secnumdepth}' not in result
-
+ assert '\\section{Foo}' in result
@pytest.mark.sphinx(
'latex', testroot='toctree-maxdepth',
@@ -755,7 +751,7 @@ def test_toctree_not_found(app, status, warning):
print(warning.getvalue())
assert '\\setcounter{tocdepth}' not in result
assert '\\setcounter{secnumdepth}' not in result
-
+ assert '\\chapter{Foo A}' in result
@pytest.mark.sphinx(
'latex', testroot='toctree-maxdepth',
@@ -805,6 +801,26 @@ def test_latex_toplevel_sectioning_is_part(app, status, warning):
print(status.getvalue())
print(warning.getvalue())
assert '\\part{Foo}' in result
+ assert '\\chapter{Foo A}' in result
+ assert '\\chapter{Foo B}' in result
+
+
+@pytest.mark.sphinx(
+ 'latex', testroot='toctree-maxdepth',
+ confoverrides={'latex_toplevel_sectioning': 'part',
+ 'latex_documents': [
+ ('index', 'Python.tex', 'Sphinx Tests Documentation',
+ 'Georg Brandl', 'howto')
+ ]})
+def test_latex_toplevel_sectioning_is_part_with_howto(app, status, warning):
+ app.builder.build_all()
+ result = (app.outdir / 'Python.tex').text(encoding='utf8')
+ print(result)
+ print(status.getvalue())
+ print(warning.getvalue())
+ assert '\\part{Foo}' in result
+ assert '\\section{Foo A}' in result
+ assert '\\section{Foo B}' in result
@pytest.mark.sphinx(
@@ -821,6 +837,22 @@ def test_latex_toplevel_sectioning_is_chapter(app, status, warning):
@pytest.mark.sphinx(
'latex', testroot='toctree-maxdepth',
+ confoverrides={'latex_toplevel_sectioning': 'chapter',
+ 'latex_documents': [
+ ('index', 'Python.tex', 'Sphinx Tests Documentation',
+ 'Georg Brandl', 'howto')
+ ]})
+def test_latex_toplevel_sectioning_is_chapter_with_howto(app, status, warning):
+ app.builder.build_all()
+ result = (app.outdir / 'Python.tex').text(encoding='utf8')
+ print(result)
+ print(status.getvalue())
+ print(warning.getvalue())
+ assert '\\section{Foo}' in result
+
+
+@pytest.mark.sphinx(
+ 'latex', testroot='toctree-maxdepth',
confoverrides={'latex_toplevel_sectioning': 'section'})
def test_latex_toplevel_sectioning_is_section(app, status, warning):
app.builder.build_all()
diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py
index 548a5d72c..e3069061b 100644
--- a/tests/test_directive_code.py
+++ b/tests/test_directive_code.py
@@ -349,6 +349,14 @@ def test_code_block_namedlink_latex(app, status, warning):
assert link2 in latex
+@pytest.mark.sphinx('latex', testroot='directive-code')
+def test_code_block_emphasize_latex(app, status, warning):
+ app.builder.build(['emphasize'])
+ latex = (app.outdir / 'Python.tex').text(encoding='utf-8').replace('\r\n', '\n')
+ includes = '\\fvset{hllines={, 5, 6, 13, 14, 15, 24, 25, 26, 27,}}%\n'
+ assert includes in latex
+
+
@pytest.mark.sphinx('xml', testroot='directive-code')
def test_literal_include(app, status, warning):
app.builder.build(['index'])
diff --git a/tests/test_intl.py b/tests/test_intl.py
index 8eff52340..6b72438bd 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -520,7 +520,7 @@ def test_gettext_buildr_ignores_only_directive(app):
@sphinx_intl
# use individual shared_result directory to avoid "incompatible doctree" error
-@pytest.mark.test_params(shared_result='test_gettext_dont_rebuild_mo')
+@pytest.mark.sphinx(testroot='builder-gettext-dont-rebuild-mo')
def test_gettext_dont_rebuild_mo(make_app, app_params, build_mo):
# --- don't rebuild by .mo mtime
def get_number_of_update_targets(app_):
@@ -533,7 +533,7 @@ def test_gettext_dont_rebuild_mo(make_app, app_params, build_mo):
app0 = make_app('dummy', *args, **kwargs)
build_mo(app0.srcdir)
app0.build()
- assert (app0.srcdir / 'bom.mo')
+ assert (app0.srcdir / 'xx' / 'LC_MESSAGES' / 'bom.mo').exists()
# Since it is after the build, the number of documents to be updated is 0
assert get_number_of_update_targets(app0) == 0
# When rewriting the timestamp of mo file, the number of documents to be
diff --git a/tests/test_markup.py b/tests/test_markup.py
index dfa4d74cf..9c41845fc 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -211,7 +211,8 @@ def get_verifier(verify, verify_re):
'verify',
u'::\n\n @Γ\\∞${}',
None,
- (u'\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]\n'
+ (u'\\fvset{hllines={, ,}}%\n'
+ u'\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]\n'
u'@\\(\\Gamma\\)\\PYGZbs{}\\(\\infty\\)\\PYGZdl{}\\PYGZob{}\\PYGZcb{}\n'
u'\\end{sphinxVerbatim}'),
),
diff --git a/tests/test_theming.py b/tests/test_theming.py
index ef9656bc5..176c9eebc 100644
--- a/tests/test_theming.py
+++ b/tests/test_theming.py
@@ -17,6 +17,7 @@ from sphinx.theming import ThemeError
@pytest.mark.sphinx(
+ testroot='theming',
confoverrides={'html_theme': 'ziptheme',
'html_theme_options.testopt': 'foo'})
def test_theme_api(app, status, warning):
@@ -25,10 +26,11 @@ def test_theme_api(app, status, warning):
# test Theme class API
assert set(app.html_themes.keys()) == \
set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc', 'haiku',
- 'traditional', 'testtheme', 'ziptheme', 'epub', 'nature',
- 'pyramid', 'bizstyle', 'classic', 'nonav'])
- assert app.html_themes['testtheme'] == app.srcdir / 'testtheme'
+ 'traditional', 'epub', 'nature', 'pyramid', 'bizstyle', 'classic', 'nonav',
+ 'test-theme', 'ziptheme', 'staticfiles', 'parent', 'child'])
+ assert app.html_themes['test-theme'] == app.srcdir / 'test_theme' / 'test-theme'
assert app.html_themes['ziptheme'] == app.srcdir / 'ziptheme.zip'
+ assert app.html_themes['staticfiles'] == app.srcdir / 'test_theme' / 'staticfiles'
# test Theme instance API
theme = app.builder.theme
@@ -93,3 +95,18 @@ def test_double_inheriting_theme(app, status, warning):
def test_nested_zipped_theme(app, status, warning):
assert app.builder.theme.name == 'child'
app.build() # => not raises TemplateNotFound
+
+
+@pytest.mark.sphinx(testroot='theming',
+ confoverrides={'html_theme': 'staticfiles'})
+def test_staticfiles(app, status, warning):
+ app.build()
+ assert (app.outdir / '_static' / 'staticimg.png').exists()
+ assert (app.outdir / '_static' / 'statictmpl.html').exists()
+ assert (app.outdir / '_static' / 'statictmpl.html').text() == (
+ '<!-- testing static templates -->\n'
+ '<html><project>Python</project></html>'
+ )
+
+ result = (app.outdir / 'index.html').text()
+ assert '<meta name="testopt" content="optdefault" />' in result