Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jellby 2016-03-06 10:08:19 +01:00
commit a3551a811b
26 changed files with 485 additions and 147 deletions

24
CHANGES
View File

@ -3,6 +3,9 @@ Release 1.4 alpha2 (in development)
Incompatible changes Incompatible changes
-------------------- --------------------
* #2327: `latex_use_parts` is deprecated now. Use `latex_toplevel_sectioning` instead.
* #2337: Use ``\url{URL}`` macro instead of ``\href{URL}{URL}`` in LaTeX writer.
* #1498: manpage writer: don't make whole of item in definition list bold if it includes strong node.
Features added Features added
-------------- --------------
@ -13,9 +16,14 @@ Features added
* #2245: Add ``latex_elements["passoptionstopackages"]`` option to call PassOptionsToPackages * #2245: Add ``latex_elements["passoptionstopackages"]`` option to call PassOptionsToPackages
in early stage of preambles. in early stage of preambles.
* #2340: Math extension: support alignment of multiple equations for MathJAX. * #2340: Math extension: support alignment of multiple equations for MathJAX.
* #2338: Define ``\titlereference`` macro to redefine the style of ``title-reference`` roles. * #2338: Define ``\titleref`` macro to redefine the style of ``title-reference`` roles.
* Define ``\menuselection`` and ``\accelerator`` macros to redefine the style of `menuselection` roles. * Define ``\menuselection`` and ``\accelerator`` macros to redefine the style of `menuselection` roles.
* Define ``\internalreference`` macro to redefine the style of references * Define ``\crossref`` macro to redefine the style of references
* #2301: Texts in the classic html theme should be hyphenated.
* #2355: Define ``\termref`` macro to redefine the style of ``term`` roles.
* Add :confval:`suppress_warnings` to suppress arbitrary warning message (experimental)
* #2229: Fix no warning is given for unknown options
* #2327: Add `latex_toplevel_sectioning` to switch the top level sectioning of LaTeX document.
Bugs fixed Bugs fixed
---------- ----------
@ -28,6 +36,13 @@ Bugs fixed
* #2329: Refresh environment forcely if source directory has changed. * #2329: Refresh environment forcely if source directory has changed.
* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from xcolor package * #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from xcolor package
* Fix the confval type checker emits warnings if unicode is given to confvals which expects string value * Fix the confval type checker emits warnings if unicode is given to confvals which expects string value
* #2360: Fix numref in LaTeX output is broken
* #2361: Fix additional paragraphs inside the "compound" directive are indented
* #2364: Fix KeyError 'rootSymbol' on Sphinx upgrade from older version.
* #2348: Move amsmath and amssymb to before fontpkg on LaTeX writer.
* #2368: Ignore emacs lock files like ``.#foo.rst`` by default.
* #2262: literal_block and its caption has been separated by pagebreak in LaTeX output.
* #2319: Fix table counter is overrided by code-block's in LaTeX. Thanks to jfbu.
Documentation Documentation
------------- -------------
@ -154,6 +169,11 @@ Release 1.3.7 (in development)
Bugs fixed Bugs fixed
---------- ----------
* #2358: Fix user-preamble could not override the tocdepth definition.
* #2358: Redece tocdepth if ``part`` or ``chapter`` is used for top_sectionlevel.
* #2351: Fix footnote spacing
* #2363: Fix ``toctree()`` in templates generates broken links in SingleHTMLBuilder.
Release 1.3.6 (released Feb 29, 2016) Release 1.3.6 (released Feb 29, 2016)
===================================== =====================================

View File

@ -212,6 +212,26 @@ General configuration
.. versionadded:: 0.5 .. versionadded:: 0.5
.. confval:: suppress_warnings
A list of warning types to suppress arbitrary warning messages.
Sphinx supports following warning types:
* ref.term
* ref.ref
* ref.numref
* ref.keyword
* ref.option
* ref.citation
* ref.doc
You can choose from these types.
Now, this option should be considered *experimental*.
.. versionadded:: 1.4
.. confval:: needs_sphinx .. confval:: needs_sphinx
If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will
@ -1459,6 +1479,15 @@ These options influence LaTeX output.
configuration directory) that is the logo of the docs. It is placed at the configuration directory) that is the logo of the docs. It is placed at the
top of the title page. Default: ``None``. top of the title page. Default: ``None``.
.. 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
documentclass will be ``howto``, otherwise ``chapter`` will be used.
.. versionadded:: 1.4
.. confval:: latex_use_parts .. confval:: latex_use_parts
If true, the topmost sectioning unit is parts, else it is chapters. Default: If true, the topmost sectioning unit is parts, else it is chapters. Default:
@ -1466,6 +1495,9 @@ These options influence LaTeX output.
.. versionadded:: 0.3 .. versionadded:: 0.3
.. deprecated:: 1.4
Use :confval:`latex_toplevel_sectioning`.
.. confval:: latex_appendices .. confval:: latex_appendices
A list of document names to append as an appendix to all manuals. A list of document names to append as an appendix to all manuals.

View File

