summaryrefslogtreecommitdiff
path: root/sphinx/writers/latex.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/writers/latex.py')
-rw-r--r--sphinx/writers/latex.py112
1 files changed, 78 insertions, 34 deletions
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 751aabf4e..de472b36c 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -8,7 +8,7 @@
Much of this code is adapted from Dave Kuhlman's "docpy" writer from his
docutils sandbox.
- :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
+ :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@@ -48,7 +48,8 @@ BEGIN_DOC = r'''
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
-SECNUMDEPTH = 3
+LATEXSECTIONNAMES = ["part", "chapter", "section", "subsection",
+ "subsubsection", "paragraph", "subparagraph"]
DEFAULT_SETTINGS = {
'latex_engine': 'pdflatex',
@@ -501,9 +502,9 @@ def rstdim_to_latexdim(width_str):
class LaTeXTranslator(nodes.NodeVisitor):
- sectionnames = ["part", "chapter", "section", "subsection",
- "subsubsection", "paragraph", "subparagraph"]
+ secnumdepth = 2 # legacy sphinxhowto.cls uses this, whereas article.cls
+ # default is originally 3. For book/report, 2 is already LaTeX default.
ignore_missing_images = False
# sphinx specific document classes
@@ -532,16 +533,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.compact_list = 0
self.first_param = 0
- # 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:
- self.top_sectionlevel = 1
-
# sort out some elements
self.elements = DEFAULT_SETTINGS.copy()
self.elements.update(ADDITIONAL_SETTINGS.get(builder.config.latex_engine, {}))
@@ -562,16 +553,60 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.elements.update({
'releasename': _('Release'),
})
+
+ # we assume LaTeX class provides \chapter command except in case
+ # of non-Japanese 'howto' case
+ self.sectionnames = LATEXSECTIONNAMES[:]
if document.settings.docclass == 'howto':
docclass = builder.config.latex_docclass.get('howto', 'article')
+ if docclass[0] == 'j': # Japanese class...
+ pass
+ else:
+ self.sectionnames.remove('chapter')
else:
docclass = builder.config.latex_docclass.get('manual', 'report')
self.elements['docclass'] = docclass
+
+ # determine top section level
+ self.top_sectionlevel = 1
+ if builder.config.latex_toplevel_sectioning:
+ try:
+ self.top_sectionlevel = \
+ self.sectionnames.index(builder.config.latex_toplevel_sectioning)
+ except ValueError:
+ logger.warning('unknown %r toplevel_sectioning for class %r' %
+ (builder.config.latex_toplevel_sectioning, docclass))
+
if builder.config.today:
self.elements['date'] = builder.config.today
else:
self.elements['date'] = format_date(builder.config.today_fmt or _('%b %d, %Y'), # type: ignore # NOQA
language=builder.config.language)
+
+ if builder.config.numfig:
+ self.numfig_secnum_depth = builder.config.numfig_secnum_depth
+ if self.numfig_secnum_depth > 0: # default is 1
+ # numfig_secnum_depth as passed to sphinx.sty indices same names as in
+ # LATEXSECTIONNAMES but with -1 for part, 0 for chapter, 1 for section...
+ if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \
+ self.top_sectionlevel > 0:
+ self.numfig_secnum_depth += self.top_sectionlevel
+ else:
+ self.numfig_secnum_depth += self.top_sectionlevel - 1
+ # this (minus one) will serve as minimum to LaTeX's secnumdepth
+ self.numfig_secnum_depth = min(self.numfig_secnum_depth,
+ len(LATEXSECTIONNAMES) - 1)
+ # if passed key value is < 1 LaTeX will act as if 0; see sphinx.sty
+ self.elements['sphinxpkgoptions'] += \
+ (',numfigreset=%s' % self.numfig_secnum_depth)
+ else:
+ self.elements['sphinxpkgoptions'] += ',nonumfigreset'
+ try:
+ if builder.config.math_numfig:
+ self.elements['sphinxpkgoptions'] += ',mathnumfig'
+ except AttributeError:
+ pass
+
if builder.config.latex_logo:
# no need for \\noindent here, used in flushright
self.elements['logo'] = '\\sphinxincludegraphics{%s}\\par' % \
@@ -628,23 +663,32 @@ class LaTeXTranslator(nodes.NodeVisitor):
return '\\usepackage{%s}' % (packagename,)
usepackages = (declare_package(*p) for p in builder.usepackages)
self.elements['usepackages'] += "\n".join(usepackages)
+
+ minsecnumdepth = self.secnumdepth # 2 from legacy sphinx manual/howto
if document.get('tocdepth'):
- # redece tocdepth if `part` or `chapter` is used for top_sectionlevel
+ # reduce 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
# ...
tocdepth = document['tocdepth'] + self.top_sectionlevel - 2
- maxdepth = len(self.sectionnames) - self.top_sectionlevel
- if tocdepth > maxdepth:
+ if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \
+ self.top_sectionlevel > 0:
+ tocdepth += 1 # because top_sectionlevel is shifted by -1
+ if tocdepth > len(LATEXSECTIONNAMES) - 2: # default is 5 <-> subparagraph
logger.warning('too large :maxdepth:, ignored.')
- tocdepth = maxdepth
+ tocdepth = len(LATEXSECTIONNAMES) - 2
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
- if tocdepth >= SECNUMDEPTH:
- # Increase secnumdepth if tocdepth is depther than default SECNUMDEPTH
- self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' % tocdepth
+ minsecnumdepth = max(minsecnumdepth, tocdepth)
+
+ if builder.config.numfig and (builder.config.numfig_secnum_depth > 0):
+ minsecnumdepth = max(minsecnumdepth, self.numfig_secnum_depth - 1)
+
+ if minsecnumdepth > self.secnumdepth:
+ self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' %\
+ minsecnumdepth
if getattr(document.settings, 'contentsname', None):
self.elements['contentsname'] = \
@@ -1172,12 +1216,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_desc_addname(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxcode{')
+ self.body.append(r'\sphinxcode{\sphinxupquote{')
self.literal_whitespace += 1
def depart_desc_addname(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.literal_whitespace -= 1
def visit_desc_type(self, node):
@@ -1198,13 +1242,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_desc_name(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxbfcode{')
+ self.body.append(r'\sphinxbfcode{\sphinxupquote{')
self.no_contractions += 1
self.literal_whitespace += 1
def depart_desc_name(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.literal_whitespace -= 1
self.no_contractions -= 1
@@ -1243,11 +1287,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_desc_annotation(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxbfcode{')
+ self.body.append(r'\sphinxbfcode{\sphinxupquote{')
def depart_desc_annotation(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
def visit_desc_content(self, node):
# type: (nodes.Node) -> None
@@ -2133,12 +2177,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_literal_emphasis(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxstyleliteralemphasis{')
+ self.body.append(r'\sphinxstyleliteralemphasis{\sphinxupquote{')
self.no_contractions += 1
def depart_literal_emphasis(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.no_contractions -= 1
def visit_strong(self, node):
@@ -2151,12 +2195,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_literal_strong(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxstyleliteralstrong{')
+ self.body.append(r'\sphinxstyleliteralstrong{\sphinxupquote{')
self.no_contractions += 1
def depart_literal_strong(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.no_contractions -= 1
def visit_abbreviation(self, node):
@@ -2215,14 +2259,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
# type: (nodes.Node) -> None
self.no_contractions += 1
if self.in_title:
- self.body.append(r'\sphinxstyleliteralintitle{')
+ self.body.append(r'\sphinxstyleliteralintitle{\sphinxupquote{')
else:
- self.body.append(r'\sphinxcode{')
+ self.body.append(r'\sphinxcode{\sphinxupquote{')
def depart_literal(self, node):
# type: (nodes.Node) -> None
self.no_contractions -= 1
- self.body.append('}')
+ self.body.append('}}')
def visit_footnote_reference(self, node):
# type: (nodes.Node) -> None