mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-08-09 12:38:07 -05:00
Merge branch 'stable'
This commit is contained in:
@@ -25,13 +25,31 @@ Documentation
|
||||
-------------
|
||||
|
||||
|
||||
Release 1.4.3 (in development)
|
||||
Release 1.4.4 (in development)
|
||||
==============================
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
|
||||
Release 1.4.3 (released Jun 5, 2016)
|
||||
====================================
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #2530: got "Counter too large" error on building PDF if large numbered footnotes existed in admonitions
|
||||
* ``width`` option of figure directive does not work if ``align`` option specified at same time (ref: #2595)
|
||||
* #2590: The ``inputenc`` package breaks compiling under lualatex and xelatex
|
||||
* #2540: date on latex front page use different font
|
||||
* Suppress "document isn't included in any toctree" warning if the document is included (ref: #2603)
|
||||
* #2614: Some tables in PDF output will end up shifted if user sets non zero \parindent in preamble
|
||||
* #2602: URL redirection breaks the hyperlinks generated by `sphinx.ext.intersphinx`
|
||||
* #2613: Show warnings if merged extensions are loaded
|
||||
* #2619: make sure amstext LaTeX package always loaded (ref: d657225, 488ee52, 9d82cad and #2615)
|
||||
* #2593: latex crashes if any figures in the table
|
||||
|
||||
|
||||
Release 1.4.2 (released May 29, 2016)
|
||||
=====================================
|
||||
|
||||
|
||||
@@ -33,12 +33,15 @@ all: clean-pyc clean-backupfiles style-check test
|
||||
style-check:
|
||||
@$(PYTHON) utils/check_sources.py $(DONT_CHECK) .
|
||||
|
||||
clean: clean-pyc clean-patchfiles clean-backupfiles clean-generated
|
||||
clean: clean-pyc clean-pycache clean-patchfiles clean-backupfiles clean-generated clean-testfiles
|
||||
|
||||
clean-pyc:
|
||||
find . -name '*.pyc' -exec rm -f {} +
|
||||
find . -name '*.pyo' -exec rm -f {} +
|
||||
|
||||
clean-pycache:
|
||||
find . -name __pycache__ -exec rm -rf {} +
|
||||
|
||||
clean-patchfiles:
|
||||
find . -name '*.orig' -exec rm -f {} +
|
||||
find . -name '*.rej' -exec rm -f {} +
|
||||
@@ -50,6 +53,10 @@ clean-backupfiles:
|
||||
clean-generated:
|
||||
rm -f utils/*3.py*
|
||||
|
||||
clean-testfiles:
|
||||
rm -rf tests/build
|
||||
rm -rf .tox/
|
||||
|
||||
pylint:
|
||||
@pylint --rcfile utils/pylintrc sphinx
|
||||
|
||||
|
||||
+1
-1
@@ -1627,7 +1627,7 @@ These options influence LaTeX output.
|
||||
``'\\usepackage[utf8]{inputenc}'`` when using pdflatex.
|
||||
Otherwise unset.
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
.. versionchanged:: 1.4.3
|
||||
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
||||
compilers.
|
||||
``'cmappkg'``
|
||||
|
||||
@@ -69,6 +69,10 @@ events = {
|
||||
CONFIG_FILENAME = 'conf.py'
|
||||
ENV_PICKLE_FILENAME = 'environment.pickle'
|
||||
|
||||
# list of deprecated extensions. Keys are extension name.
|
||||
# Values are Sphinx version that merge the extension.
|
||||
EXTENSION_BLACKLIST = {"sphinxjp.themecore": "1.2"}
|
||||
|
||||
|
||||
class Sphinx(object):
|
||||
|
||||
@@ -460,6 +464,11 @@ class Sphinx(object):
|
||||
self.debug('[app] setting up extension: %r', extension)
|
||||
if extension in self._extensions:
|
||||
return
|
||||
if extension in EXTENSION_BLACKLIST:
|
||||
self.warn('the extension %r was already merged with Sphinx since version %s; '
|
||||
'this extension is ignored.' % (
|
||||
extension, EXTENSION_BLACKLIST[extension]))
|
||||
return
|
||||
self._setting_up_extension.append(extension)
|
||||
try:
|
||||
mod = __import__(extension, None, None, ['setup'])
|
||||
|
||||
@@ -405,6 +405,7 @@ class Include(BaseInclude):
|
||||
return BaseInclude.run(self)
|
||||
rel_filename, filename = env.relfn2path(self.arguments[0])
|
||||
self.arguments[0] = filename
|
||||
env.note_included(filename)
|
||||
return BaseInclude.run(self)
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import types
|
||||
import bisect
|
||||
import codecs
|
||||
import string
|
||||
import fnmatch
|
||||
import unicodedata
|
||||
from os import path
|
||||
from glob import glob
|
||||
@@ -169,6 +170,7 @@ class BuildEnvironment:
|
||||
# contains all read docnames
|
||||
self.dependencies = {} # docname -> set of dependent file
|
||||
# names, relative to documentation root
|
||||
self.included = set() # docnames included from other documents
|
||||
self.reread_always = set() # docnames to re-read unconditionally on
|
||||
# next build
|
||||
|
||||
@@ -328,6 +330,20 @@ class BuildEnvironment:
|
||||
domain.merge_domaindata(docnames, other.domaindata[domainname])
|
||||
app.emit('env-merge-info', self, docnames, other)
|
||||
|
||||
def path2doc(self, filename):
|
||||
"""Return the docname for the filename if the file is document.
|
||||
|
||||
*filename* should be absolute or relative to the source directory.
|
||||
"""
|
||||
if filename.startswith(self.srcdir):
|
||||
filename = filename[len(self.srcdir) + 1:]
|
||||
for suffix in self.config.source_suffix:
|
||||
if fnmatch.fnmatch(filename, '*' + suffix):
|
||||
return filename[:-len(suffix)]
|
||||
else:
|
||||
# the file does not have docname
|
||||
return None
|
||||
|
||||
def doc2path(self, docname, base=True, suffix=None):
|
||||
"""Return the filename for the document name.
|
||||
|
||||
@@ -820,6 +836,15 @@ class BuildEnvironment:
|
||||
"""
|
||||
self.dependencies.setdefault(self.docname, set()).add(filename)
|
||||
|
||||
def note_included(self, filename):
|
||||
"""Add *filename* as a included from other document.
|
||||
|
||||
This means the document is not orphaned.
|
||||
|
||||
*filename* should be absolute or relative to the source directory.
|
||||
"""
|
||||
self.included.add(self.path2doc(filename))
|
||||
|
||||
def note_reread(self):
|
||||
"""Add the current document to the list of documents that will
|
||||
automatically be re-read at the next build.
|
||||
@@ -1931,6 +1956,9 @@ class BuildEnvironment:
|
||||
if docname == self.config.master_doc:
|
||||
# the master file is not included anywhere ;)
|
||||
continue
|
||||
if docname in self.included:
|
||||
# the document is included from other documents
|
||||
continue
|
||||
if 'orphan' in self.metadata[docname]:
|
||||
continue
|
||||
self.warn(docname, 'document isn\'t included in any toctree')
|
||||
|
||||
@@ -237,6 +237,13 @@ def fetch_inventory(app, uri, inv):
|
||||
'%s: %s' % (inv, err.__class__, err))
|
||||
return
|
||||
try:
|
||||
if hasattr(f, 'geturl'):
|
||||
newuri = f.geturl()
|
||||
if newuri.endswith("/" + INVENTORY_FILENAME):
|
||||
newuri = newuri[:-len(INVENTORY_FILENAME) - 1]
|
||||
if uri != newuri and uri != newuri + "/":
|
||||
app.info('intersphinx inventory has moved: %s -> %s' % (uri, newuri))
|
||||
uri = newuri
|
||||
line = f.readline().rstrip().decode('utf-8')
|
||||
try:
|
||||
if line == '# Sphinx inventory version 1':
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
\@ifclassloaded{memoir}{}{\RequirePackage{fancyhdr}}
|
||||
|
||||
% for \text macro and \iffirstchoice@ conditional even if amsmath not loaded
|
||||
\RequirePackage{amstext}
|
||||
\RequirePackage{textcomp}
|
||||
\RequirePackage{titlesec}
|
||||
\RequirePackage{tabulary}
|
||||
@@ -152,6 +154,9 @@
|
||||
|
||||
\newcommand*{\sphinxAtStartFootnote}{\mbox{ }}
|
||||
|
||||
% Support large numbered footnotes in minipage (cf. admonitions)
|
||||
\def\thempfootnote{\arabic{mpfootnote}}
|
||||
|
||||
% Redefine the Verbatim environment to allow border and background colors
|
||||
% and to handle the top caption in a non separable by pagebreak way.
|
||||
% The original environment is still used for verbatims within tables.
|
||||
@@ -828,3 +833,15 @@
|
||||
% if the left page space is less than \literalblockneedspace, insert page-break
|
||||
\newcommand{\literalblockneedspace}{5\baselineskip}
|
||||
\newcommand{\literalblockwithoutcaptionneedspace}{1.5\baselineskip}
|
||||
|
||||
% figure in table
|
||||
\newenvironment{figure-in-table}[1][\linewidth]{%
|
||||
\def\@captype{figure}%
|
||||
\begin{minipage}{#1}%
|
||||
}{\end{minipage}}
|
||||
% store original \caption macro for use with figures in longtable and tabulary
|
||||
\AtBeginDocument{\let\Sphinx@originalcaption\caption}
|
||||
\newcommand*\figcaption
|
||||
{\ifx\equation$%$% this is trick to identify tabulary first pass
|
||||
\firstchoice@false\else\firstchoice@true\fi
|
||||
\Sphinx@originalcaption }
|
||||
|
||||
@@ -51,14 +51,15 @@
|
||||
\endgroup
|
||||
\fi
|
||||
\begin{flushright}
|
||||
\sphinxlogo%
|
||||
{\rm\Huge\py@HeaderFamily \@title} \par
|
||||
{\em\large\py@HeaderFamily \py@release\releaseinfo} \par
|
||||
\sphinxlogo
|
||||
\py@HeaderFamily
|
||||
{\Huge \@title }\par
|
||||
{\itshape\large \py@release \releaseinfo}\par
|
||||
\vspace{25pt}
|
||||
{\Large\py@HeaderFamily
|
||||
{\Large
|
||||
\begin{tabular}[t]{c}
|
||||
\@author
|
||||
\end{tabular}} \par
|
||||
\end{tabular}}\par
|
||||
\vspace{25pt}
|
||||
\@date \par
|
||||
\py@authoraddress \par
|
||||
|
||||
@@ -58,11 +58,12 @@
|
||||
\endgroup
|
||||
\fi
|
||||
\begin{flushright}%
|
||||
\sphinxlogo%
|
||||
{\rm\Huge\py@HeaderFamily \@title \par}%
|
||||
{\em\LARGE\py@HeaderFamily \py@release\releaseinfo \par}
|
||||
\sphinxlogo
|
||||
\py@HeaderFamily
|
||||
{\Huge \@title \par}
|
||||
{\itshape\LARGE \py@release\releaseinfo \par}
|
||||
\vfill
|
||||
{\LARGE\py@HeaderFamily
|
||||
{\LARGE
|
||||
\begin{tabular}[t]{c}
|
||||
\@author
|
||||
\end{tabular}
|
||||
|
||||
+20
-6
@@ -303,10 +303,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
'passoptionstopackages': '',
|
||||
'inputenc': ('\\ifPDFTeX\n'
|
||||
' \\usepackage[utf8]{inputenc}\n'
|
||||
'\\else\\fi'),
|
||||
'\\fi'),
|
||||
'utf8extra': ('\\ifdefined\\DeclareUnicodeCharacter\n'
|
||||
' \\DeclareUnicodeCharacter{00A0}{\\nobreakspace}\n'
|
||||
'\\else\\fi'),
|
||||
'\\fi'),
|
||||
'cmappkg': '\\usepackage{cmap}',
|
||||
'fontenc': '\\usepackage[T1]{fontenc}',
|
||||
'amsmath': '\\usepackage{amsmath,amssymb,amstext}',
|
||||
@@ -1022,15 +1022,15 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append('\n\\begin{longtable}')
|
||||
endmacro = '\\end{longtable}\n\n'
|
||||
elif self.table.has_verbatim:
|
||||
self.body.append('\n\\begin{tabular}')
|
||||
self.body.append('\n\\noindent\\begin{tabular}')
|
||||
endmacro = '\\end{tabular}\n\n'
|
||||
elif self.table.has_problematic and not self.table.colspec:
|
||||
# if the user has given us tabularcolumns, accept them and use
|
||||
# tabulary nevertheless
|
||||
self.body.append('\n\\begin{tabular}')
|
||||
self.body.append('\n\\noindent\\begin{tabular}')
|
||||
endmacro = '\\end{tabular}\n\n'
|
||||
else:
|
||||
self.body.append('\n\\begin{tabulary}{\\linewidth}')
|
||||
self.body.append('\n\\noindent\\begin{tabulary}{\\linewidth}')
|
||||
endmacro = '\\end{tabulary}\n\n'
|
||||
if self.table.colspec:
|
||||
self.body.append(self.table.colspec)
|
||||
@@ -1444,9 +1444,21 @@ 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 node.get('align', '') in ('left', 'right'):
|
||||
if self.table:
|
||||
# TODO: support align option
|
||||
if 'width' in node:
|
||||
length = width_to_latex_length(node['width'])
|
||||
self.body.append('\\begin{figure-in-table}[%s]\n\\centering\n' % length)
|
||||
else:
|
||||
self.body.append('\\begin{figure-in-table}\n\\centering\n')
|
||||
if any(isinstance(child, nodes.caption) for child in node):
|
||||
self.body.append('\\capstart')
|
||||
self.context.append(ids + '\\end{figure-in-table}\n')
|
||||
elif node.get('align', '') in ('left', 'right'):
|
||||
if 'width' in node:
|
||||
length = width_to_latex_length(node['width'])
|
||||
elif 'width' in node[0]:
|
||||
length = width_to_latex_length(node[0]['width'])
|
||||
else:
|
||||
length = '0pt'
|
||||
self.body.append('\\begin{wrapfigure}{%s}{%s}\n\\centering' %
|
||||
@@ -1486,6 +1498,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append('\\SphinxSetupCaptionForVerbatim{literal-block}{')
|
||||
elif self.in_minipage and isinstance(node.parent, nodes.figure):
|
||||
self.body.append('\\captionof{figure}{')
|
||||
elif self.table and node.parent.tagname == 'figure':
|
||||
self.body.append('\\figcaption{')
|
||||
else:
|
||||
self.body.append('\\caption{')
|
||||
|
||||
|
||||
@@ -220,6 +220,13 @@ Tables with multirow and multicol:
|
||||
| |
|
||||
+----+
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 0
|
||||
|
||||
* - .. figure:: img.png
|
||||
|
||||
figure in table
|
||||
|
||||
|
||||
Figures
|
||||
-------
|
||||
@@ -246,6 +253,12 @@ Figures
|
||||
|
||||
figure with align & figwidth option
|
||||
|
||||
.. figure:: rimg.png
|
||||
:align: right
|
||||
:width: 3cm
|
||||
|
||||
figure with align & width option
|
||||
|
||||
Version markup
|
||||
--------------
|
||||
|
||||
|
||||
@@ -70,6 +70,12 @@ def test_extensions(app, status, warning):
|
||||
assert warning.getvalue().startswith("WARNING: extension 'shutil'")
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_extension_in_blacklist(app, status, warning):
|
||||
app.setup_extension('sphinxjp.themecore')
|
||||
assert warning.getvalue().startswith("WARNING: the extension 'sphinxjp.themecore' was")
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_domain_override(app, status, warning):
|
||||
class A(Domain):
|
||||
|
||||
+10
-10
@@ -24,23 +24,23 @@ ENV_WARNINGS = """\
|
||||
(%(root)s/autodoc_fodder.py:docstring of autodoc_fodder\\.MarkupError:2: \
|
||||
WARNING: Explicit markup ends without a blank line; unexpected \
|
||||
unindent\\.\\n?
|
||||
)?%(root)s/images.txt:9: WARNING: image file not readable: foo.png
|
||||
%(root)s/images.txt:23: WARNING: nonlocal image URI found: \
|
||||
)?%(root)s/images.txt:\\d+: WARNING: image file not readable: foo.png
|
||||
%(root)s/images.txt:\\d+3: WARNING: nonlocal image URI found: \
|
||||
http://www.python.org/logo.png
|
||||
%(root)s/includes.txt:\\d*: WARNING: Encoding 'utf-8-sig' used for \
|
||||
%(root)s/includes.txt:\\d+: WARNING: Encoding 'utf-8-sig' used for \
|
||||
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:373: WARNING: invalid single index entry u'')?
|
||||
(%(root)s/undecodable.txt:3: WARNING: undecodable source characters, replacing \
|
||||
%(root)s/includes.txt:\\d+: WARNING: download file not readable: .*?nonexisting.png
|
||||
(%(root)s/markup.txt:\\d+: WARNING: invalid single index entry u'')?
|
||||
(%(root)s/undecodable.txt:\\d+: 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: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:164: WARNING: unknown option: &option
|
||||
%(root)s/images.txt:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/markup.txt:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
%(root)s/footnote.txt:\\d+: WARNING: citation not found: missing
|
||||
%(root)s/markup.txt:\\d+: WARNING: unknown option: &option
|
||||
"""
|
||||
|
||||
if PY3:
|
||||
|
||||
@@ -24,10 +24,10 @@ from test_build_html import ENV_WARNINGS
|
||||
|
||||
|
||||
LATEX_WARNINGS = ENV_WARNINGS + """\
|
||||
%(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:285: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
%(root)s/markup.txt:\\d+: WARNING: unknown option: &option
|
||||
%(root)s/footnote.txt:\\d+: WARNING: citation not found: missing
|
||||
%(root)s/images.txt:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/markup.txt:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
"""
|
||||
|
||||
if PY3:
|
||||
@@ -111,13 +111,22 @@ def test_writer(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
|
||||
|
||||
assert ('\\begin{figure-in-table}\n\\centering\n\\capstart\n'
|
||||
'\\includegraphics{{img}.png}\n'
|
||||
'\\figcaption{figure in table}\\label{markup:id7}\\end{figure-in-table}' in result)
|
||||
|
||||
assert ('\\begin{wrapfigure}{r}{0pt}\n\\centering\n'
|
||||
'\\includegraphics{{rimg}.png}\n\\caption{figure with align option}'
|
||||
'\\label{markup:id7}\\end{wrapfigure}' in result)
|
||||
'\\label{markup:id8}\\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)
|
||||
'\\label{markup:id9}\\end{wrapfigure}' in result)
|
||||
|
||||
assert ('\\begin{wrapfigure}{r}{3cm}\n\\centering\n'
|
||||
'\\includegraphics[width=3cm]{{rimg}.png}\n'
|
||||
'\\caption{figure with align \\& width option}'
|
||||
'\\label{markup:id10}\\end{wrapfigure}' in result)
|
||||
|
||||
|
||||
@with_app(buildername='latex', freshenv=True, # use freshenv to check warnings
|
||||
|
||||
Reference in New Issue
Block a user