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
--------------------
* #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
--------------
@ -13,9 +16,14 @@ Features added
* #2245: Add ``latex_elements["passoptionstopackages"]`` option to call PassOptionsToPackages
in early stage of preambles.
* #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 ``\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
----------
@ -28,6 +36,13 @@ Bugs fixed
* #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
* 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
-------------
@ -154,6 +169,11 @@ Release 1.3.7 (in development)
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)
=====================================

View File

@ -212,6 +212,26 @@ General configuration
.. 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
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
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
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
.. deprecated:: 1.4
Use :confval:`latex_toplevel_sectioning`.
.. confval:: latex_appendices
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
.. [#] The ``maxdepth`` option does not apply to the LaTeX writer, where the
whole table of contents will always be presented at the begin of the
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}``.
.. [#] The LaTeX writer only refers the ``maxdepth`` option of first toctree
directive in the document.
.. [#] A note on available globbing syntax: you can use the standard shell
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.tags import Tags
from sphinx.util.osutil import ENOENT
from sphinx.util.logging import is_suppressed_warning
from sphinx.util.console import bold, lightgray, darkgray, darkgreen, \
term_width_line
@ -318,7 +319,7 @@ class Sphinx(object):
wfile.flush()
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.
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.
*type* and *subtype* are used to suppress warnings with :confval:`suppress_warnings`.
.. note::
For warnings emitted during parsing, you should use
:meth:`.BuildEnvironment.warn` since that will collect all
warnings during parsing for later output.
"""
if is_suppressed_warning(type, subtype, self.config.suppress_warnings):
return
if isinstance(location, tuple):
docname, lineno = location
if docname:

View File

@ -260,12 +260,12 @@ class Builder(object):
# while reading, collect all warnings from docutils
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,
self.doctreedir, self.app))
self.env.set_warnfunc(self.warn)
for warning in warnings:
self.warn(*warning)
for warning, kwargs in warnings:
self.warn(*warning, **kwargs)
doccount = len(updated_docnames)
self.info(bold('looking for now-outdated files... '), nonl=1)
@ -350,7 +350,7 @@ class Builder(object):
self.info('done')
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:
# number of subprocesses is parallel-1 because the main process
# 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)
self.write_doc_serialized(docname, doctree)
self.write_doc(docname, doctree)
for warning in warnings:
self.warn(*warning)
for warning, kwargs in warnings:
self.warn(*warning, **kwargs)
def _write_parallel(self, docnames, warnings, nproc):
def write_process(docs):
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:
self.write_doc(docname, doctree)
return local_warnings
@ -402,8 +405,8 @@ class Builder(object):
self.info(bold('waiting for workers...'))
tasks.join()
for warning in warnings:
self.warn(*warning)
for warning, kwargs in warnings:
self.warn(*warning, **kwargs)
def prepare_writing(self, docnames):
"""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:
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):
master = self.config.master_doc
tree = self.env.get_doctree(master)

View File

@ -11,6 +11,7 @@
import os
from os import path
import warnings
from six import iteritems
from docutils import nodes
@ -43,6 +44,21 @@ class LaTeXBuilder(Builder):
self.docnames = []
self.document_data = []
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):
return 'all documents' # for now

View File

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

View File

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

View File