@ -223,11 +223,8 @@ The special document names (and pages generated for them) are:
.. rubric:: Footnotes .. rubric:: Footnotes
.. [#] The ``maxdepth`` option does not apply to the LaTeX writer, where the .. [#] The LaTeX writer only refers the ``maxdepth`` option of first toctree
whole table of contents will always be presented at the begin of the directive in the document.
document, and its depth is controlled by the ``tocdepth`` counter, which
you can reset in your :confval:`latex_preamble` config value using
e.g. ``\setcounter{tocdepth}{2}``.
.. [#] A note on available globbing syntax: you can use the standard shell .. [#] A note on available globbing syntax: you can use the standard shell
constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that

View File

@ -41,6 +41,7 @@ from sphinx.util import pycompat # noqa: imported for side-effects
from sphinx.util import import_object from sphinx.util import import_object
from sphinx.util.tags import Tags from sphinx.util.tags import Tags
from sphinx.util.osutil import ENOENT from sphinx.util.osutil import ENOENT
from sphinx.util.logging import is_suppressed_warning
from sphinx.util.console import bold, lightgray, darkgray, darkgreen, \ from sphinx.util.console import bold, lightgray, darkgray, darkgreen, \
term_width_line term_width_line
@ -318,7 +319,7 @@ class Sphinx(object):
wfile.flush() wfile.flush()
self.messagelog.append(message) self.messagelog.append(message)
def warn(self, message, location=None, prefix='WARNING: '): def warn(self, message, location=None, prefix='WARNING: ', type=None, subtype=None):
"""Emit a warning. """Emit a warning.
If *location* is given, it should either be a tuple of (docname, lineno) If *location* is given, it should either be a tuple of (docname, lineno)
@ -326,12 +327,17 @@ class Sphinx(object):
*prefix* usually should not be changed. *prefix* usually should not be changed.
*type* and *subtype* are used to suppress warnings with :confval:`suppress_warnings`.
.. note:: .. note::
For warnings emitted during parsing, you should use For warnings emitted during parsing, you should use
:meth:`.BuildEnvironment.warn` since that will collect all :meth:`.BuildEnvironment.warn` since that will collect all
warnings during parsing for later output. warnings during parsing for later output.
""" """
if is_suppressed_warning(type, subtype, self.config.suppress_warnings):
return
if isinstance(location, tuple): if isinstance(location, tuple):
docname, lineno = location docname, lineno = location
if docname: if docname:

View File

@ -260,12 +260,12 @@ class Builder(object):
# while reading, collect all warnings from docutils # while reading, collect all warnings from docutils
warnings = [] warnings = []
self.env.set_warnfunc(lambda *args: warnings.append(args)) self.env.set_warnfunc(lambda *args, **kwargs: warnings.append((args, kwargs)))
updated_docnames = set(self.env.update(self.config, self.srcdir, updated_docnames = set(self.env.update(self.config, self.srcdir,
self.doctreedir, self.app)) self.doctreedir, self.app))
self.env.set_warnfunc(self.warn) self.env.set_warnfunc(self.warn)
for warning in warnings: for warning, kwargs in warnings:
self.warn(*warning) self.warn(*warning, **kwargs)
doccount = len(updated_docnames) doccount = len(updated_docnames)
self.info(bold('looking for now-outdated files... '), nonl=1) self.info(bold('looking for now-outdated files... '), nonl=1)
@ -350,7 +350,7 @@ class Builder(object):
self.info('done') self.info('done')
warnings = [] warnings = []
self.env.set_warnfunc(lambda *args: warnings.append(args)) self.env.set_warnfunc(lambda *args, **kwargs: warnings.append((args, kwargs)))
if self.parallel_ok: if self.parallel_ok:
# number of subprocesses is parallel-1 because the main process # number of subprocesses is parallel-1 because the main process
# is busy loading doctrees and doing write_doc_serialized() # is busy loading doctrees and doing write_doc_serialized()
@ -366,13 +366,16 @@ class Builder(object):
doctree = self.env.get_and_resolve_doctree(docname, self) doctree = self.env.get_and_resolve_doctree(docname, self)
self.write_doc_serialized(docname, doctree) self.write_doc_serialized(docname, doctree)
self.write_doc(docname, doctree) self.write_doc(docname, doctree)
for warning in warnings: for warning, kwargs in warnings:
self.warn(*warning) self.warn(*warning, **kwargs)
def _write_parallel(self, docnames, warnings, nproc): def _write_parallel(self, docnames, warnings, nproc):
def write_process(docs): def write_process(docs):
local_warnings = [] local_warnings = []
self.env.set_warnfunc(lambda *args: local_warnings.append(args))
def warnfunc(*args, **kwargs):
local_warnings.append((args, kwargs))
self.env.set_warnfunc(warnfunc)
for docname, doctree in docs: for docname, doctree in docs:
self.write_doc(docname, doctree) self.write_doc(docname, doctree)
return local_warnings return local_warnings
@ -402,8 +405,8 @@ class Builder(object):
self.info(bold('waiting for workers...')) self.info(bold('waiting for workers...'))
tasks.join() tasks.join()
for warning in warnings: for warning, kwargs in warnings:
self.warn(*warning) self.warn(*warning, **kwargs)
def prepare_writing(self, docnames): def prepare_writing(self, docnames):
"""A place where you can add logic before :meth:`write_doc` is run""" """A place where you can add logic before :meth:`write_doc` is run"""

View File

@ -947,6 +947,13 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
if hashindex >= 0: if hashindex >= 0:
refnode['refuri'] = fname + refuri[hashindex:] refnode['refuri'] = fname + refuri[hashindex:]
def _get_local_toctree(self, docname, collapse=True, **kwds):
if 'includehidden' not in kwds:
kwds['includehidden'] = False
toctree = self.env.get_toctree_for(docname, self, collapse, **kwds)
self.fix_refuris(toctree)
return self.render_partial(toctree)['fragment']
def assemble_doctree(self): def assemble_doctree(self):
master = self.config.master_doc master = self.config.master_doc
tree = self.env.get_doctree(master) tree = self.env.get_doctree(master)

View File

@ -11,6 +11,7 @@
import os import os
from os import path from os import path
import warnings
from six import iteritems from six import iteritems
from docutils import nodes from docutils import nodes
@ -43,6 +44,21 @@ class LaTeXBuilder(Builder):
self.docnames = [] self.docnames = []
self.document_data = [] self.document_data = []
texescape.init() texescape.init()
self.check_options()
def check_options(self):
if self.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
self.warn('invalid latex_toplevel_sectioning, ignored: %s' %
self.config.latex_top_sectionlevel)
self.config.latex_top_sectionlevel = None
if self.config.latex_use_parts:
warnings.warn('latex_use_parts will be removed at Sphinx-1.5. '
'Use latex_toplevel_sectioning instead.',
DeprecationWarning)
if self.config.latex_toplevel_sectioning:
self.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')
def get_outdated_docs(self): def get_outdated_docs(self):
return 'all documents' # for now return 'all documents' # for now

View File

@ -76,6 +76,7 @@ class Config(object):
templates_path = ([], 'html'), templates_path = ([], 'html'),
template_bridge = (None, 'html', string_classes), template_bridge = (None, 'html', string_classes),
keep_warnings = (False, 'env'), keep_warnings = (False, 'env'),
suppress_warnings = ([], 'env'),
modindex_common_prefix = ([], 'html'), modindex_common_prefix = ([], 'html'),
rst_epilog = (None, 'env', string_classes), rst_epilog = (None, 'env', string_classes),
rst_prolog = (None, 'env', string_classes), rst_prolog = (None, 'env', string_classes),
@ -206,7 +207,9 @@ class Config(object):
None), None),
latex_logo = (None, None, string_classes), latex_logo = (None, None, string_classes),
latex_appendices = ([], None), latex_appendices = ([], None),
# now deprecated - use latex_toplevel_sectioning
latex_use_parts = (False, None), latex_use_parts = (False, None),
latex_toplevel_sectioning = (None, None, [str]),
latex_use_modindex = (True, None), # deprecated latex_use_modindex = (True, None), # deprecated
latex_domain_indices = (True, None, [list]), latex_domain_indices = (True, None, [list]),
latex_show_urls = ('no', None), latex_show_urls = ('no', None),

View File

@ -447,7 +447,7 @@ class StandardDomain(Domain):
'productionlist': ProductionList, 'productionlist': ProductionList,
} }
roles = { roles = {
'option': OptionXRefRole(), 'option': OptionXRefRole(warn_dangling=True),
'envvar': EnvVarXRefRole(), 'envvar': EnvVarXRefRole(),
# links to tokens in grammar productions # links to tokens in grammar productions
'token': XRefRole(), 'token': XRefRole(),
@ -485,6 +485,7 @@ class StandardDomain(Domain):
'the label must precede a section header)', 'the label must precede a section header)',
'numref': 'undefined label: %(target)s', 'numref': 'undefined label: %(target)s',
'keyword': 'unknown keyword: %(target)s', 'keyword': 'unknown keyword: %(target)s',
'option': 'unknown option: %(target)s',
} }
enumerable_nodes = { # node_class -> (figtype, title_getter) enumerable_nodes = { # node_class -> (figtype, title_getter)

View File

@ -75,7 +75,7 @@ default_settings = {
# or changed to properly invalidate pickle files. # or changed to properly invalidate pickle files.
# #
# NOTE: increase base version by 2 to have distinct numbers for Py2 and 3 # NOTE: increase base version by 2 to have distinct numbers for Py2 and 3
ENV_VERSION = 46 + (sys.version_info[0] - 2) ENV_VERSION = 47 + (sys.version_info[0] - 2)
dummy_reporter = Reporter('', 4, 4) dummy_reporter = Reporter('', 4, 4)
@ -242,7 +242,7 @@ class BuildEnvironment:
self.versioning_condition = condition self.versioning_condition = condition
self.versioning_compare = compare self.versioning_compare = compare
def warn(self, docname, msg, lineno=None): def warn(self, docname, msg, lineno=None, **kwargs):
"""Emit a warning. """Emit a warning.
This differs from using ``app.warn()`` in that the warning may not This differs from using ``app.warn()`` in that the warning may not
@ -250,11 +250,11 @@ class BuildEnvironment:
the update of the environment. the update of the environment.
""" """
# strange argument order is due to backwards compatibility # strange argument order is due to backwards compatibility
self._warnfunc(msg, (docname, lineno)) self._warnfunc(msg, (docname, lineno), **kwargs)
def warn_node(self, msg, node): def warn_node(self, msg, node, **kwargs):
"""Like :meth:`warn`, but with source information taken from *node*.""" """Like :meth:`warn`, but with source information taken from *node*."""
self._warnfunc(msg, '%s:%s' % get_source_line(node)) self._warnfunc(msg, '%s:%s' % get_source_line(node), **kwargs)
def clear_doc(self, docname): def clear_doc(self, docname):
"""Remove all traces of a source file in the inventory.""" """Remove all traces of a source file in the inventory."""
@ -391,7 +391,7 @@ class BuildEnvironment:
config.exclude_patterns[:] + config.exclude_patterns[:] +
config.templates_path + config.templates_path +
config.html_extra_path + config.html_extra_path +
['**/_sources', '.#*', '*.lproj/**'] ['**/_sources', '.#*', '**/.#*', '*.lproj/**']
) )
self.found_docs = set(get_matching_docs( self.found_docs = set(get_matching_docs(
self.srcdir, config.source_suffix, exclude_matchers=matchers)) self.srcdir, config.source_suffix, exclude_matchers=matchers))
@ -576,7 +576,7 @@ class BuildEnvironment:
def read_process(docs): def read_process(docs):
self.app = app self.app = app
self.warnings = [] self.warnings = []
self.set_warnfunc(lambda *args: self.warnings.append(args)) self.set_warnfunc(lambda *args, **kwargs: self.warnings.append((args, kwargs)))
for docname in docs: for docname in docs:
self.read_doc(docname, app) self.read_doc(docname, app)
# allow pickling self to send it back # allow pickling self to send it back
@ -603,8 +603,8 @@ class BuildEnvironment:
app.info(bold('waiting for workers...')) app.info(bold('waiting for workers...'))
tasks.join() tasks.join()
for warning in warnings: for warning, kwargs in warnings:
self._warnfunc(*warning) self._warnfunc(*warning, **kwargs)
def check_dependents(self, already): def check_dependents(self, already):
to_rewrite = self.assign_section_numbers() + self.assign_figure_numbers() to_rewrite = self.assign_section_numbers() + self.assign_figure_numbers()
@ -1540,7 +1540,7 @@ class BuildEnvironment:
(node['refdomain'], typ) (node['refdomain'], typ)
else: else:
msg = '%r reference target not found: %%(target)s' % typ msg = '%r reference target not found: %%(target)s' % typ
self.warn_node(msg % {'target': target}, node) self.warn_node(msg % {'target': target}, node, type='ref', subtype=typ)
def _resolve_doc_reference(self, builder, node, contnode): def _resolve_doc_reference(self, builder, node, contnode):
# directly reference to document by source name; # directly reference to document by source name;

