Merge branch 'stable'

This commit is contained in:
Takeshi KOMIYA 2016-05-09 10:11:13 +09:00
commit c9296ba467
37 changed files with 425 additions and 78 deletions

41
CHANGES
View File

@ -27,11 +27,26 @@ Release 1.4.2 (in development)
Features added
--------------
* Now :confval:`suppress_warnings` accepts following configurations: ``app.add_node``, ``app.add_directive``, ``app.add_role`` and ``app.add_generic_role`` (ref: #2451)
* LaTeX writer allows page breaks in topic contents; and their horizontal
extent now fits in the line width (shadow in margin). Warning-type
admonitions allow page breaks (if very long) and their vertical spacing
has been made more coherent with the one for Hint-type notices.
* Now :confval:`suppress_warnings` accepts following configurations (ref: #2451, #2466):
- ``app.add_node``
- ``app.add_directive``
- ``app.add_role``
- ``app.add_generic_role``
- ``app.add_source_parser``
- ``image.data_uri``
- ``image.nonlocal_uri``
* #2453: LaTeX writer allows page breaks in topic contents; and their
horizontal extent now fits in the line width (with shadow in margin). Also
warning-type admonitions allow page breaks and their vertical spacing has
been made more coherent with the one for hint-type notices (ref #2446).
* #2459: the framing of literal code-blocks in LaTeX output (and not only the
code lines themselves) obey the indentation in lists or quoted blocks.
* #2343: the long source lines in code-blocks are wrapped (without modifying
the line numbering) in LaTeX output (ref #1534, #2304).
* Convert linkcheck builder to requests for better encoding handling
Bugs fixed
@ -45,6 +60,22 @@ Bugs fixed
* #2447: VerbatimBorderColor wrongly used also for captions of PDF
* #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders).
* #2446: latex(pdf) sets local tables of contents (or more generally topic nodes) in unbreakable boxes, causes overflow at bottom
* #2476: Omit MathJax markers if :nowrap: is given
* #2465: latex builder fails in case no caption option is provided to toctree directive
* Sphinx crashes if self referenced toctree found
* #2481: spelling mistake for mecab search splitter. Thanks to Naoki Sato.
* #2309: Fix could not refer "indirect hyperlink targets" by ref-role
* intersphinx fails if mapping URL contains any port
* #2088: intersphinx crashes if the mapping URL requires basic auth
* #2304: auto line breaks in latexpdf codeblocks
* #1534: Word wrap long lines in Latex verbatim blocks
* #2460: too much white space on top of captioned literal blocks in PDF output
* Show error reason when multiple math extensions are loaded (ref: #2499)
* #2483: any figure number was not assigned if figure title contains only non text objects
* #2501: Unicode subscript numbers are normalized in LaTeX
* #2492: Figure directive with :figwidth: generates incorrect Latex-code
* The caption of figure is always put on center even if ``:align:`` was specified
* #2526: LaTeX writer crashes if the section having only images
Release 1.4.1 (released Apr 12, 2016)

View File

@ -222,6 +222,9 @@ General configuration
* app.add_directive
* app.add_role
* app.add_generic_role
* app.add_source_parser
* image.data_uri
* image.nonlocal_uri
* ref.term
* ref.ref
* ref.numref

View File

@ -33,11 +33,14 @@ There are two kinds of test blocks:
* *code-output-style* blocks consist of an ordinary piece of Python code, and
optionally, a piece of output for that code.
The doctest extension provides four directives. The *group* argument is
interpreted as follows: if it is empty, the block is assigned to the group named
``default``. If it is ``*``, the block is assigned to all groups (including the
``default`` group). Otherwise, it must be a comma-separated list of group
names.
Directives
----------
The *group* argument below is interpreted as follows: if it is empty, the block
is assigned to the group named ``default``. If it is ``*``, the block is
assigned to all groups (including the ``default`` group). Otherwise, it must be
a comma-separated list of group names.
.. rst:directive:: .. testsetup:: [group]
@ -171,7 +174,10 @@ The following is an example for the usage of the directives. The test via
This parrot wouldn't voom if you put 3000 volts through it!
There are also these config values for customizing the doctest extension:
Configuration
-------------
The doctest extension uses the following configuration values:
.. confval:: doctest_default_flags

View File

@ -51,7 +51,7 @@ The third form provides your theme path dynamically to Sphinx if the
called ``sphinx_themes`` in your setup.py file and write a ``get_path`` function
that has to return the directory with themes in it::
// in your 'setup.py'
# 'setup.py'
setup(
...
@ -63,7 +63,7 @@ that has to return the directory with themes in it::
...
)
// in 'your_package.py'
# 'your_package.py'
from os import path
package_dir = path.abspath(path.dirname(__file__))

View File

@ -788,6 +788,11 @@ class Sphinx(object):
def add_source_parser(self, suffix, parser):
self.debug('[app] adding search source_parser: %r, %r', (suffix, parser))
if suffix in self._additional_source_parsers:
self.warn('while setting up extension %s: source_parser for %r is '
'already registered, it will be overridden' %
(self._setting_up_extension[-1], suffix),
type='app', subtype='add_source_parser')
self._additional_source_parsers[suffix] = parser

View File

@ -11,7 +11,7 @@
from __future__ import unicode_literals
from os import path, walk
from os import path, walk, getenv
from codecs import open
from time import time
from datetime import datetime, tzinfo, timedelta
@ -130,6 +130,12 @@ class I18nBuilder(Builder):
timestamp = time()
tzdelta = datetime.fromtimestamp(timestamp) - \
datetime.utcfromtimestamp(timestamp)
# set timestamp from SOURCE_DATE_EPOCH if set
# see https://reproducible-builds.org/specs/source-date-epoch/
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
if source_date_epoch is not None:
timestamp = float(source_date_epoch)
tzdelta = 0
class LocalTimeZone(tzinfo):

View File

@ -137,7 +137,7 @@ class LaTeXBuilder(Builder):
tree = self.env.get_doctree(indexfile)
contentsname = None
for toctree in tree.traverse(addnodes.toctree):
if toctree['caption']:
if 'caption' in toctree:
contentsname = toctree['caption']
break

View File

@ -10,7 +10,7 @@
"""
import re
from os import path, environ
from os import path, environ, getenv
import shlex
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
@ -19,8 +19,10 @@ from sphinx.errors import ConfigError
from sphinx.locale import l_
from sphinx.util.osutil import make_filename, cd
from sphinx.util.pycompat import execfile_, NoneType
from sphinx.util.i18n import format_date
nonascii_re = re.compile(br'[\x80-\xff]')
copyright_year_re = re.compile(r'^((\d{4}-)?)(\d{4})(?=[ ,])')
CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s"
if PY3:
@ -298,6 +300,15 @@ class Config(object):
self.setup = config.get('setup', None)
self.extensions = config.get('extensions', [])
# correct values of copyright year that are not coherent with
# the SOURCE_DATE_EPOCH environment variable (if set)
# See https://reproducible-builds.org/specs/source-date-epoch/
if getenv('SOURCE_DATE_EPOCH') is not None:
for k in ('copyright', 'epub_copyright'):
if k in config:
config[k] = copyright_year_re.sub('\g<1>%s' % format_date('%Y'),
config[k])
def check_types(self, warn):
# check all values for deviation from the default value's type, since
# that can result in TypeErrors all over the place

View File

@ -28,6 +28,10 @@ class Figure(images.Figure):
self.options['name'] = name
self.add_name(figure_node)
# fill lineno using image node
if figure_node.line is None and len(figure_node) == 2:
figure_node.line = figure_node[1].line
return [figure_node]

View File

@ -532,6 +532,9 @@ class StandardDomain(Domain):
if labelid is None:
continue
node = document.ids[labelid]
if node.tagname == 'target' and 'refid' in node: # indirect hyperlink targets
node = document.ids.get(node['refid'])
labelid = node['names'][0]
if name.isdigit() or 'refuri' in node or \
node.tagname.startswith('desc_'):
# ignore footnote labels, labels automatically generated from a
@ -545,7 +548,7 @@ class StandardDomain(Domain):
sectname = clean_astext(node[0]) # node[0] == title node
elif self.is_enumerable_node(node):
sectname = self.get_numfig_title(node)
if sectname is None:
if not sectname:
continue
elif node.traverse(addnodes.toctree):
n = node.traverse(addnodes.toctree)[0]

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 = 47 + (sys.version_info[0] - 2)
ENV_VERSION = 48 + (sys.version_info[0] - 2)
dummy_reporter = Reporter('', 4, 4)
@ -908,11 +908,13 @@ class BuildEnvironment:
node['candidates'] = candidates = {}
imguri = node['uri']
if imguri.startswith('data:'):
self.warn_node('image data URI found. some builders might not support', node)
self.warn_node('image data URI found. some builders might not support', node,
type='image', subtype='data_uri')
candidates['?'] = imguri
continue
elif imguri.find('://') != -1:
self.warn_node('nonlocal image URI found: %s' % imguri, node)
self.warn_node('nonlocal image URI found: %s' % imguri, node,
type='image', subtype='nonlocal_uri')
candidates['?'] = imguri
continue
rel_imgpath, full_imgpath = self.relfn2path(imguri, docname)
@ -1909,6 +1911,10 @@ class BuildEnvironment:
traversed = set()
def traverse_toctree(parent, docname):
if parent == docname:
self.warn(docname, 'self referenced toctree found. Ignored.')
return
# traverse toctree by pre-order
yield parent, docname
traversed.add(docname)

View File

@ -22,7 +22,7 @@ from six import text_type
from docutils import nodes
import sphinx
from sphinx.errors import SphinxError
from sphinx.errors import SphinxError, ExtensionError
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.osutil import ensuredir, ENOENT, cd
from sphinx.util.pycompat import sys_encoding
@ -267,7 +267,11 @@ def html_visit_displaymath(self, node):
def setup(app):
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.imgmath: other math package is already loaded')
app.add_config_value('imgmath_image_format', 'png', 'html')
app.add_config_value('imgmath_dvipng', 'dvipng', 'html')
app.add_config_value('imgmath_dvisvgm', 'dvisvgm', 'html')

View File

@ -150,7 +150,10 @@ def _strip_basic_auth(url):
password = url_parts.password
frags = list(url_parts)
# swap out "user[:pass]@hostname" for "hostname"
frags[1] = url_parts.hostname
if url_parts.port:
frags[1] = "%s:%s" % (url_parts.hostname, url_parts.port)
else:
frags[1] = url_parts.hostname
url = parse.urlunsplit(frags)
return (url, username, password)
@ -177,7 +180,7 @@ def _read_from_url(url):
password_mgr = request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, url, username, password)
handler = request.HTTPBasicAuthHandler(password_mgr)
opener = request.build_opener(default_handlers + [handler])
opener = request.build_opener(*(default_handlers + [handler]))
else:
opener = default_opener

View File

@ -56,7 +56,11 @@ def builder_inited(app):
def setup(app):
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.jsmath: other math package is already loaded')
app.add_config_value('jsmath_path', '', False)
app.connect('builder-inited', builder_inited)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -14,7 +14,7 @@
from docutils import nodes
import sphinx
from sphinx.application import ExtensionError
from sphinx.errors import ExtensionError
from sphinx.ext.mathbase import setup_math as mathbase_setup
@ -29,9 +29,7 @@ def html_visit_math(self, node):
def html_visit_displaymath(self, node):
self.body.append(self.starttag(node, 'div', CLASS='math'))
if node['nowrap']:
self.body.append(self.builder.config.mathjax_display[0] +
self.encode(node['latex']) +
self.builder.config.mathjax_display[1])
self.body.append(self.encode(node['latex']))
self.body.append('</div>')
raise nodes.SkipNode
@ -65,7 +63,11 @@ def builder_inited(app):
def setup(app):
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.mathjax: other math package is already loaded')
# more information for mathjax secure url is here:
# http://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
app.add_config_value('mathjax_path',
@ -74,4 +76,5 @@ def setup(app):
app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
app.connect('builder-inited', builder_inited)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -23,7 +23,7 @@ from six import text_type
from docutils import nodes
import sphinx
from sphinx.errors import SphinxError
from sphinx.errors import SphinxError, ExtensionError
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.osutil import ensuredir, ENOENT, cd
from sphinx.util.pycompat import sys_encoding
@ -239,7 +239,11 @@ def html_visit_displaymath(self, node):
def setup(app):
app.warn('sphinx.ext.pngmath has been deprecated. Please use sphinx.ext.imgmath instead.')
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.pngmath: other math package is already loaded')
app.add_config_value('pngmath_dvipng', 'dvipng', 'html')
app.add_config_value('pngmath_latex', 'latex', 'html')
app.add_config_value('pngmath_use_preview', False, 'html')

View File

@ -533,7 +533,7 @@ class SearchJapanese(SearchLanguage):
language_name = 'Japanese'
splitters = {
'default': 'sphinx.search.ja.DefaultSplitter',
'mecab': 'sphinx.sarch.ja.MecabSplitter',
'mecab': 'sphinx.search.ja.MecabSplitter',
'janome': 'sphinx.search.ja.JanomeSplitter',
}

View File

@ -8,12 +8,6 @@
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{sphinx}[2010/01/15 LaTeX package (Sphinx markup)]
\ifx\directlua\undefined\else
% if compiling with lualatex 0.85 or later load compatibility patch issued by
% the LaTeX team for older packages relying on \pdf<name> named primitives.
\IfFileExists{luatex85.sty}{\RequirePackage{luatex85}}{}
\fi
\@ifclassloaded{memoir}{}{\RequirePackage{fancyhdr}}
\RequirePackage{textcomp}
@ -166,12 +160,12 @@
\newcommand\Sphinx@colorbox [2]{%
% #1 will be \fcolorbox or, for first part of frame: \Sphinx@fcolorbox
#1{VerbatimBorderColor}{VerbatimColor}{%
% adjust width to be able to handle indentation.
\begin{minipage}{\dimexpr\linewidth-\@totalleftmargin\relax}%
#2%
\end{minipage}%
}%
% let the framing obey the current indentation (adapted from framed.sty's code).
\hskip\@totalleftmargin
\hskip-\fboxsep\hskip-\fboxrule
#1{VerbatimBorderColor}{VerbatimColor}{#2}%
\hskip-\fboxsep\hskip-\fboxrule
\hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth
}
% use of \color@b@x here is compatible with both xcolor.sty and color.sty
\def\Sphinx@fcolorbox #1#2%
@ -184,9 +178,11 @@
\newcommand*\SphinxLiteralBlockLabel {}
\newcommand*\SphinxSetupCaptionForVerbatim [2]
{%
\needspace{\literalblockneedspace}\vspace{\literalblockcaptiontopvspace}%
\needspace{\literalblockneedspace}%
% insert a \label via \SphinxLiteralBlockLabel
% reset to normal the color for the literal block caption
% the caption inserts \abovecaptionskip whitespace above itself (usually 10pt)
% there is also \belowcaptionskip but it is usually zero, hence the \smallskip
\def\SphinxVerbatimTitle
{\py@NormalColor\captionof{#1}{\SphinxLiteralBlockLabel #2}\smallskip }%
}
@ -198,12 +194,22 @@
\long\def\Sphinx@VerbatimFBox#1{%
\leavevmode
\begingroup
% framed.sty does some measuring but this macro adds possibly a caption
% use amsmath conditional to inhibit the caption counter stepping after
% first pass
\ifSphinx@myfirstframedpass\else\firstchoice@false\fi
\setbox\@tempboxa\hbox{\kern\fboxsep{#1}\kern\fboxsep}%
\hbox
{\lower\dimexpr\fboxrule+\fboxsep+\dp\@tempboxa
\hbox{%
\vbox{\ifx\SphinxVerbatimTitle\empty\else{\SphinxVerbatimTitle}\fi
\vbox{\ifx\SphinxVerbatimTitle\empty\else
% add the caption in a centered way above possibly indented frame
% hide its width from framed.sty's measuring step
% note that the caption brings \abovecaptionskip top vertical space
\moveright\dimexpr\fboxrule+.5\wd\@tempboxa
\hb@xt@\z@{\hss\begin{minipage}{\wd\@tempboxa}%
\SphinxVerbatimTitle
\end{minipage}\hss}\fi
\hrule\@height\fboxrule\relax
\hbox{\vrule\@width\fboxrule\relax
\vbox{\vskip\fboxsep\copy\@tempboxa\vskip\fboxsep}%
@ -211,16 +217,70 @@
\hrule\@height\fboxrule\relax}%
}}%
\endgroup
% amsmath conditional inhibits counter stepping after first pass.
\global\Sphinx@myfirstframedpassfalse
}
% For linebreaks inside Verbatim environment from package fancyvrb.
\newbox\Sphinxcontinuationbox
\newbox\Sphinxvisiblespacebox
% These are user customizable e.g. from latex_elements's preamble key.
% Use of \textvisiblespace for compatibility with XeTeX/LuaTeX/fontspec.
\newcommand*\Sphinxvisiblespace {\textcolor{red}{\textvisiblespace}}
\newcommand*\Sphinxcontinuationsymbol {\textcolor{red}{\llap{\tiny$\m@th\hookrightarrow$}}}
\newcommand*\Sphinxcontinuationindent {3ex }
\newcommand*\Sphinxafterbreak {\kern\Sphinxcontinuationindent\copy\Sphinxcontinuationbox}
% Take advantage of the already applied Pygments mark-up to insert
% potential linebreaks for TeX processing.
% {, <, #, %, $, ' and ": go to next line.
% _, }, ^, &, >, - and ~: stay at end of broken line.
% Use of \textquotesingle for straight quote.
\newcommand*\Sphinxbreaksatspecials {%
\def\PYGZus{\discretionary{\char`\_}{\Sphinxafterbreak}{\char`\_}}%
\def\PYGZob{\discretionary{}{\Sphinxafterbreak\char`\{}{\char`\{}}%
\def\PYGZcb{\discretionary{\char`\}}{\Sphinxafterbreak}{\char`\}}}%
\def\PYGZca{\discretionary{\char`\^}{\Sphinxafterbreak}{\char`\^}}%
\def\PYGZam{\discretionary{\char`\&}{\Sphinxafterbreak}{\char`\&}}%
\def\PYGZlt{\discretionary{}{\Sphinxafterbreak\char`\<}{\char`\<}}%
\def\PYGZgt{\discretionary{\char`\>}{\Sphinxafterbreak}{\char`\>}}%
\def\PYGZsh{\discretionary{}{\Sphinxafterbreak\char`\#}{\char`\#}}%
\def\PYGZpc{\discretionary{}{\Sphinxafterbreak\char`\%}{\char`\%}}%
\def\PYGZdl{\discretionary{}{\Sphinxafterbreak\char`\$}{\char`\$}}%
\def\PYGZhy{\discretionary{\char`\-}{\Sphinxafterbreak}{\char`\-}}%
\def\PYGZsq{\discretionary{}{\Sphinxafterbreak\textquotesingle}{\textquotesingle}}%
\def\PYGZdq{\discretionary{}{\Sphinxafterbreak\char`\"}{\char`\"}}%
\def\PYGZti{\discretionary{\char`\~}{\Sphinxafterbreak}{\char`\~}}%
}
% Some characters . , ; ? ! / are not pygmentized.
% This macro makes them "active" and they will insert potential linebreaks
\newcommand*\Sphinxbreaksatpunct {%
\lccode`\~`\.\lowercase{\def~}{\discretionary{\char`\.}{\Sphinxafterbreak}{\char`\.}}%
\lccode`\~`\,\lowercase{\def~}{\discretionary{\char`\,}{\Sphinxafterbreak}{\char`\,}}%
\lccode`\~`\;\lowercase{\def~}{\discretionary{\char`\;}{\Sphinxafterbreak}{\char`\;}}%
\lccode`\~`\:\lowercase{\def~}{\discretionary{\char`\:}{\Sphinxafterbreak}{\char`\:}}%
\lccode`\~`\?\lowercase{\def~}{\discretionary{\char`\?}{\Sphinxafterbreak}{\char`\?}}%
\lccode`\~`\!\lowercase{\def~}{\discretionary{\char`\!}{\Sphinxafterbreak}{\char`\!}}%
\lccode`\~`\/\lowercase{\def~}{\discretionary{\char`\/}{\Sphinxafterbreak}{\char`\/}}%
\catcode`\.\active
\catcode`\,\active
\catcode`\;\active
\catcode`\:\active
\catcode`\?\active
\catcode`\!\active
\catcode`\/\active
\lccode`\~`\~
}
\renewcommand{\Verbatim}[1][1]{%
% quit horizontal mode if we are still in a paragraph
\par
% list starts new par, but we don't want it to be set apart vertically
\parskip\z@skip
\smallskip
% first, let's check if there is a caption
\ifx\SphinxVerbatimTitle\empty
\addvspace\z@% counteract possible previous negative skip (French lists!)
\smallskip
% there was no caption. Check if nevertheless a label was set.
\ifx\SphinxLiteralBlockLabel\empty\else
% we require some space to be sure hyperlink target from \phantomsection
@ -238,8 +298,36 @@
% for mid pages and last page portion of (long) split frame:
\def\MidFrameCommand{\Sphinx@colorbox\fcolorbox }%
\let\LastFrameCommand\MidFrameCommand
% The list environement is needed to control perfectly the vertical
% space.
% fancyvrb's Verbatim puts each input line in (unbreakable) horizontal boxes.
% This customization wraps each line from the input in a \vtop, thus
% allowing it to wrap and display on two or more lines in the latex output.
% - The codeline counter will be increased only once.
% - The wrapped material will not break across pages, it is impossible
% to achieve this without extensive rewrite of fancyvrb.
% - The (not used in Sphinx) obeytabs option to Verbatim is
% broken by this change (showtabs and tabspace work).
\sbox\Sphinxcontinuationbox {\Sphinxcontinuationsymbol}%
\sbox\Sphinxvisiblespacebox {\FV@SetupFont\Sphinxvisiblespace}%
\def\FancyVerbFormatLine ##1{\hsize\linewidth
\vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@
\doublehyphendemerits\z@\finalhyphendemerits\z@
\strut ##1\strut}%
}%
% If the linebreak is at a space, the latter will be displayed as visible
% space at end of first line, and a continuation symbol starts next line.
% Stretch/shrink are however usually zero for typewriter font.
\def\FV@Space {%
\nobreak\hskip\z@ plus\fontdimen3\font minus\fontdimen4\font
\discretionary{\copy\Sphinxvisiblespacebox}{\Sphinxafterbreak}
{\kern\fontdimen2\font}%
}%
% Allow breaks at special characters using \PYG... macros.
\Sphinxbreaksatspecials
% The list environment is needed to control perfectly the vertical space.
% Note: \OuterFrameSep used by framed.sty is later set to \topsep hence 0pt.
% - if caption: vertical space above caption = (\abovecaptionskip + D) with
% D = \baselineskip-\FrameHeightAdjust, and then \smallskip above frame.
% - if no caption: (\smallskip + D) above frame. By default D=6pt.
\list{}{%
\setlength\parskip{0pt}%
\setlength\itemsep{0ex}%
@ -251,13 +339,18 @@
\item
% use a minipage if we are already inside a framed environment
\relax\ifSphinx@inframed\noindent\begin{\minipage}{\linewidth}\fi
\MakeFramed {\FrameRestore}%
\MakeFramed {% adapted over from framed.sty's snugshade environment
\advance\hsize-\width\@totalleftmargin\z@\linewidth\hsize
\@setminipage }%
\small
\OriginalVerbatim[#1]%
% For grid placement from \strut's in \FancyVerbFormatLine
\lineskip\z@skip
% Breaks at punctuation characters . , ; ? ! and / need catcode=\active
\OriginalVerbatim[#1,codes*=\Sphinxbreaksatpunct]%
}
\renewcommand{\endVerbatim}{%
\endOriginalVerbatim
\endMakeFramed
\par\unskip\@minipagefalse\endMakeFramed
\ifSphinx@inframed\end{minipage}\fi
\endlist
% LaTeX environments always revert local changes on exit, here e.g. \parskip
@ -344,6 +437,7 @@
\endtrivlist
}
% \moduleauthor{name}{email}
\newcommand{\moduleauthor}[2]{}
@ -456,8 +550,11 @@
{\parskip\z@skip\noindent}%
}
\newcommand{\py@endlightbox}{%
\par\nobreak
{\parskip\z@skip\noindent\rule[.4\baselineskip]{\linewidth}{0.5pt}}\par
\par
% counteract previous possible negative skip (French lists!):
% (we can't cancel that any earlier \vskip introduced a potential pagebreak)
\ifdim\lastskip<\z@\vskip-\lastskip\fi
\nobreak\vbox{\noindent\rule[.4\baselineskip]{\linewidth}{0.5pt}}\allowbreak
}
% Some are quite plain:
@ -721,8 +818,6 @@
% control caption around literal-block
\RequirePackage{capt-of}
\RequirePackage{needspace}
% if the left page space is less than \literalblockneedsapce, insert page-break
% if the left page space is less than \literalblockneedspace, insert page-break
\newcommand{\literalblockneedspace}{5\baselineskip}
\newcommand{\literalblockwithoutcaptionneedspace}{1.5\baselineskip}
% margin before the caption of literal-block
\newcommand{\literalblockcaptiontopvspace}{0.5\baselineskip}

View File

@ -5,6 +5,12 @@
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesClass{sphinxhowto}[2009/06/02 Document class (Sphinx HOWTO)]
\ifx\directlua\undefined\else
% if compiling with lualatex 0.85 or later load compatibility patch issued by
% the LaTeX team for older packages relying on \pdf<name> named primitives.
\IfFileExists{luatex85.sty}{\RequirePackage{luatex85}}{}
\fi
% 'oneside' option overriding the 'twoside' default
\newif\if@oneside
\DeclareOption{oneside}{\@onesidetrue}

View File

@ -5,6 +5,12 @@
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesClass{sphinxmanual}[2009/06/02 Document class (Sphinx manual)]
\ifx\directlua\undefined\else
% if compiling with lualatex 0.85 or later load compatibility patch issued by
% the LaTeX team for older packages relying on \pdf<name> named primitives.
\IfFileExists{luatex85.sty}{\RequirePackage{luatex85}}{}
\fi
% chapters starting at odd pages (overridden by 'openany' document option)
\PassOptionsToClass{openright}{\sphinxdocclass}

View File

@ -103,7 +103,8 @@ class Theme(object):
if name not in self.themes:
if name == 'sphinx_rtd_theme':
raise ThemeError('sphinx_rtd_theme is no longer a hard dependency '
'since version 1.4.0. Please install it manually.')
'since version 1.4.0. Please install it manually.'
'(pip install sphinx_rtd_theme)')
else:
raise ThemeError('no theme named %r found '
'(missing theme.conf?)' % name)

View File

@ -114,7 +114,7 @@ class AutoNumbering(Transform):
domain = self.document.settings.env.domains['std']
for node in self.document.traverse(nodes.Element):
if domain.is_enumerable_node(node) and domain.get_numfig_title(node):
if domain.is_enumerable_node(node) and domain.get_numfig_title(node) is not None:
self.document.note_implicit_target(node)

View File

@ -14,7 +14,6 @@ import os
import re
import warnings
from os import path
from time import gmtime
from datetime import datetime
from collections import namedtuple
@ -188,7 +187,7 @@ def format_date(format, date=None, language=None, warn=None):
# See https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal
source_date_epoch = os.getenv('SOURCE_DATE_EPOCH')
if source_date_epoch is not None:
date = gmtime(float(source_date_epoch))
date = datetime.utcfromtimestamp(float(source_date_epoch))
else:
date = datetime.now()

View File

@ -47,8 +47,26 @@ tex_replacements = [
('', r'\textbar{}'),
('', r'e'),
('', r'i'),
('', r'1'),
('', r'2'),
('', r'$^\text{0}$'),
('¹', r'$^\text{1}$'),
('²', r'$^\text{2}$'),
('³', r'$^\text{3}$'),
('', r'$^\text{4}$'),
('', r'$^\text{5}$'),
('', r'$^\text{6}$'),
('', r'$^\text{7}$'),
('', r'$^\text{8}$'),
('', r'$^\text{9}$'),
('', r'$_\text{0}$'),
('', r'$_\text{1}$'),
('', r'$_\text{2}$'),
('', r'$_\text{3}$'),
('', r'$_\text{4}$'),
('', r'$_\text{5}$'),
('', r'$_\text{6}$'),
('', r'$_\text{7}$'),
('', r'$_\text{8}$'),
('', r'$_\text{9}$'),
# map Greek alphabet
('α', r'\(\alpha\)'),
('β', r'\(\beta\)'),

View File

@ -278,7 +278,7 @@ class HTMLTranslator(BaseTranslator):
figtype = self.builder.env.domains['std'].get_figtype(node)
if figtype:
if len(node['ids']) == 0:
msg = 'Any IDs not assiend for %s node' % node.tagname
msg = 'Any IDs not assigned for %s node' % node.tagname
self.builder.env.warn_node(msg, node)
else:
append_fignumber(figtype, node['ids'][0])

View File

@ -263,6 +263,24 @@ class Table(object):
self.longtable = False
def width_to_latex_length(length_str):
"""Convert `length_str` with rst length to LaTeX length.
This function is copied from docutils' latex writer
"""
match = re.match('(\d*\.?\d*)\s*(\S*)', length_str)
if not match:
return length_str
value, unit = match.groups()[:2]
if unit in ('', 'pt'):
length_str = '%sbp' % value # convert to 'bp'
# percentage: relate to current line width
elif unit == '%':
length_str = '%.3f\\linewidth' % (float(value)/100.0)
return length_str
class LaTeXTranslator(nodes.NodeVisitor):
sectionnames = ["part", "chapter", "section", "subsection",
"subsubsection", "paragraph", "subparagraph"]
@ -281,7 +299,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
'\\else\\fi'),
'cmappkg': '\\usepackage{cmap}',
'fontenc': '\\usepackage[T1]{fontenc}',
'amsmath': '\\usepackage{amsmath,amssymb}',
'amsmath': '\\usepackage{amsmath,amssymb,amstext}',
'babel': '\\usepackage{babel}',
'fontpkg': '\\usepackage{times}',
'fncychap': '\\usepackage[Bjarne]{fncychap}',
@ -764,7 +782,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
elif isinstance(parent, nodes.section):
short = ''
if node.traverse(nodes.image):
short = '[%s]' % ' '.join(clean_astext(node).split()).translate(tex_escape_map)
short = ('[%s]' %
u' '.join(clean_astext(node).split()).translate(tex_escape_map))
try:
self.body.append(r'\%s%s{' % (self.sectionnames[self.sectionlevel], short))
@ -1406,10 +1425,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
isinstance(node.children[0], nodes.image) and
node.children[0]['ids']):
ids += self.hypertarget(node.children[0]['ids'][0], anchor=False)
if 'width' in node and node.get('align', '') in ('left', 'right'):
if node.get('align', '') in ('left', 'right'):
if 'width' in node:
length = width_to_latex_length(node['width'])
else:
length = '0pt'
self.body.append('\\begin{wrapfigure}{%s}{%s}\n\\centering' %
(node['align'] == 'right' and 'r' or 'l',
node['width']))
(node['align'] == 'right' and 'r' or 'l', length))
self.context.append(ids + '\\end{wrapfigure}\n')
elif self.in_minipage:
if ('align' not in node.attributes or

View File

@ -62,3 +62,7 @@ Test for issue #1700
:ref:`mastertoc`
Test for indirect hyperlink targets
===================================
:ref:`indirect hyperref <other-label>`

View File

@ -107,6 +107,9 @@ Admonitions
.. tip::
Tip text.
Indirect hyperlink targets
.. _other-label: some-label_
Inline markup
-------------
@ -142,6 +145,7 @@ Adding \n to test unescaping.
* :token:`try statement <try_stmt>`
* :ref:`admonition-section`
* :ref:`here <some-label>`
* :ref:`there <other-label>`
* :ref:`my-figure`
* :ref:`my-figure-name`
* :ref:`my-table`
@ -231,6 +235,16 @@ Figures
Description paragraph is wraped with legend node.
.. figure:: rimg.png
:align: right
figure with align option
.. figure:: rimg.png
:align: right
:figwidth: 50%
figure with align & figwidth option
Version markup
--------------

View File

@ -0,0 +1,3 @@
copyright = u'2006-2009, Author'

View File

@ -0,0 +1,4 @@
=================
test-correct-year
=================

View File

@ -16,3 +16,7 @@ another blah
Other [blah] |picture| section
------------------------------
other blah
|picture|
---------
blah blah blah

View File

@ -31,16 +31,16 @@ http://www.python.org/logo.png
reading included file u'.*?wrongenc.inc' seems to be wrong, try giving an \
:encoding: option\\n?
%(root)s/includes.txt:4: WARNING: download file not readable: .*?nonexisting.png
(%(root)s/markup.txt:359: WARNING: invalid single index entry u'')?
(%(root)s/markup.txt:373: WARNING: invalid single index entry u'')?
(%(root)s/undecodable.txt:3: WARNING: undecodable source characters, replacing \
with "\\?": b?'here: >>>(\\\\|/)xbb<<<'
)?"""
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/markup.txt:285: 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
%(root)s/markup.txt:164: WARNING: unknown option: &option
"""
if PY3:
@ -151,6 +151,8 @@ HTML_XPATH = {
"[@class='reference internal']/code/span[@class='pre']", '^with$'),
(".//a[@href='#grammar-token-try_stmt']"
"[@class='reference internal']/code/span", '^statement$'),
(".//a[@href='#some-label'][@class='reference internal']/span", '^here$'),
(".//a[@href='#some-label'][@class='reference internal']/span", '^there$'),
(".//a[@href='subdir/includes.html']"
"[@class='reference internal']/span", 'Including in subdir'),
(".//a[@href='objects.html#cmdoption-python-c']"
@ -274,6 +276,9 @@ HTML_XPATH = {
'http://sphinx-doc.org/'),
(".//a[@class='reference external'][@href='http://sphinx-doc.org/latest/']",
'Latest reference'),
# Indirect hyperlink targets across files
(".//a[@href='markup.html#some-label'][@class='reference internal']/span",
'^indirect hyperref$'),
],
'bom.html': [
(".//title", " File with UTF-8 BOM"),

View File

@ -24,10 +24,10 @@ from test_build_html import ENV_WARNINGS
LATEX_WARNINGS = ENV_WARNINGS + """\
%(root)s/markup.txt:160: WARNING: unknown option: &option
%(root)s/markup.txt:164: 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.
%(root)s/markup.txt:285: WARNING: Could not lex literal_block as "c". Highlighting skipped.
"""
if PY3:
@ -106,6 +106,20 @@ def test_latex(app, status, warning):
run_latex(app.outdir)
@with_app(buildername='latex')
def test_writer(app, status, warning):
app.builder.build_all()
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
assert ('\\begin{wrapfigure}{r}{0pt}\n\\centering\n'
'\\includegraphics{{rimg}.png}\n\\caption{figure with align option}'
'\\label{markup:id7}\\end{wrapfigure}' in result)
assert ('\\begin{wrapfigure}{r}{0.500\\linewidth}\n\\centering\n'
'\\includegraphics{{rimg}.png}\n\\caption{figure with align \\& figwidth option}'
'\\label{markup:id8}\\end{wrapfigure}' in result)
@with_app(buildername='latex', freshenv=True, # use freshenv to check warnings
confoverrides={'latex_documents': [
('contents', 'SphinxTests.tex', 'Sphinx Tests Documentation',

View File

@ -23,7 +23,7 @@ from test_build_html import ENV_WARNINGS
TEXINFO_WARNINGS = ENV_WARNINGS + """\
%(root)s/markup.txt:160: WARNING: unknown option: &option
%(root)s/markup.txt:164: 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

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
"""
test_correct_year
~~~~~~~~~~~~~~~~~
Test copyright year adjustment
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
from util import TestApp
def test_correct_year():
try:
# save current value of SOURCE_DATE_EPOCH
sde = os.environ.pop('SOURCE_DATE_EPOCH',None)
# test with SOURCE_DATE_EPOCH unset: no modification
app = TestApp(buildername='html',testroot='correct-year')
app.builder.build_all()
content = (app.outdir / 'contents.html').text()
app.cleanup()
assert '2006-2009' in content
# test with SOURCE_DATE_EPOCH set: copyright year should be
# updated
os.environ['SOURCE_DATE_EPOCH'] = "1293840000"
app = TestApp(buildername='html',testroot='correct-year')
app.builder.build_all()
content = (app.outdir / 'contents.html').text()
app.cleanup()
assert '2006-2011' in content
os.environ['SOURCE_DATE_EPOCH'] = "1293839999"
app = TestApp(buildername='html',testroot='correct-year')
app.builder.build_all()
content = (app.outdir / 'contents.html').text()
app.cleanup()
assert '2006-2010' in content
finally:
# Restores SOURCE_DATE_EPOCH
if sde == None:
os.environ.pop('SOURCE_DATE_EPOCH',None)
else:
os.environ['SOURCE_DATE_EPOCH'] = sde

View File

@ -24,7 +24,7 @@ def setup_module():
global app, env
app = TestApp(srcdir='root-envtest')
env = app.env
env.set_warnfunc(lambda *args: warnings.append(args))
env.set_warnfunc(lambda *args, **kwargs: warnings.append(args))
def teardown_module():

View File

@ -199,6 +199,16 @@ class TestStripBasicAuth(unittest.TestCase):
self.assertEqual(None, actual_username)
self.assertEqual(None, actual_password)
def test_having_port(self):
"""basic auth creds correctly stripped from URL containing creds even if URL
contains port"""
url = 'https://user:12345@domain.com:8080/project/objects.inv'
expected = 'https://domain.com:8080/project/objects.inv'
actual_url, actual_username, actual_password = _strip_basic_auth(url)
self.assertEqual(expected, actual_url)
self.assertEqual('user', actual_username)
self.assertEqual('12345', actual_password)
@mock.patch('six.moves.urllib.request.HTTPBasicAuthHandler')
@mock.patch('six.moves.urllib.request.HTTPPasswordMgrWithDefaultRealm')