@ -75,7 +75,7 @@ default_settings = {
# or changed to properly invalidate pickle files.
#
# 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)
@ -242,7 +242,7 @@ class BuildEnvironment:
self.versioning_condition = condition
self.versioning_compare = compare
def warn(self, docname, msg, lineno=None):
def warn(self, docname, msg, lineno=None, **kwargs):
"""Emit a warning.
This differs from using ``app.warn()`` in that the warning may not
@ -250,11 +250,11 @@ class BuildEnvironment:
the update of the environment.
"""
# 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*."""
self._warnfunc(msg, '%s:%s' % get_source_line(node))
self._warnfunc(msg, '%s:%s' % get_source_line(node), **kwargs)
def clear_doc(self, docname):
"""Remove all traces of a source file in the inventory."""
@ -391,7 +391,7 @@ class BuildEnvironment:
config.exclude_patterns[:] +
config.templates_path +
config.html_extra_path +
['**/_sources', '.#*', '*.lproj/**']
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set(get_matching_docs(
self.srcdir, config.source_suffix, exclude_matchers=matchers))
@ -576,7 +576,7 @@ class BuildEnvironment:
def read_process(docs):
self.app = app
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:
self.read_doc(docname, app)
# allow pickling self to send it back
@ -603,8 +603,8 @@ class BuildEnvironment:
app.info(bold('waiting for workers...'))
tasks.join()
for warning in warnings:
self._warnfunc(*warning)
for warning, kwargs in warnings:
self._warnfunc(*warning, **kwargs)
def check_dependents(self, already):
to_rewrite = self.assign_section_numbers() + self.assign_figure_numbers()
@ -1540,7 +1540,7 @@ class BuildEnvironment:
(node['refdomain'], typ)
else:
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):
# 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)
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):
app.add_config_value('math_number_all', False, 'html')
app.add_node(math, override=True,
@ -243,4 +238,3 @@ def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
app.add_role('eq', eq_role)
app.add_directive('math', MathDirective)
app.connect('doctree-resolved', number_equations)
app.connect('builder-inited', setup_amsfont)

View File

@ -14,8 +14,6 @@
\RequirePackage{fancybox}
\RequirePackage{titlesec}
\RequirePackage{tabulary}
\RequirePackage{amsmath} % for \text
\RequirePackage{amssymb} % for some symbols
\RequirePackage{makeidx}
\RequirePackage{framed}
\RequirePackage{ifthen}
@ -146,10 +144,13 @@
\newcommand{\bfcode}[1]{\code{\bfseries#1}}
\newcommand{\email}[1]{\textsf{#1}}
\newcommand{\tablecontinued}[1]{\textsf{#1}}
\newcommand{\titlereference}[1]{\emph{#1}}
\newcommand{\titleref}[1]{\emph{#1}}
\newcommand{\menuselection}[1]{\emph{#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.
% The original environment is still used for verbatims within tables.
@ -157,22 +158,96 @@
\let\endOriginalVerbatim=\endVerbatim
% Play with vspace to be able to keep the indentation.
\newlength\distancetoright
\def\mycolorbox#1{%
\setlength\distancetoright{\linewidth}%
\advance\distancetoright -\@totalleftmargin %
\newlength\Sphinx@scratchlength
\newcommand\Sphinxcolorbox [1]{%
\setlength\Sphinx@scratchlength{\linewidth}%
\advance\Sphinx@scratchlength -\@totalleftmargin %
\fcolorbox{VerbatimBorderColor}{VerbatimColor}{%
\begin{minipage}{\distancetoright}%
\begin{minipage}{\Sphinx@scratchlength}%
#1
\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]{%
% list starts new par, but we don't want it to be set apart vertically
\bgroup\parskip=0pt%
\smallskip%
\bgroup\parskip\z@skip
\smallskip
% use customized framed environment
\let\SphinxFrameTitle\SphinxVerbatimTitle
\global\Sphinx@myfirstframedpasstrue
% The list environement is needed to control perfectly the vertical
% space.
\list{}{%
@ -183,15 +258,17 @@
\setlength\leftmargin{0pt}%
}%
\item\MakeFramed {\FrameRestore}%
\small%
\small
\OriginalVerbatim[#1]%
}
\renewcommand{\endVerbatim}{%
\endOriginalVerbatim%
\endMakeFramed%
\endlist%
% close group to restore \parskip
\egroup%
\endOriginalVerbatim
\endMakeFramed
\endlist
% close group to restore \parskip (and \SphinxFrameTitle)
\egroup
% reset to empty \SphinxVerbatimTitle
\global\let\SphinxVerbatimTitle\empty
}
@ -448,6 +525,9 @@
% \capstart for figures that actually have a caption.)
\RequirePackage{hypcap}
% Set up styles of URL: it should be placed after hyperref
\urlstyle{same}
% From docutils.writers.latex2e
% inline markup (custom roles)
% \DUrole{#1}{#2} tries \DUrole#1{#2}

View File

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

View File

@ -203,6 +203,13 @@ class ManualPageTranslator(BaseTranslator):
def depart_versionmodified(self, 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):
warnings.warn('sphinx.addnodes.termsep will be removed at Sphinx-1.5',
DeprecationWarning)

View File

@ -12,7 +12,7 @@ import sys
import shutil
from io import open
from six import PY2, text_type
from six import PY2, text_type, binary_type
FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
@ -143,7 +143,9 @@ class path(text_type):
Returns the text in the file.
"""
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):
"""
@ -198,3 +200,18 @@ class path(text_type):
def __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
#. {
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/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/markup.txt:160: WARNING: unknown option: &option
"""
if PY3:

View File

@ -24,6 +24,7 @@ from test_build_html import 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/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.
@ -394,18 +395,18 @@ def test_footnote(app, status, warning):
print(result)
print(status.getvalue())
print(warning.getvalue())
assert '\\footnote[1]{\nnumbered\n}' in result
assert '\\footnote[2]{\nauto numbered\n}' in result
assert '\\footnote[3]{\nnamed\n}' in result
assert '{\\hyperref[footnote:bar]{\\internalreference{{[}bar{]}}}}' in result
assert '\\footnote[1]{\sphinxAtStartFootnote%\nnumbered\n}' in result
assert '\\footnote[2]{\sphinxAtStartFootnote%\nauto numbered\n}' in result
assert '\\footnote[3]{\sphinxAtStartFootnote%\nnamed\n}' 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} \ncite' 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 'name \\protect\\footnotemark[5]' in result
assert ('\\end{threeparttable}\n\n'
'\\footnotetext[4]{\nfootnotes in table caption\n}'
'\\footnotetext[5]{\nfootnotes in table\n}' in result)
'\\footnotetext[4]{\sphinxAtStartFootnote%\nfootnotes in table caption\n}'
'\\footnotetext[5]{\sphinxAtStartFootnote%\nfootnotes in table\n}' in result)
@with_app(buildername='latex', testroot='footnotes')
@ -416,22 +417,24 @@ def test_reference_in_caption(app, status, warning):
print(status.getvalue())
print(warning.getvalue())
assert ('\\caption{This is the figure caption with a reference to \\label{index:id2}'
'{\\hyperref[index:authoryear]{\\internalreference{{[}AuthorYear{]}}}}.}'
in result)
'{\\hyperref[index:authoryear]{\\crossref{{[}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 '\\paragraph{The rubric title with a reference to {[}AuthorYear{]}}' in result
assert ('\\chapter{The section with a reference to \\protect\\footnotemark[4]}\n'
'\\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 '
'\\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] '
'in caption of normal table}') in result
assert '\\end{threeparttable}\n\n\\footnotetext[7]{\nFoot note in table\n}' in result
assert '\\caption{footnote \\protect\\footnotemark[8] in caption of longtable}' in result
assert '\end{longtable}\n\n\\footnotetext[8]{\nFoot note in longtable\n}' in result
assert ('\\end{threeparttable}\n\n\\footnotetext[7]{\sphinxAtStartFootnote%\n'
'Foot note in table\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',
@ -442,30 +445,31 @@ def test_latex_show_urls_is_inline(app, status, warning):
print(result)
print(status.getvalue())
print(warning.getvalue())
assert 'Same footnote number \\footnote[1]{\nfootnote in bar\n} in bar.rst' in result
assert 'Auto footnote number \\footnote[1]{\nfootnote in baz\n} in baz.rst' in result
assert ('Same footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
'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'
'\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]'
'{\\internalreference{The section with a reference to \\phantomsection'
'\\label{index:id1}{\\hyperref[index:authoryear]{\\internalreference'
'{{[}AuthorYear{]}}}}}}}' in result)
'{\\crossref{The section with a reference to \\phantomsection\\label{index:id1}'
'{\\hyperref[index:authoryear]{\\crossref{{[}AuthorYear{]}}}}}}}' in result)
assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to]'
'{\\internalreference{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[2]{\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\nSecond\n}' in result
'{\\crossref{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[2]{\sphinxAtStartFootnote%\nFirst\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 '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} '
'(http://sphinx-doc.org/\\textasciitilde{}test/)' in result)
assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term} (http://sphinx-doc.org/)}] '
'\\leavevmode\nDescription' in result)
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} '
'(http://sphinx-doc.org/)}] \\leavevmode\nDescription' in result)
assert ('\\href{https://github.com/sphinx-doc/sphinx}'
'{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}'
'{sphinx-dev@googlegroups.com}' in result)
@ -478,32 +482,36 @@ def test_latex_show_urls_is_footnote(app, status, warning):
print(result)
print(status.getvalue())
print(warning.getvalue())
assert 'Same footnote number \\footnote[1]{\nfootnote in bar\n} in bar.rst' in result
assert 'Auto footnote number \\footnote[2]{\nfootnote in baz\n} in baz.rst' in result
assert ('Same footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
'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'
'\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]'
'{\\internalreference{The section with a reference to \\phantomsection'
'\\label{index:id1}{\\hyperref[index:authoryear]{\\internalreference'
'{{[}AuthorYear{]}}}}}}}' in result)
'{\\crossref{The section with a reference to \\phantomsection\\label{index:id1}'
'{\\hyperref[index:authoryear]{\\crossref{{[}AuthorYear{]}}}}}}}' in result)
assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to]{\\internalreference'
'{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[3]{\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\nSecond\n}' in result
'\\string-with\\string-a\\string-reference\\string-to]'
'{\\crossref{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[3]{\sphinxAtStartFootnote%\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\sphinxAtStartFootnote%\nSecond\n}' in result
assert ('\\href{http://sphinx-doc.org/}{Sphinx}'
'\\footnote[4]{\nhttp://sphinx-doc.org/\n}' in result)
assert 'Third footnote: \\footnote[6]{\nThird\n}' in result
'\\footnote[4]{\sphinxAtStartFootnote%\nhttp://sphinx-doc.org/\n}' in result)
assert 'Third footnote: \\footnote[6]{\sphinxAtStartFootnote%\nThird\n}' in result
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]}] '
'\\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]}] '
'\\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'
'\\footnotemark[9]}] '
'\\leavevmode\\footnotetext[9]{\nhttp://sphinx-doc.org/\n}\nDescription' in result)
assert ('\\href{https://github.com/sphinx-doc/sphinx}'
'{https://github.com/sphinx-doc/sphinx}\n' in result)
'\\leavevmode\\footnotetext[9]{\sphinxAtStartFootnote%\n'
'http://sphinx-doc.org/\n}\nDescription' in result)
assert ('\\url{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\href{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}\n' in result)
@ -516,29 +524,30 @@ def test_latex_show_urls_is_no(app, status, warning):
print(result)
print(status.getvalue())
print(warning.getvalue())
assert 'Same footnote number \\footnote[1]{\nfootnote in bar\n} in bar.rst' in result
assert 'Auto footnote number \\footnote[1]{\nfootnote in baz\n} in baz.rst' in result
assert ('Same footnote number \\footnote[1]{\sphinxAtStartFootnote%\n'
'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'
'\\string-with\\string-a\\string-reference\\string-to\\string-authoryear]'
'{\\internalreference{The section with a reference to \\phantomsection'
'\\label{index:id1}{\\hyperref[index:authoryear]{\\internalreference'
'{{[}AuthorYear{]}}}}}}}' in result)
'{\\crossref{The section with a reference to \\phantomsection\\label{index:id1}'
'{\\hyperref[index:authoryear]{\\crossref{{[}AuthorYear{]}}}}}}}' in result)
assert ('\\phantomsection\\label{index:id27}{\\hyperref[index:the\\string-section'
'\\string-with\\string-a\\string-reference\\string-to]{\\internalreference'
'{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[2]{\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\nSecond\n}' in result
'\\string-with\\string-a\\string-reference\\string-to]'
'{\\crossref{The section with a reference to }}}' in result)
assert 'First footnote: \\footnote[2]{\sphinxAtStartFootnote%\nFirst\n}' in result
assert 'Second footnote: \\footnote[1]{\sphinxAtStartFootnote%\nSecond\n}' 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 ('\\item[{\\href{http://sphinx-doc.org/}{URL in term}}] '
'\\leavevmode\nDescription' in result)
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}}] '
'\\leavevmode\nDescription' in result)
assert ('\\href{https://github.com/sphinx-doc/sphinx}'
'{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}'
'{sphinx-dev@googlegroups.com}\n' in result)
@ -615,3 +624,47 @@ def test_toctree_without_maxdepth(app, status, warning):
print(status.getvalue())
print(warning.getvalue())
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()
assert r'\fBprint \fP\fIi\fP\fB\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 + """\
%(root)s/markup.txt:160: WARNING: unknown option: &option
%(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: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):
app.builder.build_all()
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
@ -229,7 +229,7 @@ def test_literalinclude_caption_html(app, status, warning):
def test_literalinclude_caption_latex(app, status, warning):
app.builder.build('index')
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

View File

@ -24,7 +24,7 @@ from six import string_types
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_startswith, assert_node
assert_startswith, assert_node, repr_as
root = tempdir / 'test-intl'
@ -120,7 +120,7 @@ def test_text_builder(app, status, warning):
# --- warnings in translation
warnings = warning.getvalue().replace(os.sep, '/')
warnings = getwarning(warning)
warning_expr = u'.*/warnings.txt:4: ' \
u'WARNING: Inline literal start-string without end-string.\n'
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")
yield assert_equal, result, expect
warnings = warning.getvalue().replace(os.sep, '/')
warnings = getwarning(warning)
warning_fmt = u'.*/refs_inconsistency.txt:\\d+: ' \
u'WARNING: inconsistent %s in translated message\n'
expected_warning_expr = (
@ -178,7 +178,7 @@ def test_text_builder(app, status, warning):
u"\n<SYSTEM MESSAGE:")
yield assert_startswith, result, expect
warnings = warning.getvalue().replace(os.sep, '/')
warnings = getwarning(warning)
expected_warning_expr = u'.*/literalblock.txt:\\d+: ' \
u'WARNING: Literal block expected; none found.'
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"\nLINK TO *SOME NEW TERM*.\n")
yield assert_equal, result, expect
warnings = warning.getvalue().replace(os.sep, '/')
warnings = getwarning(warning)
yield assert_not_in, 'term not in glossary', warnings
# --- 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")
yield assert_equal, result, expect
warnings = warning.getvalue().replace(os.sep, '/')
warnings = getwarning(warning)
expected_warning_expr = (
u'.*/glossary_terms_inconsistency.txt:\\d+: '
u'WARNING: inconsistent term references in translated message\n')
@ -487,7 +487,7 @@ def test_xml_builder(app, status, warning):
None,
['ref'])
warnings = warning.getvalue().replace(os.sep, '/')
warnings = getwarning(warning)
warning_expr = u'.*/footnote.xml:\\d*: SEVERE: Duplicate ID: ".*".\n'
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'])
# warnings
warnings = warning.getvalue().replace(os.sep, '/')
warnings = getwarning(warning)
yield assert_not_in, 'term not in glossary', warnings
yield assert_not_in, 'undefined label', 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.*',
candidates={'application/pdf': 'subdir/svgimg.pdf',
'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.pycode import ModuleAnalyzer
from path import path
from path import path, repr_as
try:
# Python >=3.3