View File

@ -214,11 +214,6 @@ def number_equations(app, doctree, docname):
node[0] = nodes.Text(num, num) node[0] = nodes.Text(num, num)
def setup_amsfont(app):
# use amsfonts if users do not configure latex_elements['amsfonts']
app.config.latex_elements.setdefault('amsfonts', r'\usepackage{amsfonts}')
def setup_math(app, htmlinlinevisitors, htmldisplayvisitors): def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
app.add_config_value('math_number_all', False, 'html') app.add_config_value('math_number_all', False, 'html')
app.add_node(math, override=True, app.add_node(math, override=True,
@ -243,4 +238,3 @@ def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
app.add_role('eq', eq_role) app.add_role('eq', eq_role)
app.add_directive('math', MathDirective) app.add_directive('math', MathDirective)
app.connect('doctree-resolved', number_equations) app.connect('doctree-resolved', number_equations)
app.connect('builder-inited', setup_amsfont)

View File

@ -14,8 +14,6 @@
\RequirePackage{fancybox} \RequirePackage{fancybox}
\RequirePackage{titlesec} \RequirePackage{titlesec}
\RequirePackage{tabulary} \RequirePackage{tabulary}
\RequirePackage{amsmath} % for \text
\RequirePackage{amssymb} % for some symbols
\RequirePackage{makeidx} \RequirePackage{makeidx}
\RequirePackage{framed} \RequirePackage{framed}
\RequirePackage{ifthen} \RequirePackage{ifthen}
@ -146,10 +144,13 @@
\newcommand{\bfcode}[1]{\code{\bfseries#1}} \newcommand{\bfcode}[1]{\code{\bfseries#1}}
\newcommand{\email}[1]{\textsf{#1}} \newcommand{\email}[1]{\textsf{#1}}
\newcommand{\tablecontinued}[1]{\textsf{#1}} \newcommand{\tablecontinued}[1]{\textsf{#1}}
\newcommand{\titlereference}[1]{\emph{#1}} \newcommand{\titleref}[1]{\emph{#1}}
\newcommand{\menuselection}[1]{\emph{#1}} \newcommand{\menuselection}[1]{\emph{#1}}
\newcommand{\accelerator}[1]{\underline{#1}} \newcommand{\accelerator}[1]{\underline{#1}}
\newcommand{\internalreference}[1]{\emph{#1}} \newcommand{\crossref}[1]{\emph{#1}}
\newcommand{\termref}[1]{\emph{#1}}
\newcommand*{\sphinxAtStartFootnote}{\mbox{ }}
% Redefine the Verbatim environment to allow border and background colors. % Redefine the Verbatim environment to allow border and background colors.
% The original environment is still used for verbatims within tables. % The original environment is still used for verbatims within tables.
@ -157,22 +158,96 @@
\let\endOriginalVerbatim=\endVerbatim \let\endOriginalVerbatim=\endVerbatim
% Play with vspace to be able to keep the indentation. % Play with vspace to be able to keep the indentation.
\newlength\distancetoright \newlength\Sphinx@scratchlength
\def\mycolorbox#1{% \newcommand\Sphinxcolorbox [1]{%
\setlength\distancetoright{\linewidth}% \setlength\Sphinx@scratchlength{\linewidth}%
\advance\distancetoright -\@totalleftmargin % \advance\Sphinx@scratchlength -\@totalleftmargin %
\fcolorbox{VerbatimBorderColor}{VerbatimColor}{% \fcolorbox{VerbatimBorderColor}{VerbatimColor}{%
\begin{minipage}{\distancetoright}% \begin{minipage}{\Sphinx@scratchlength}%
#1 #1
\end{minipage}% \end{minipage}%
}% }%
} }
\def\FrameCommand{\mycolorbox} % used for split frames for continuation on next and final page
\def\MidFrameCommand{\Sphinxcolorbox}
\let\LastFrameCommand\MidFrameCommand
% We customize \FrameCommand (for non split frames) and \FirstFrameCommand
% (split frames), in order for the framed environment to insert a Title above
% the frame, which can not be separated by a pagebreak.
% The title is specified from outside as macro \SphinxVerbatimTitle.
% \SphinxVerbatimTitle is reset to empty after each use of Verbatim environment.
% It is also possible to use directly framed environment (i.e. not indirectly
% via the Verbatim environment next), then it is \SphinxFrameTitle which specifies
% the title.
\newcommand*\SphinxFrameTitle {}
\newcommand*\SphinxVerbatimTitle {}
\newcommand*\SphinxSetupCaptionForVerbatim [2]
{%
\def\SphinxVerbatimTitle{\captionof{#1}{#2}\smallskip }%
}
% \SphinxCustomFBox is copied from framed.sty's \CustomFBox, but
% #1=title/caption is to be set _above_ the top rule, not _below_
% #1 must be "vertical material", it may be left empty.
% The amsmath patches \stepcounter to inhibit stepping under
% \firstchoice@false. We use it because framed.sty typesets multiple
% times its contents.
\newif\ifSphinx@myfirstframedpass
\long\def\SphinxCustomFBox#1#2#3#4#5#6#7{%
% we set up amsmath (amstext.sty) conditional to inhibit counter stepping
% except in first pass
\ifSphinx@myfirstframedpass\firstchoice@true
\else\firstchoice@false\fi
\leavevmode\begingroup
\setbox\@tempboxa\hbox{%
\color@begingroup
\kern\fboxsep{#7}\kern\fboxsep
\color@endgroup}%
\hbox{%
\lower\dimexpr#4+\fboxsep+\dp\@tempboxa\hbox{%
\vbox{%
#1% TITLE
\hrule\@height#3\relax
\hbox{%
\vrule\@width#5\relax
\vbox{%
\vskip\fboxsep
\copy\@tempboxa
\vskip\fboxsep}%
\vrule\@width#6\relax}%
#2%
\hrule\@height#4\relax}%
}%
}%
\endgroup
\global\Sphinx@myfirstframedpassfalse
}
% for non split frames:
\def\FrameCommand{%
% this is inspired from framed.sty v 0.96 2011/10/22 lines 185--190
% \fcolorbox (see \Sphinxcolorbox above) from color.sty uses \fbox.
\def\fbox{\SphinxCustomFBox{\SphinxFrameTitle}{}%
\fboxrule\fboxrule\fboxrule\fboxrule}%
% \fcolorbox from xcolor.sty may use rather \XC@fbox.
\let\XC@fbox\fbox
\Sphinxcolorbox
}
% for first portion of split frames:
\let\FirstFrameCommand\FrameCommand
\renewcommand{\Verbatim}[1][1]{% \renewcommand{\Verbatim}[1][1]{%
% list starts new par, but we don't want it to be set apart vertically % list starts new par, but we don't want it to be set apart vertically
\bgroup\parskip=0pt% \bgroup\parskip\z@skip
\smallskip% \smallskip
% use customized framed environment
\let\SphinxFrameTitle\SphinxVerbatimTitle
\global\Sphinx@myfirstframedpasstrue
% The list environement is needed to control perfectly the vertical % The list environement is needed to control perfectly the vertical
% space. % space.
\list{}{% \list{}{%
@ -183,15 +258,17 @@
\setlength\leftmargin{0pt}% \setlength\leftmargin{0pt}%
}% }%
\item\MakeFramed {\FrameRestore}% \item\MakeFramed {\FrameRestore}%
\small% \small
\OriginalVerbatim[#1]% \OriginalVerbatim[#1]%
} }
\renewcommand{\endVerbatim}{% \renewcommand{\endVerbatim}{%
\endOriginalVerbatim% \endOriginalVerbatim
\endMakeFramed% \endMakeFramed
\endlist% \endlist
% close group to restore \parskip % close group to restore \parskip (and \SphinxFrameTitle)
\egroup% \egroup
% reset to empty \SphinxVerbatimTitle
\global\let\SphinxVerbatimTitle\empty
} }
@ -448,6 +525,9 @@
% \capstart for figures that actually have a caption.) % \capstart for figures that actually have a caption.)
\RequirePackage{hypcap} \RequirePackage{hypcap}
% Set up styles of URL: it should be placed after hyperref
\urlstyle{same}
% From docutils.writers.latex2e % From docutils.writers.latex2e
% inline markup (custom roles) % inline markup (custom roles)
% \DUrole{#1}{#2} tries \DUrole#1{#2} % \DUrole{#1}{#2} tries \DUrole#1{#2}

View File

@ -189,6 +189,13 @@ div.genindex-jumpbox {
/* -- general body styles --------------------------------------------------- */ /* -- general body styles --------------------------------------------------- */
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink { a.headerlink {
visibility: hidden; visibility: hidden;
} }

29
sphinx/util/logging.py Normal file
View File

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
"""
sphinx.util.logging
~~~~~~~~~~~~~~~~~~~
Logging utility functions for Sphinx.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
def is_suppressed_warning(type, subtype, suppress_warnings):
"""Check the warning is suppressed or not."""
if type is None:
return False
for warning_type in suppress_warnings:
if '.' in warning_type:
target, subtarget = warning_type.split('.', 1)
else:
target, subtarget = warning_type, None
if target == type:
if (subtype is None or subtarget is None or
subtarget == subtype or subtarget == '*'):
return True
return False

View File

@ -39,7 +39,7 @@ HEADER = r'''%% Generated by Sphinx.
%(utf8extra)s %(utf8extra)s
%(cmappkg)s %(cmappkg)s
%(fontenc)s %(fontenc)s
%(amsfonts)s %(amsmath)s
%(babel)s %(babel)s
%(fontpkg)s %(fontpkg)s
%(fncychap)s %(fncychap)s
@ -51,6 +51,7 @@ HEADER = r'''%% Generated by Sphinx.
%(contentsname)s %(contentsname)s
%(numfig_format)s %(numfig_format)s
%(pageautorefname)s %(pageautorefname)s
%(tocdepth)s
%(preamble)s %(preamble)s
\title{%(title)s} \title{%(title)s}
@ -59,7 +60,6 @@ HEADER = r'''%% Generated by Sphinx.
\author{%(author)s} \author{%(author)s}
\newcommand{\sphinxlogo}{%(logo)s} \newcommand{\sphinxlogo}{%(logo)s}
\renewcommand{\releasename}{%(releasename)s} \renewcommand{\releasename}{%(releasename)s}
%(tocdepth)s
%(makeindex)s %(makeindex)s
''' '''
@ -279,7 +279,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
'\\else\\fi'), '\\else\\fi'),
'cmappkg': '\\usepackage{cmap}', 'cmappkg': '\\usepackage{cmap}',
'fontenc': '\\usepackage[T1]{fontenc}', 'fontenc': '\\usepackage[T1]{fontenc}',
'amsfonts': '', 'amsmath': '\\usepackage{amsmath,amssymb}',
'babel': '\\usepackage{babel}', 'babel': '\\usepackage{babel}',
'fontpkg': '\\usepackage{times}', 'fontpkg': '\\usepackage{times}',
'fncychap': '\\usepackage[Bjarne]{fncychap}', 'fncychap': '\\usepackage[Bjarne]{fncychap}',
@ -331,6 +331,19 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.remember_multirow = {} self.remember_multirow = {}
self.remember_multirowcol = {} self.remember_multirowcol = {}
# 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:
if builder.config.latex_use_parts:
self.top_sectionlevel = 0
else:
self.top_sectionlevel = 1
# sort out some elements # sort out some elements
papersize = builder.config.latex_paper_size + 'paper' papersize = builder.config.latex_paper_size + 'paper'
if papersize == 'paper': # e.g. command line "-D latex_paper_size=" if papersize == 'paper': # e.g. command line "-D latex_paper_size="
@ -399,12 +412,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.elements['classoptions'] += ',' + \ self.elements['classoptions'] += ',' + \
self.elements['extraclassoptions'] self.elements['extraclassoptions']
if document.get('tocdepth'): if document.get('tocdepth'):
if document.settings.docclass == 'howto': # redece tocdepth if `part` or `chapter` is used for top_sectionlevel
self.elements['tocdepth'] = ('\\setcounter{tocdepth}{%d}' % # tocdepth = -1: show only parts
document['tocdepth']) # tocdepth = 0: show parts and chapters
else: # tocdepth = 1: show parts, chapters and sections
self.elements['tocdepth'] = ('\\setcounter{tocdepth}{%d}' % # tocdepth = 2: show parts, chapters, sections and subsections
(document['tocdepth'] - 1)) # ...
self.elements['tocdepth'] = ('\\setcounter{tocdepth}{%d}' %
(document['tocdepth'] + self.top_sectionlevel - 2))
if getattr(document.settings, 'contentsname', None): if getattr(document.settings, 'contentsname', None):
self.elements['contentsname'] = \ self.elements['contentsname'] = \
self.babel_renewcommand('\\contentsname', document.settings.contentsname) self.babel_renewcommand('\\contentsname', document.settings.contentsname)
@ -432,13 +447,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.pending_footnotes = [] self.pending_footnotes = []
self.curfilestack = [] self.curfilestack = []
self.handled_abbrs = set() self.handled_abbrs = set()
if document.settings.docclass == 'howto':
self.top_sectionlevel = 2
else:
if builder.config.latex_use_parts:
self.top_sectionlevel = 0
else:
self.top_sectionlevel = 1
self.next_hyperlink_ids = {} self.next_hyperlink_ids = {}
self.next_section_ids = set() self.next_section_ids = set()
@ -925,9 +933,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_collected_footnote(self, node): def visit_collected_footnote(self, node):
self.in_footnote += 1 self.in_footnote += 1
if 'footnotetext' in node: if 'footnotetext' in node:
self.body.append('\\footnotetext[%s]{' % node['number']) self.body.append('\\footnotetext[%s]{\sphinxAtStartFootnote%%' % node['number'])
else: else:
self.body.append('\\footnote[%s]{' % node['number']) self.body.append('\\footnote[%s]{\sphinxAtStartFootnote%%' % node['number'])
def depart_collected_footnote(self, node): def depart_collected_footnote(self, node):
self.body.append('}') self.body.append('}')
@ -1267,7 +1275,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
depart_field_body = depart_definition depart_field_body = depart_definition
def visit_paragraph(self, node): def visit_paragraph(self, node):
self.body.append('\n') # insert blank line, if the paragraph follows a non-paragraph node in a compound
index = node.parent.index(node)
if (index > 0 and isinstance(node.parent, nodes.compound) and
not isinstance(node.parent[index - 1], nodes.paragraph) and
not isinstance(node.parent[index - 1], nodes.compound)):
self.body.append('\\noindent\n')
else:
self.body.append('\n')
def depart_paragraph(self, node): def depart_paragraph(self, node):
self.body.append('\n') self.body.append('\n')
@ -1419,8 +1434,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.in_caption += 1 self.in_caption += 1
if self.in_container_literal_block: if self.in_container_literal_block:
self.body.append('\\needspace{\\literalblockneedspace}') self.body.append('\\needspace{\\literalblockneedspace}')
self.body.append('\\vspace{\\literalblockcaptiontopvspace}') self.body.append('\\vspace{\\literalblockcaptiontopvspace}%')
self.body.append('\\captionof{literal-block}{') self.body.append('\n\\SphinxSetupCaptionForVerbatim{literal-block}{')
return return
self.body.append('\\caption{') self.body.append('\\caption{')
@ -1504,8 +1519,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
return return
else: else:
domain = self.builder.env.domains['std'] domain = self.builder.env.domains['std']
figtype = domain.get_figtype(node) figtype = domain.get_figtype(next)
if figtype and domain.get_numfig_title(node): if figtype and domain.get_numfig_title(next):
ids = set() ids = set()
# labels for figures go in the figure body, not before # labels for figures go in the figure body, not before
if node.get('refid'): if node.get('refid'):
@ -1584,8 +1599,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
if self.in_title or not uri: if self.in_title or not uri:
self.context.append('') self.context.append('')
elif uri.startswith(URI_SCHEMES): elif uri.startswith(URI_SCHEMES):
self.body.append('\\href{%s}{' % self.encode_uri(uri)) if len(node) == 1 and uri == node[0]:
self.context.append('}') self.body.append('\\url{%s}' % self.encode_uri(uri))
raise nodes.SkipNode
else:
self.body.append('\\href{%s}{' % self.encode_uri(uri))
self.context.append('}')
elif uri.startswith('#'): elif uri.startswith('#'):
# references to labels in the same document # references to labels in the same document
id = self.curfilestack[-1] + ':' + uri[1:] id = self.curfilestack[-1] + ':' + uri[1:]
@ -1606,12 +1625,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
# reference to a label # reference to a label
id = uri[1:].replace('#', ':') id = uri[1:].replace('#', ':')
self.body.append(self.hyperlink(id)) self.body.append(self.hyperlink(id))
self.body.append(r'\internalreference{')
if len(node) and hasattr(node[0], 'attributes') and \ if len(node) and hasattr(node[0], 'attributes') and \
'std-term' in node[0].get('classes', []): 'std-term' in node[0].get('classes', []):
# don't add a pageref for glossary terms # don't add a pageref for glossary terms
self.context.append('}}}') self.context.append('}}}')
# mark up as termreference
self.body.append(r'\termref{')
else: else:
self.body.append(r'\crossref{')
if self.builder.config.latex_show_pagerefs and not \ if self.builder.config.latex_show_pagerefs and not \
self.in_production_list: self.in_production_list:
self.context.append('}}} (%s)' % self.hyperpageref(id)) self.context.append('}}} (%s)' % self.hyperpageref(id))
@ -1699,7 +1720,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
return self.depart_literal_emphasis(node) return self.depart_literal_emphasis(node)
def visit_title_reference(self, node): def visit_title_reference(self, node):
self.body.append(r'\titlereference{') self.body.append(r'\titleref{')
def depart_title_reference(self, node): def depart_title_reference(self, node):
self.body.append('}') self.body.append('}')

View File

@ -203,6 +203,13 @@ class ManualPageTranslator(BaseTranslator):
def depart_versionmodified(self, node): def depart_versionmodified(self, node):
self.depart_paragraph(node) self.depart_paragraph(node)
# overwritten -- don't make whole of term bold if it includes strong node
def visit_term(self, node):
if node.traverse(nodes.strong):
self.body.append('\n')
else:
BaseTranslator.visit_term(self, node)
def visit_termsep(self, node): def visit_termsep(self, node):
warnings.warn('sphinx.addnodes.termsep will be removed at Sphinx-1.5', warnings.warn('sphinx.addnodes.termsep will be removed at Sphinx-1.5',
DeprecationWarning) DeprecationWarning)

View File

@ -12,7 +12,7 @@ import sys
import shutil import shutil
from io import open from io import open
from six import PY2, text_type from six import PY2, text_type, binary_type
FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding() FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
@ -143,7 +143,9 @@ class path(text_type):
Returns the text in the file. Returns the text in the file.
""" """
with open(self, mode='U', encoding=encoding, **kwargs) as f: with open(self, mode='U', encoding=encoding, **kwargs) as f:
return f.read() text = f.read()
contents = repr_as(text, '<%s contents>' % self.basename())
return contents
def bytes(self): def bytes(self):
""" """
@ -198,3 +200,18 @@ class path(text_type):
def __repr__(self): def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, text_type.__repr__(self)) return '%s(%s)' % (self.__class__.__name__, text_type.__repr__(self))
# Lives here only to avoid circular references; use it from util.py!
class _repr_text(text_type):
def __repr__(self):
return self._repr
class _repr_bin(binary_type):
def __repr__(self):
return self._repr
def repr_as(string, repr_):
wrapper = _repr_text if isinstance(string, text_type) else _repr_bin
proxy = wrapper(string)
proxy._repr = repr_
return proxy

View File

@ -52,3 +52,12 @@ y. y
#. z #. z
#. { #. {
definition lists
-----------------
term1
description
term2 (**stronged partially**)
description

View File

@ -40,6 +40,7 @@ HTML_WARNINGS = ENV_WARNINGS + """\
%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*' %(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*'
%(root)s/markup.txt:271: WARNING: Could not lex literal_block as "c". Highlighting skipped. %(root)s/markup.txt:271: WARNING: Could not lex literal_block as "c". Highlighting skipped.
%(root)s/footnote.txt:60: WARNING: citation not found: missing %(root)s/footnote.txt:60: WARNING: citation not found: missing
%(root)s/markup.txt:160: WARNING: unknown option: &option
""" """
if PY3: if PY3:

View File

@ -24,6 +24,7 @@ from test_build_html import ENV_WARNINGS
LATEX_WARNINGS = ENV_WARNINGS + """\ LATEX_WARNINGS = ENV_WARNINGS + """\
%(root)s/markup.txt:160: WARNING: unknown option: &option
%(root)s/footnote.txt:60: WARNING: citation not found: missing %(root)s/footnote.txt:60: WARNING: citation not found: missing
%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*' %(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*'
%(root)s/markup.txt:271: WARNING: Could not lex literal_block as "c". Highlighting skipped. %(root)s/markup.txt:271: WARNING: Could not lex literal_block as "c". Highlighting skipped.
@ -394,18 +395,18 @@ def test_footnote(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert '\\footnote[1]{\nnumbered\n}' in result assert '\\footnote[1]{\sphinxAtStartFootnote%\nnumbered\n}' in result
assert '\\footnote[2]{\nauto numbered\n}' in result assert '\\footnote[2]{\sphinxAtStartFootnote%\nauto numbered\n}' in result
assert '\\footnote[3]{\nnamed\n}' in result assert '\\footnote[3]{\sphinxAtStartFootnote%\nnamed\n}' in result
assert '{\\hyperref[footnote:bar]{\\internalreference{{[}bar{]}}}}' in result assert '{\\hyperref[footnote:bar]{\\crossref{{[}bar{]}}}}' in result
assert '\\bibitem[bar]{bar}{\\phantomsection\\label{footnote:bar} ' in result assert '\\bibitem[bar]{bar}{\\phantomsection\\label{footnote:bar} ' in result
assert '\\bibitem[bar]{bar}{\\phantomsection\\label{footnote:bar} \ncite' in result assert '\\bibitem[bar]{bar}{\\phantomsection\\label{footnote:bar} \ncite' in result
assert '\\bibitem[bar]{bar}{\\phantomsection\\label{footnote:bar} \ncite\n}' in result assert '\\bibitem[bar]{bar}{\\phantomsection\\label{footnote:bar} \ncite\n}' in result
assert '\\capstart\\caption{Table caption \\protect\\footnotemark[4]}' in result assert '\\capstart\\caption{Table caption \\protect\\footnotemark[4]}' in result
assert 'name \\protect\\footnotemark[5]' in result assert 'name \\protect\\footnotemark[5]' in result
assert ('\\end{threeparttable}\n\n' assert ('\\end{threeparttable}\n\n'
'\\footnotetext[4]{\nfootnotes in table caption\n}' '\\footnotetext[4]{\sphinxAtStartFootnote%\nfootnotes in table caption\n}'
'\\footnotetext[5]{\nfootnotes in table\n}' in result) '\\footnotetext[5]{\sphinxAtStartFootnote%\nfootnotes in table\n}' in result)
@with_app(buildername='latex', testroot='footnotes') @with_app(buildername='latex', testroot='footnotes')
@ -416,22 +417,24 @@ def test_reference_in_caption(app, status, warning):
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert ('\\caption{This is the figure caption with a reference to \\label{index:id2}' assert ('\\caption{This is the figure caption with a reference to \\label{index:id2}'
'{\\hyperref[index:authoryear]{\\internalreference{{[}AuthorYear{]}}}}.}' '{\\hyperref[index:authoryear]{\\crossref{{[}AuthorYear{]}}}}.}' in result)
in result)
assert '\\chapter{The section with a reference to {[}AuthorYear{]}}' in result assert '\\chapter{The section with a reference to {[}AuthorYear{]}}' in result
assert '\\caption{The table title with a reference to {[}AuthorYear{]}}' in result assert '\\caption{The table title with a reference to {[}AuthorYear{]}}' in result
assert '\\paragraph{The rubric title with a reference to {[}AuthorYear{]}}' in result assert '\\paragraph{The rubric title with a reference to {[}AuthorYear{]}}' in result
assert ('\\chapter{The section with a reference to \\protect\\footnotemark[4]}\n' assert ('\\chapter{The section with a reference to \\protect\\footnotemark[4]}\n'
'\\label{index:the-section-with-a-reference-to}' '\\label{index:the-section-with-a-reference-to}'
'\\footnotetext[4]{\nFootnote in section\n}' in result) '\\footnotetext[4]{\sphinxAtStartFootnote%\nFootnote in section\n}' in result)
assert ('\\caption{This is the figure caption with a footnote to ' assert ('\\caption{This is the figure caption with a footnote to '
'\\protect\\footnotemark[6].}\label{index:id23}\end{figure}\n' '\\protect\\footnotemark[6].}\label{index:id23}\end{figure}\n'
'\\footnotetext[6]{\nFootnote in caption\n}')in result '\\footnotetext[6]{\sphinxAtStartFootnote%\nFootnote in caption\n}')in result
assert ('\\caption{footnote \\protect\\footnotemark[7] ' assert ('\\caption{footnote \\protect\\footnotemark[7] '
'in caption of normal table}') in result 'in caption of normal table}') in result
assert '\\end{threeparttable}\n\n\\footnotetext[7]{\nFoot note in table\n}' in result assert ('\\end{threeparttable}\n\n\\footnotetext[7]{\sphinxAtStartFootnote%\n'
assert '\\caption{footnote \\protect\\footnotemark[8] in caption of longtable}' in result 'Foot note in table\n}' in result)
assert '\end{longtable}\n\n\\footnotetext[8]{\nFoot note in longtable\n}' in result assert ('\\caption{footnote \\protect\\footnotemark[8] in caption of longtable}'
in result)
assert ('\end{longtable}\n\n\\footnotetext[8]{\sphinxAtStartFootnote%\n'
'Foot note in longtable\n}' in result)
@with_app(buildername='latex', testroot='footnotes', @with_app(buildername='latex', testroot='footnotes',
@ -442,30 +445,31 @@ def test_latex_show_urls_is_inline(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert 'Same footnote number \\footnote[1]{\nfootnote in bar\n} in bar.rst' in result assert ('Same footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
assert 'Auto footnote number \\footnote[1]{\nfootnote in baz\n} in baz.rst' in result 'footnote in bar\n} in bar.rst' in result)
assert ('Auto footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
'footnote in baz\n} in baz.rst' in result)
assert ('\\phantomsection\\label{index:id26}{\\hyperref[index:the\\string-section' assert ('\\phantomsection\\label{index:id26}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]' '\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]'
'{\\internalreference{The section with a reference to \\phantomsection' '{\\crossref{The section with a reference to \\phantomsection\\label{index:id1}'
'\\label{index:id1}{\\hyperref[index:authoryear]{\\internalreference' '{\\hyperref[index:authoryear]{\\crossref{{[}AuthorYear{]}}}}}}}' in result)
'{{[}AuthorYear{]}}}}}}}' in result)
assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section' assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to]' '\\string-with\\string-a\\string-reference\\string-to]'
'{\\internalreference{The section with a reference to }}}' in result) '{\\crossref{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[2]{\nFirst\n}' in result assert 'First footnote: \\footnote[2]{\sphinxAtStartFootnote%\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\nSecond\n}' in result assert 'Second footnote: \\footnote[1]{\sphinxAtStartFootnote%\nSecond\n}' in result
assert '\\href{http://sphinx-doc.org/}{Sphinx} (http://sphinx-doc.org/)' in result assert '\\href{http://sphinx-doc.org/}{Sphinx} (http://sphinx-doc.org/)' in result
assert 'Third footnote: \\footnote[3]{\nThird\n}' in result assert 'Third footnote: \\footnote[3]{\sphinxAtStartFootnote%\nThird\n}' in result
assert ('\\href{http://sphinx-doc.org/~test/}{URL including tilde} ' assert ('\\href{http://sphinx-doc.org/~test/}{URL including tilde} '
'(http://sphinx-doc.org/\\textasciitilde{}test/)' in result) '(http://sphinx-doc.org/\\textasciitilde{}test/)' in result)
assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term} (http://sphinx-doc.org/)}] ' assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term} (http://sphinx-doc.org/)}] '
'\\leavevmode\nDescription' in result) '\\leavevmode\nDescription' in result)
assert ('\\item[{Footnote in term \\protect\\footnotemark[5]}] ' assert ('\\item[{Footnote in term \\protect\\footnotemark[5]}] '
'\\leavevmode\\footnotetext[5]{\nFootnote in term\n}\nDescription' in result) '\\leavevmode\\footnotetext[5]{\sphinxAtStartFootnote%\n'
'Footnote in term\n}\nDescription' in result)
assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist} ' assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist} '
'(http://sphinx-doc.org/)}] \\leavevmode\nDescription' in result) '(http://sphinx-doc.org/)}] \\leavevmode\nDescription' in result)
assert ('\\href{https://github.com/sphinx-doc/sphinx}' assert ('\\url{https://github.com/sphinx-doc/sphinx}\n' in result)
'{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\href{mailto:sphinx-dev@googlegroups.com}' assert ('\\href{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}' in result) '{sphinx-dev@googlegroups.com}' in result)
@ -478,32 +482,36 @@ def test_latex_show_urls_is_footnote(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert 'Same footnote number \\footnote[1]{\nfootnote in bar\n} in bar.rst' in result assert ('Same footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
assert 'Auto footnote number \\footnote[2]{\nfootnote in baz\n} in baz.rst' in result 'footnote in bar\n} in bar.rst' in result)
assert ('Auto footnote number \\footnote[2]{\sphinxAtStartFootnote%\n'
'footnote in baz\n} in baz.rst' in result)
assert ('\\phantomsection\\label{index:id26}{\\hyperref[index:the\\string-section' assert ('\\phantomsection\\label{index:id26}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]' '\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]'
'{\\internalreference{The section with a reference to \\phantomsection' '{\\crossref{The section with a reference to \\phantomsection\\label{index:id1}'
'\\label{index:id1}{\\hyperref[index:authoryear]{\\internalreference' '{\\hyperref[index:authoryear]{\\crossref{{[}AuthorYear{]}}}}}}}' in result)
'{{[}AuthorYear{]}}}}}}}' in result)
assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section' assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to]{\\internalreference' '\\string-with\\string-a\\string-reference\\string-to]'
'{The section with a reference to }}}' in result) '{\\crossref{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[3]{\nFirst\n}' in result assert 'First footnote: \\footnote[3]{\sphinxAtStartFootnote%\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\nSecond\n}' in result assert 'Second footnote: \\footnote[1]{\sphinxAtStartFootnote%\nSecond\n}' in result
assert ('\\href{http://sphinx-doc.org/}{Sphinx}' assert ('\\href{http://sphinx-doc.org/}{Sphinx}'
'\\footnote[4]{\nhttp://sphinx-doc.org/\n}' in result) '\\footnote[4]{\sphinxAtStartFootnote%\nhttp://sphinx-doc.org/\n}' in result)
assert 'Third footnote: \\footnote[6]{\nThird\n}' in result assert 'Third footnote: \\footnote[6]{\sphinxAtStartFootnote%\nThird\n}' in result
assert ('\\href{http://sphinx-doc.org/~test/}{URL including tilde}' assert ('\\href{http://sphinx-doc.org/~test/}{URL including tilde}'
'\\footnote[5]{\nhttp://sphinx-doc.org/\\textasciitilde{}test/\n}' in result) '\\footnote[5]{\sphinxAtStartFootnote%\n'
'http://sphinx-doc.org/\\textasciitilde{}test/\n}' in result)
assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term}\\protect\\footnotemark[8]}] ' assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term}\\protect\\footnotemark[8]}] '
'\\leavevmode\\footnotetext[8]{\nhttp://sphinx-doc.org/\n}\nDescription' in result) '\\leavevmode\\footnotetext[8]{\sphinxAtStartFootnote%\n'
'http://sphinx-doc.org/\n}\nDescription' in result)
assert ('\\item[{Footnote in term \\protect\\footnotemark[10]}] ' assert ('\\item[{Footnote in term \\protect\\footnotemark[10]}] '
'\\leavevmode\\footnotetext[10]{\nFootnote in term\n}\nDescription' in result) '\\leavevmode\\footnotetext[10]{\sphinxAtStartFootnote%\n'
'Footnote in term\n}\nDescription' in result)
assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist}\\protect' assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist}\\protect'
'\\footnotemark[9]}] ' '\\footnotemark[9]}] '
'\\leavevmode\\footnotetext[9]{\nhttp://sphinx-doc.org/\n}\nDescription' in result) '\\leavevmode\\footnotetext[9]{\sphinxAtStartFootnote%\n'
assert ('\\href{https://github.com/sphinx-doc/sphinx}' 'http://sphinx-doc.org/\n}\nDescription' in result)
'{https://github.com/sphinx-doc/sphinx}\n' in result) assert ('\\url{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\href{mailto:sphinx-dev@googlegroups.com}' assert ('\\href{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}\n' in result) '{sphinx-dev@googlegroups.com}\n' in result)
@ -516,29 +524,30 @@ def test_latex_show_urls_is_no(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert 'Same footnote number \\footnote[1]{\nfootnote in bar\n} in bar.rst' in result assert ('Same footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
assert 'Auto footnote number \\footnote[1]{\nfootnote in baz\n} in baz.rst' in result 'footnote in bar\n} in bar.rst' in result)
assert ('Auto footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
'footnote in baz\n} in baz.rst' in result)
assert ('\\phantomsection\\label{index:id26}{\\hyperref[index:the\\string-section' assert ('\\phantomsection\\label{index:id26}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]' '\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]'
'{\\internalreference{The section with a reference to \\phantomsection' '{\\crossref{The section with a reference to \\phantomsection\\label{index:id1}'
'\\label{index:id1}{\\hyperref[index:authoryear]{\\internalreference' '{\\hyperref[index:authoryear]{\\crossref{{[}AuthorYear{]}}}}}}}' in result)
'{{[}AuthorYear{]}}}}}}}' in result)
assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section' assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to]{\\internalreference' '\\string-with\\string-a\\string-reference\\string-to]'
'{The section with a reference to }}}' in result) '{\\crossref{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[2]{\nFirst\n}' in result assert 'First footnote: \\footnote[2]{\sphinxAtStartFootnote%\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\nSecond\n}' in result assert 'Second footnote: \\footnote[1]{\sphinxAtStartFootnote%\nSecond\n}' in result
assert '\\href{http://sphinx-doc.org/}{Sphinx}' in result assert '\\href{http://sphinx-doc.org/}{Sphinx}' in result
assert 'Third footnote: \\footnote[3]{\nThird\n}' in result assert 'Third footnote: \\footnote[3]{\sphinxAtStartFootnote%\nThird\n}' in result
assert '\\href{http://sphinx-doc.org/~test/}{URL including tilde}' in result assert '\\href{http://sphinx-doc.org/~test/}{URL including tilde}' in result
assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term}}] ' assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term}}] '
'\\leavevmode\nDescription' in result) '\\leavevmode\nDescription' in result)
assert ('\\item[{Footnote in term \\protect\\footnotemark[5]}] ' assert ('\\item[{Footnote in term \\protect\\footnotemark[5]}] '
'\\leavevmode\\footnotetext[5]{\nFootnote in term\n}\nDescription' in result) '\\leavevmode\\footnotetext[5]{\sphinxAtStartFootnote%\n'
'Footnote in term\n}\nDescription' in result)
assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist}}] ' assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist}}] '
'\\leavevmode\nDescription' in result) '\\leavevmode\nDescription' in result)
assert ('\\href{https://github.com/sphinx-doc/sphinx}' assert ('\\url{https://github.com/sphinx-doc/sphinx}\n' in result)
'{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\href{mailto:sphinx-dev@googlegroups.com}' assert ('\\href{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}\n' in result) '{sphinx-dev@googlegroups.com}\n' in result)
@ -615,3 +624,47 @@ def test_toctree_without_maxdepth(app, status, warning):
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert '\\setcounter{tocdepth}' not in result assert '\\setcounter{tocdepth}' not in result
@with_app(buildername='latex', testroot='toctree-maxdepth',
confoverrides={'latex_toplevel_sectioning': None})
def test_latex_toplevel_sectioning_is_None(app, status, warning):
app.builder.build_all()
result = (app.outdir / 'Python.tex').text(encoding='utf8')
print(result)
print(status.getvalue())
print(warning.getvalue())
assert '\\chapter{Foo}' in result
@with_app(buildername='latex', testroot='toctree-maxdepth',
confoverrides={'latex_toplevel_sectioning': 'part'})
def test_latex_toplevel_sectioning_is_part(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
@with_app(buildername='latex', testroot='toctree-maxdepth',
confoverrides={'latex_toplevel_sectioning': 'chapter'})
def test_latex_toplevel_sectioning_is_chapter(app, status, warning):
app.builder.build_all()
result = (app.outdir / 'Python.tex').text(encoding='utf8')
print(result)
print(status.getvalue())
print(warning.getvalue())
assert '\\chapter{Foo}' in result
@with_app(buildername='latex', testroot='toctree-maxdepth',
confoverrides={'latex_toplevel_sectioning': 'section'})
def test_latex_toplevel_sectioning_is_section(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

View File

@ -21,3 +21,7 @@ def test_all(app, status, warning):
content = (app.outdir / 'SphinxTests.1').text() content = (app.outdir / 'SphinxTests.1').text()
assert r'\fBprint \fP\fIi\fP\fB\en\fP' in content assert r'\fBprint \fP\fIi\fP\fB\en\fP' in content
assert r'\fBmanpage\en\fP' in content assert r'\fBmanpage\en\fP' in content
# term of definition list including nodes.strong
assert '\n.B term1\n' in content
assert '\nterm2 (\\fBstronged partially\\fP)\n' in content

View File

@ -23,6 +23,7 @@ from test_build_html import ENV_WARNINGS
TEXINFO_WARNINGS = ENV_WARNINGS + """\ TEXINFO_WARNINGS = ENV_WARNINGS + """\
%(root)s/markup.txt:160: WARNING: unknown option: &option
%(root)s/footnote.txt:60: WARNING: citation not found: missing %(root)s/footnote.txt:60: WARNING: citation not found: missing
%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*' %(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*'
%(root)s/images.txt:29: WARNING: no matching candidate for image URI u'svgimg.\\*' %(root)s/images.txt:29: WARNING: no matching candidate for image URI u'svgimg.\\*'

View File

@ -64,7 +64,7 @@ def test_code_block_caption_html(app, status, warning):
def test_code_block_caption_latex(app, status, warning): def test_code_block_caption_latex(app, status, warning):
app.builder.build_all() app.builder.build_all()
latex = (app.outdir / 'Python.tex').text(encoding='utf-8') latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
caption = '\\captionof{literal-block}{caption \\emph{test} rb}' caption = '\\SphinxSetupCaptionForVerbatim{literal-block}{caption \\emph{test} rb}'
assert caption in latex assert caption in latex
@ -229,7 +229,7 @@ def test_literalinclude_caption_html(app, status, warning):
def test_literalinclude_caption_latex(app, status, warning): def test_literalinclude_caption_latex(app, status, warning):
app.builder.build('index') app.builder.build('index')
latex = (app.outdir / 'Python.tex').text(encoding='utf-8') latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
caption = '\\captionof{literal-block}{caption \\textbf{test} py}' caption = '\\SphinxSetupCaptionForVerbatim{literal-block}{caption \\textbf{test} py}'
assert caption in latex assert caption in latex

View File

@ -24,7 +24,7 @@ from six import string_types
from util import tempdir, rootdir, path, gen_with_app, with_app, SkipTest, \ from util import tempdir, rootdir, path, gen_with_app, with_app, SkipTest, \
assert_re_search, assert_not_re_search, assert_in, assert_not_in, \ assert_re_search, assert_not_re_search, assert_in, assert_not_in, \
assert_startswith, assert_node assert_startswith, assert_node, repr_as
root = tempdir / 'test-intl' root = tempdir / 'test-intl'
@ -120,7 +120,7 @@ def test_text_builder(app, status, warning):
# --- warnings in translation # --- warnings in translation
warnings = warning.getvalue().replace(os.sep, '/') warnings = getwarning(warning)
warning_expr = u'.*/warnings.txt:4: ' \ warning_expr = u'.*/warnings.txt:4: ' \
u'WARNING: Inline literal start-string without end-string.\n' u'WARNING: Inline literal start-string without end-string.\n'
yield assert_re_search, warning_expr, warnings yield assert_re_search, warning_expr, warnings
@ -157,7 +157,7 @@ def test_text_builder(app, status, warning):
u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n") u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n")
yield assert_equal, result, expect yield assert_equal, result, expect
warnings = warning.getvalue().replace(os.sep, '/') warnings = getwarning(warning)
warning_fmt = u'.*/refs_inconsistency.txt:\\d+: ' \ warning_fmt = u'.*/refs_inconsistency.txt:\\d+: ' \
u'WARNING: inconsistent %s in translated message\n' u'WARNING: inconsistent %s in translated message\n'
expected_warning_expr = ( expected_warning_expr = (
@ -178,7 +178,7 @@ def test_text_builder(app, status, warning):
u"\n<SYSTEM MESSAGE:") u"\n<SYSTEM MESSAGE:")
yield assert_startswith, result, expect yield assert_startswith, result, expect
warnings = warning.getvalue().replace(os.sep, '/') warnings = getwarning(warning)
expected_warning_expr = u'.*/literalblock.txt:\\d+: ' \ expected_warning_expr = u'.*/literalblock.txt:\\d+: ' \
u'WARNING: Literal block expected; none found.' u'WARNING: Literal block expected; none found.'
yield assert_re_search, expected_warning_expr, warnings yield assert_re_search, expected_warning_expr, warnings
@ -210,7 +210,7 @@ def test_text_builder(app, status, warning):
u"\n THE CORRESPONDING GLOSSARY #2\n" u"\n THE CORRESPONDING GLOSSARY #2\n"
u"\nLINK TO *SOME NEW TERM*.\n") u"\nLINK TO *SOME NEW TERM*.\n")
yield assert_equal, result, expect yield assert_equal, result, expect
warnings = warning.getvalue().replace(os.sep, '/') warnings = getwarning(warning)
yield assert_not_in, 'term not in glossary', warnings yield assert_not_in, 'term not in glossary', warnings
# --- glossary term inconsistencies: regression test for #1090 # --- glossary term inconsistencies: regression test for #1090
@ -221,7 +221,7 @@ def test_text_builder(app, status, warning):
u"\n1. LINK TO *SOME NEW TERM*.\n") u"\n1. LINK TO *SOME NEW TERM*.\n")
yield assert_equal, result, expect yield assert_equal, result, expect
warnings = warning.getvalue().replace(os.sep, '/') warnings = getwarning(warning)
expected_warning_expr = ( expected_warning_expr = (
u'.*/glossary_terms_inconsistency.txt:\\d+: ' u'.*/glossary_terms_inconsistency.txt:\\d+: '
u'WARNING: inconsistent term references in translated message\n') u'WARNING: inconsistent term references in translated message\n')
@ -487,7 +487,7 @@ def test_xml_builder(app, status, warning):
None, None,
['ref']) ['ref'])
warnings = warning.getvalue().replace(os.sep, '/') warnings = getwarning(warning)
warning_expr = u'.*/footnote.xml:\\d*: SEVERE: Duplicate ID: ".*".\n' warning_expr = u'.*/footnote.xml:\\d*: SEVERE: Duplicate ID: ".*".\n'
yield assert_not_re_search, warning_expr, warnings yield assert_not_re_search, warning_expr, warnings
@ -618,7 +618,7 @@ def test_xml_builder(app, status, warning):
['same-type-links', 'i18n-role-xref']) ['same-type-links', 'i18n-role-xref'])
# warnings # warnings
warnings = warning.getvalue().replace(os.sep, '/') warnings = getwarning(warning)
yield assert_not_in, 'term not in glossary', warnings yield assert_not_in, 'term not in glossary', warnings
yield assert_not_in, 'undefined label', warnings yield assert_not_in, 'undefined label', warnings
yield assert_not_in, 'unknown document', warnings yield assert_not_in, 'unknown document', warnings
@ -880,3 +880,7 @@ def test_image_glob_intl_using_figure_language_filename(app, status, warning):
assert_node(doctree[0][3][0], nodes.image, uri='subdir/svgimg.*', assert_node(doctree[0][3][0], nodes.image, uri='subdir/svgimg.*',
candidates={'application/pdf': 'subdir/svgimg.pdf', candidates={'application/pdf': 'subdir/svgimg.pdf',
'image/svg+xml': 'subdir/svgimg.svg'}) 'image/svg+xml': 'subdir/svgimg.svg'})
def getwarning(warnings):
return repr_as(warnings.getvalue().replace(os.sep, '/'), '<warnings>')

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
test_util_logging
~~~~~~~~~~~~~~~~~
Test logging util.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
from sphinx.util.logging import is_suppressed_warning
def test_is_suppressed_warning():
suppress_warnings = ["ref", "files.*", "rest.duplicated_labels"]
assert is_suppressed_warning(None, None, suppress_warnings) is False
assert is_suppressed_warning("ref", None, suppress_warnings) is True
assert is_suppressed_warning("ref", "numref", suppress_warnings) is True
assert is_suppressed_warning("ref", "option", suppress_warnings) is True
assert is_suppressed_warning("files", "image", suppress_warnings) is True
assert is_suppressed_warning("files", "stylesheet", suppress_warnings) is True
assert is_suppressed_warning("rest", "syntax", suppress_warnings) is False
assert is_suppressed_warning("rest", "duplicated_labels", suppress_warnings) is True

View File

@ -26,7 +26,7 @@ from sphinx.theming import Theme
from sphinx.ext.autodoc import AutoDirective from sphinx.ext.autodoc import AutoDirective
from sphinx.pycode import ModuleAnalyzer from sphinx.pycode import ModuleAnalyzer
from path import path from path import path, repr_as
try: try:
# Python >=3.3 # Python >=3.3