Merge pull request #2475 from jfbu/master

merge stable into master and update sphinx.sty and CHANGES for 1.5
This commit is contained in:
Jean-François B 2016-04-20 19:23:27 +02:00
commit 4959a75c6f
5 changed files with 189 additions and 65 deletions

View File

@ -11,8 +11,11 @@ python:
- "3.5"
- "pypy"
env:
- DOCUTILS=0.11
- DOCUTILS=0.12
global:
- TEST=-v
matrix:
- DOCUTILS=0.11
- DOCUTILS=0.12
install:
- pip install -U pip
- pip install docutils==$DOCUTILS

View File

@ -4,6 +4,8 @@ Release 1.5 (in development)
Incompatible changes
--------------------
* LaTeX package fancybox is not longer a dependency of sphinx.sty
Features added
--------------
@ -24,6 +26,10 @@ 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.
Bugs fixed
----------
@ -34,6 +40,8 @@ Bugs fixed
* #2436: Sphinx does not check version by :confval:`needs_sphinx` if loading extensions failed
* #2397: Setup shorthandoff for turkish documents
* #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
Release 1.4.1 (released Apr 12, 2016)

View File

@ -572,7 +572,7 @@ class ASTIdentifier(ASTBase):
classname=None)
key = symbol.get_lookup_key()
assert key
pnode['cpp:parentKey'] = key
pnode['cpp:parent_key'] = key
pnode += nodes.Text(self.identifier)
signode += pnode
elif mode == 'lastIsName':
@ -3768,10 +3768,10 @@ class CPPObject(ObjectDescription):
raise NotImplementedError()
def handle_signature(self, sig, signode):
if 'cpp:parentSymbol' not in self.env.ref_context:
root = self.env.domaindata['cpp']['rootSymbol']
self.env.ref_context['cpp:parentSymbol'] = root
parentSymbol = self.env.ref_context['cpp:parentSymbol']
if 'cpp:parent_symbol' not in self.env.ref_context:
root = self.env.domaindata['cpp']['root_symbol']
self.env.ref_context['cpp:parent_symbol'] = root
parentSymbol = self.env.ref_context['cpp:parent_symbol']
parser = DefinitionParser(sig, self)
try:
@ -3783,16 +3783,16 @@ class CPPObject(ObjectDescription):
# the possibly inner declarations.
name = _make_phony_error_name()
symbol = parentSymbol.add_name(name)
self.env.ref_context['cpp:lastSymbol'] = symbol
self.env.ref_context['cpp:last_symbol'] = symbol
raise ValueError
try:
symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
self.env.ref_context['cpp:lastSymbol'] = symbol
self.env.ref_context['cpp:last_symbol'] = symbol
except _DuplicateSymbolError as e:
# Assume we are actually in the old symbol,
# instead of the newly created duplicate.
self.env.ref_context['cpp:lastSymbol'] = e.symbol
self.env.ref_context['cpp:last_symbol'] = e.symbol
if ast.objectType == 'enumerator':
self._add_enumerator_to_parent(ast)
@ -3839,13 +3839,13 @@ class CPPClassObject(CPPObject):
return _('%s (C++ class)') % name
def before_content(self):
lastSymbol = self.env.ref_context['cpp:lastSymbol']
lastSymbol = self.env.ref_context['cpp:last_symbol']
assert lastSymbol
self.oldParentSymbol = self.env.ref_context['cpp:parentSymbol']
self.env.ref_context['cpp:parentSymbol'] = lastSymbol
self.oldParentSymbol = self.env.ref_context['cpp:parent_symbol']
self.env.ref_context['cpp:parent_symbol'] = lastSymbol
def after_content(self):
self.env.ref_context['cpp:parentSymbol'] = self.oldParentSymbol
self.env.ref_context['cpp:parent_symbol'] = self.oldParentSymbol
def parse_definition(self, parser):
return parser.parse_declaration("class")
@ -3859,13 +3859,13 @@ class CPPEnumObject(CPPObject):
return _('%s (C++ enum)') % name
def before_content(self):
lastSymbol = self.env.ref_context['cpp:lastSymbol']
lastSymbol = self.env.ref_context['cpp:last_symbol']
assert lastSymbol
self.oldParentSymbol = self.env.ref_context['cpp:parentSymbol']
self.env.ref_context['cpp:parentSymbol'] = lastSymbol
self.oldParentSymbol = self.env.ref_context['cpp:parent_symbol']
self.env.ref_context['cpp:parent_symbol'] = lastSymbol
def after_content(self):
self.env.ref_context['cpp:parentSymbol'] = self.oldParentSymbol
self.env.ref_context['cpp:parent_symbol'] = self.oldParentSymbol
def parse_definition(self, parser):
ast = parser.parse_declaration("enum")
@ -3912,7 +3912,7 @@ class CPPNamespaceObject(Directive):
def run(self):
env = self.state.document.settings.env
rootSymbol = env.domaindata['cpp']['rootSymbol']
rootSymbol = env.domaindata['cpp']['root_symbol']
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
symbol = rootSymbol
stack = []
@ -3927,8 +3927,8 @@ class CPPNamespaceObject(Directive):
ast = ASTNamespace(name, None)
symbol = rootSymbol.add_name(ast.nestedName, ast.templatePrefix)
stack = [symbol]
env.ref_context['cpp:parentSymbol'] = symbol
env.temp_data['cpp:namespaceStack'] = stack
env.ref_context['cpp:parent_symbol'] = symbol
env.temp_data['cpp:namespace_stack'] = stack
return []
@ -3954,14 +3954,14 @@ class CPPNamespacePushObject(Directive):
self.warn(e.description)
name = _make_phony_error_name()
ast = ASTNamespace(name, None)
oldParent = env.ref_context.get('cpp:parentSymbol', None)
oldParent = env.ref_context.get('cpp:parent_symbol', None)
if not oldParent:
oldParent = env.domaindata['cpp']['rootSymbol']
oldParent = env.domaindata['cpp']['root_symbol']
symbol = oldParent.add_name(ast.nestedName, ast.templatePrefix)
stack = env.temp_data.get('cpp:namespaceStack', [])
stack = env.temp_data.get('cpp:namespace_stack', [])
stack.append(symbol)
env.ref_context['cpp:parentSymbol'] = symbol
env.temp_data['cpp:namespaceStack'] = stack
env.ref_context['cpp:parent_symbol'] = symbol
env.temp_data['cpp:namespace_stack'] = stack
return []
@ -3977,7 +3977,7 @@ class CPPNamespacePopObject(Directive):
def run(self):
env = self.state.document.settings.env
stack = env.temp_data.get('cpp:namespaceStack', None)
stack = env.temp_data.get('cpp:namespace_stack', None)
if not stack or len(stack) == 0:
self.warn("C++ namespace pop on empty stack. Defaulting to gobal scope.")
stack = []
@ -3986,17 +3986,17 @@ class CPPNamespacePopObject(Directive):
if len(stack) > 0:
symbol = stack[-1]
else:
symbol = env.domaindata['cpp']['rootSymbol']
env.ref_context['cpp:parentSymbol'] = symbol
env.temp_data['cpp:namespaceStack'] = stack
symbol = env.domaindata['cpp']['root_symbol']
env.ref_context['cpp:parent_symbol'] = symbol
env.temp_data['cpp:namespace_stack'] = stack
return []
class CPPXRefRole(XRefRole):
def process_link(self, env, refnode, has_explicit_title, title, target):
parent = env.ref_context.get('cpp:parentSymbol', None)
parent = env.ref_context.get('cpp:parent_symbol', None)
if parent:
refnode['cpp:parentKey'] = parent.get_lookup_key()
refnode['cpp:parent_key'] = parent.get_lookup_key()
if refnode['reftype'] == 'any':
# Assume the removal part of fix_parens for :any: refs.
# The addition part is done with the reference is resolved.
@ -4055,12 +4055,12 @@ class CPPDomain(Domain):
'enumerator': CPPXRefRole()
}
initial_data = {
'rootSymbol': Symbol(None, None, None, None, None, None),
'root_symbol': Symbol(None, None, None, None, None, None),
'names': {} # full name for indexing -> docname
}
def clear_doc(self, docname):
rootSymbol = self.data['rootSymbol']
rootSymbol = self.data['root_symbol']
rootSymbol.clear_doc(docname)
for name, nDocname in list(self.data['names'].items()):
if nDocname == docname:
@ -4069,12 +4069,12 @@ class CPPDomain(Domain):
def process_doc(self, env, docname, document):
# just for debugging
# print(docname)
# print(self.data['rootSymbol'].dump(0))
# print(self.data['root_symbol'].dump(0))
pass
def merge_domaindata(self, docnames, otherdata):
self.data['rootSymbol'].merge_with(otherdata['rootSymbol'],
docnames, self.env)
self.data['root_symbol'].merge_with(otherdata['root_symbol'],
docnames, self.env)
ourNames = self.data['names']
for name, docname in otherdata['names'].items():
if docname in docnames:
@ -4102,8 +4102,8 @@ class CPPDomain(Domain):
warner.warn('Unparseable C++ cross-reference: %r\n%s'
% (target, str(e.description)))
return None, None
parentKey = node.get("cpp:parentKey", None)
rootSymbol = self.data['rootSymbol']
parentKey = node.get("cpp:parent_key", None)
rootSymbol = self.data['root_symbol']
if parentKey:
parentSymbol = rootSymbol.direct_lookup(parentKey)
if not parentSymbol:
@ -4152,7 +4152,7 @@ class CPPDomain(Domain):
return []
def get_objects(self):
rootSymbol = self.data['rootSymbol']
rootSymbol = self.data['root_symbol']
for symbol in rootSymbol.get_all_symbols():
if symbol.declaration is None:
continue

View File

@ -8,17 +8,23 @@
\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}
\RequirePackage{fancybox}
\RequirePackage{titlesec}
\RequirePackage{tabulary}
\RequirePackage{makeidx}
% For framing code-blocks and warning type notices, and shadowing topics
\RequirePackage{framed}
\newif\ifSphinx@inframed % flag set if we are in a framed environment
\RequirePackage{ifthen}
%The xcolor package draws better fcolorboxes
%around verbatim code
% The xcolor package draws better fcolorboxes around verbatim code
\IfFileExists{xcolor.sty}{
\RequirePackage{xcolor}
}{
@ -242,17 +248,101 @@
\setlength\partopsep{0pt}%
\setlength\leftmargin{0pt}%
}%
\item\MakeFramed {\FrameRestore}%
\item
% use a minipage if we are already inside a framed environment
\relax\ifSphinx@inframed\noindent\begin{\minipage}{\linewidth}\fi
\MakeFramed {\FrameRestore}%
\small
\OriginalVerbatim[#1]%
}
\renewcommand{\endVerbatim}{%
\endOriginalVerbatim
\endMakeFramed
\ifSphinx@inframed\end{minipage}\fi
\endlist
% LaTeX environments always revert local changes on exit, here e.g. \parskip
}
% define macro to frame contents and add shadow on right and bottom
\def\Sphinx@shadowsep {5\p@} % \p@ means "pt "
\def\Sphinx@shadowsize {4\p@}
\def\Sphinx@shadowrule {\fboxrule}
\long\def\Sphinx@ShadowFBox#1{%
\leavevmode\begingroup
% first we frame the box #1
\setbox\@tempboxa
\hbox{\vrule\@width\Sphinx@shadowrule
\vbox{\hrule\@height\Sphinx@shadowrule
\kern\Sphinx@shadowsep
\hbox{\kern\Sphinx@shadowsep #1\kern\Sphinx@shadowsep}%
\kern\Sphinx@shadowsep
\hrule\@height\Sphinx@shadowrule}%
\vrule\@width\Sphinx@shadowrule}%
% Now we add the shadow, like \shadowbox from fancybox.sty would do
\dimen@\dimexpr.5\Sphinx@shadowrule+\Sphinx@shadowsize\relax
\hbox{\vbox{\offinterlineskip
\hbox{\copy\@tempboxa\kern-.5\Sphinx@shadowrule
% add shadow on right side
\lower\Sphinx@shadowsize
\hbox{\vrule\@height\ht\@tempboxa \@width\dimen@}%
}%
\kern-\dimen@ % shift back vertically to bottom of frame
% and add shadow at bottom
\moveright\Sphinx@shadowsize
\vbox{\hrule\@width\wd\@tempboxa \@height\dimen@}%
}%
% move left by the size of right shadow so shadow adds no width
\kern-\Sphinx@shadowsize
}%
\endgroup
}
% use framed.sty to allow page breaks in frame+shadow
% works well inside Lists and Quote-like environments
% produced by ``topic'' directive (or local contents)
% could nest if LaTeX writer authorized it
\newenvironment{SphinxShadowBox}
{\def\FrameCommand {\Sphinx@ShadowFBox }%
% configure framed.sty not to add extra vertical spacing
\OuterFrameSep \z@skip
% the \trivlist will add the vertical spacing on top and bottom which is
% typical of center environment as used in Sphinx <= 1.4.1
% the \noindent has the effet of an extra blank line on top, to
% imitate closely the layout from Sphinx <= 1.4.1; the \FrameHeightAdjust
% will put top part of frame on this baseline.
\def\FrameHeightAdjust {\baselineskip}%
\trivlist\item\noindent
% use a minipage if we are already inside a framed environment
\ifSphinx@inframed\begin{minipage}{\linewidth}\fi
\MakeFramed {\Sphinx@inframedtrue
% framed.sty puts into "\width" the added width (=2shadowsep+2shadowrule)
% adjust \hsize to what the contents must use
\advance\hsize-\width
% adjust LaTeX parameters to behave properly in indented/quoted contexts
\FrameRestore
% typeset the contents as in a minipage (Sphinx <= 1.4.1 used a minipage and
% itemize/enumerate are therein typeset more tightly, we want to keep
% that). We copy-paste from LaTeX source code but don't do a real minipage.
\@pboxswfalse
% for footnotes, but Sphinx inactivates footnotes in topics
\def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
\let\@footnotetext\@mpfootnotetext
\let\@listdepth\@mplistdepth \@mplistdepth\z@
\@minipagerestore
\@setminipage
}%
}%
{% insert the "endminipage" code
\par\unskip
% handle (currently non existing) minipage style footnotes
\ifvoid\@mpfootins\else
\vskip\skip\@mpfootins\normalcolor\footnoterule\unvbox\@mpfootins
\fi
\@minipagefalse
\endMakeFramed
\ifSphinx@inframed\end{minipage}\fi
\endtrivlist
}
% \moduleauthor{name}{email}
\newcommand{\moduleauthor}[2]{}
@ -316,23 +406,49 @@
% Notices / Admonitions
%
\newlength{\py@noticelength}
\newcommand{\py@heavybox}{
\setlength{\fboxrule}{1pt}
\setlength{\fboxsep}{6pt}
\setlength{\py@noticelength}{\linewidth}
\addtolength{\py@noticelength}{-2\fboxsep}
\addtolength{\py@noticelength}{-2\fboxrule}
%\setlength{\shadowsize}{3pt}
\noindent\Sbox
\minipage{\py@noticelength}
}
\newcommand{\py@endheavybox}{
\endminipage
\endSbox
\fbox{\TheSbox}
}
% Code adapted from framed.sty's "snugshade" environment.
% Nesting works (inner frames do not allow page breaks).
\newcommand{\py@heavybox}{\par
\setlength{\FrameRule}{\p@}% 1pt
\setlength{\FrameSep}{\dimexpr.6\baselineskip-\FrameRule\relax}
% configure framed.sty's parameters to obtain same vertical spacing
% as for "light" boxes. We need for this to manually insert parskip glue and
% revert a skip done by framed before the frame.
\setlength{\OuterFrameSep}{0pt}
\vspace{\FrameHeightAdjust}
% copied/adapted from framed.sty's snugshade
\def\FrameCommand##1{\hskip\@totalleftmargin
\fboxsep\FrameSep \fboxrule\FrameRule\fbox{##1}%
\hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
% use a minipage if we are already inside a framed environment
\ifSphinx@inframed
\noindent\begin{minipage}{\linewidth}
\else
\vspace{\parskip}
\fi
\MakeFramed {\Sphinx@inframedtrue
\advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize
% minipage initialization copied from LaTeX source code.
\@pboxswfalse
% for footnotes
\def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
\let\@footnotetext\@mpfootnotetext
\let\@listdepth\@mplistdepth \@mplistdepth\z@
\@minipagerestore
\@setminipage }%
}
\newcommand{\py@endheavybox}{%
\par\unskip
% handles footnotes
\ifvoid\@mpfootins\else
\vskip\skip\@mpfootins\normalcolor\footnoterule\unvbox\@mpfootins
\fi
\@minipagefalse\endMakeFramed
\ifSphinx@inframed\end{minipage}\fi
% arrange for similar spacing below frame as for "light" boxes.
\vskip .4\baselineskip
}
\newcommand{\py@lightbox}{%
\par\allowbreak

View File

@ -706,14 +706,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_topic(self, node):
self.in_minipage = 1
self.body.append('\\setbox0\\vbox{\n'
'\\begin{minipage}{0.95\\linewidth}\n')
self.body.append('\n\\begin{SphinxShadowBox}\n')
def depart_topic(self, node):
self.in_minipage = 0
self.body.append('\\end{minipage}}\n'
'\\begin{center}\\setlength{\\fboxsep}{5pt}'
'\\shadowbox{\\box0}\\end{center}\n')
self.body.append('\\end{SphinxShadowBox}\n')
visit_sidebar = visit_topic
depart_sidebar = depart_topic