Skip to content

Commit

Permalink
Refactor: Add captioned_literal_block node to simplify LaTeX writer
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed May 23, 2018
1 parent 51962c7 commit 489d86d
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 56 deletions.
6 changes: 5 additions & 1 deletion CHANGES
Expand Up @@ -64,9 +64,13 @@ Deprecated
* ``sphinx.writers.latex.Table.caption_footnotetexts`` is deprecated
* ``sphinx.writers.latex.Table.header_footnotetexts`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.footnotestack`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.in_container_literal_block`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.next_hyperlink_ids`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.restrict_footnote()`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.unrestrict_footnote()`` is deprecated
* ``LaTeXWriter.bibitems`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.push_hyperlink_ids()`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.pop_hyperlink_ids()`` is deprecated
* ``sphinx.writers.latex.LaTeXWriter.bibitems`` is deprecated
* ``BuildEnvironment.load()`` is deprecated
* ``BuildEnvironment.loads()`` is deprecated
* ``BuildEnvironment.frompickle()`` is deprecated
Expand Down
20 changes: 20 additions & 0 deletions doc/extdev/index.rst
Expand Up @@ -171,6 +171,16 @@ The following is a list of deprecated interface.
- 3.0
- N/A

* - ``sphinx.writers.latex.LaTeXWriter.in_container_literal_block``
- 1.8
- 3.0
- N/A

* - ``sphinx.writers.latex.LaTeXWriter.next_hyperlink_ids``
- 1.8
- 3.0
- N/A

* - ``sphinx.writers.latex.LaTeXWriter.restrict_footnote()``
- 1.8
- 3.0
Expand All @@ -181,6 +191,16 @@ The following is a list of deprecated interface.
- 3.0
- N/A

* - ``sphinx.writers.latex.LaTeXWriter.push_hyperlink_ids()``
- 1.8
- 3.0
- N/A

* - ``sphinx.writers.latex.LaTeXWriter.pop_hyperlink_ids()``
- 1.8
- 3.0
- N/A

* - ``sphinx.writers.latex.LaTeXWriter.bibitems``
- 1.8
- 3.0
Expand Down
6 changes: 4 additions & 2 deletions sphinx/builders/latex/__init__.py
Expand Up @@ -20,7 +20,8 @@
from sphinx.builders import Builder
from sphinx.builders.latex.transforms import (
BibliographyTransform, CitationReferenceTransform, MathReferenceTransform,
FootnoteDocnameUpdater, LaTeXFootnoteTransform, ShowUrlsTransform
FootnoteDocnameUpdater, LaTeXFootnoteTransform, LiteralBlockTransform,
ShowUrlsTransform,
)
from sphinx.config import string_classes, ENUM
from sphinx.environment import NoUri
Expand Down Expand Up @@ -223,7 +224,8 @@ def apply_transforms(self, doctree):
transformer.set_environment(self.env)
transformer.add_transforms([BibliographyTransform,
ShowUrlsTransform,
LaTeXFootnoteTransform])
LaTeXFootnoteTransform,
LiteralBlockTransform])
transformer.apply_transforms()

def finish(self):
Expand Down
5 changes: 5 additions & 0 deletions sphinx/builders/latex/nodes.py
Expand Up @@ -12,6 +12,11 @@
from docutils import nodes


class captioned_literal_block(nodes.container):
"""A node for a container of literal_block having a caption."""
pass


class footnotemark(nodes.Inline, nodes.Referential, nodes.TextElement):
"""A node represents ``\footnotemark``."""
pass
Expand Down
17 changes: 16 additions & 1 deletion sphinx/builders/latex/transforms.py
Expand Up @@ -13,7 +13,7 @@

from sphinx import addnodes
from sphinx.builders.latex.nodes import (
footnotemark, footnotetext, math_reference, thebibliography
captioned_literal_block, footnotemark, footnotetext, math_reference, thebibliography
)
from sphinx.transforms import SphinxTransform

Expand Down Expand Up @@ -566,3 +566,18 @@ def apply(self):
if docname:
refnode = math_reference('', docname=docname, target=node['reftarget'])
node.replace_self(refnode)


class LiteralBlockTransform(SphinxTransform):
"""Replace container nodes for literal_block by captioned_literal_block."""
default_priority = 400

def apply(self):
# type: () -> None
if self.app.builder.name != 'latex':
return

for node in self.document.traverse(nodes.container):
if node['literal_block'] is True:
newnode = captioned_literal_block('', *node.children, **node.attributes)
node.replace_self(newnode)
97 changes: 45 additions & 52 deletions sphinx/writers/latex.py
Expand Up @@ -25,7 +25,7 @@

from sphinx import addnodes
from sphinx import highlighting
from sphinx.builders.latex.nodes import footnotetext
from sphinx.builders.latex.nodes import captioned_literal_block, footnotetext
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.errors import SphinxError
from sphinx.locale import admonitionlabels, _, __
Expand Down Expand Up @@ -58,6 +58,7 @@
nodes.literal_block,
nodes.table,
nodes.section,
captioned_literal_block,
)

DEFAULT_SETTINGS = {
Expand Down Expand Up @@ -465,7 +466,6 @@ def __init__(self, document, builder):
self.in_production_list = 0
self.in_footnote = 0
self.in_caption = 0
self.in_container_literal_block = 0
self.in_term = 0
self.needs_linetrimming = 0
self.in_minipage = 0
Expand Down Expand Up @@ -691,7 +691,6 @@ def declare_package(packagename, options=None):
self.pending_footnotes = [] # type: List[nodes.footnote_reference]
self.curfilestack = [] # type: List[unicode]
self.handled_abbrs = set() # type: Set[unicode]
self.next_hyperlink_ids = {} # type: Dict[unicode, Set[unicode]]
self.next_section_ids = set() # type: Set[unicode]

def pushbody(self, newbody):
Expand All @@ -705,15 +704,6 @@ def popbody(self):
self.body = self.bodystack.pop()
return body

def push_hyperlink_ids(self, figtype, ids):
# type: (unicode, Set[unicode]) -> None
hyperlink_ids = self.next_hyperlink_ids.setdefault(figtype, set())
hyperlink_ids.update(ids)

def pop_hyperlink_ids(self, figtype):
# type: (unicode) -> Set[unicode]
return self.next_hyperlink_ids.pop(figtype, set())

def check_latex_elements(self):
# type: () -> None
for key in self.builder.config.latex_elements:
Expand Down Expand Up @@ -1790,7 +1780,7 @@ def depart_figure(self, node):
def visit_caption(self, node):
# type: (nodes.Node) -> None
self.in_caption += 1
if self.in_container_literal_block:
if isinstance(node.parent, captioned_literal_block):
self.body.append('\\sphinxSetupCaptionForVerbatim{')
elif self.in_minipage and isinstance(node.parent, nodes.figure):
self.body.append('\\captionof{figure}{')
Expand Down Expand Up @@ -1883,35 +1873,13 @@ def add_target(id):
self.body.append(self.hypertarget(id, anchor=anchor))

# skip if visitor for next node supports hyperlink
domain = self.builder.env.get_domain('std')
next_node = node.next_node(ascend=True)
if isinstance(next_node, HYPERLINK_SUPPORT_NODES):
return
elif domain.get_enumerable_node_type(next_node) and domain.get_numfig_title(next_node):
return

# postpone the labels until after the sectioning command
parindex = node.parent.index(node)
try:
try:
next = node.parent[parindex + 1]
except IndexError:
# last node in parent, look at next after parent
# (for section of equal level) if it exists
if node.parent.parent is not None:
next = node.parent.parent[
node.parent.parent.index(node.parent)]
else:
raise
domain = self.builder.env.get_domain('std')
figtype = domain.get_enumerable_node_type(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'):
ids.add(node['refid'])
ids.update(node['ids'])
self.push_hyperlink_ids(figtype, ids)
return
except IndexError:
pass
if 'refuri' in node:
return
if node.get('refid'):
Expand Down Expand Up @@ -2221,6 +2189,14 @@ def depart_footnotetext(self, node):
# the \ignorespaces in particular for after table header use
self.body.append('%\n\\end{footnotetext}\\ignorespaces ')

def visit_captioned_literal_block(self, node):
# type: (nodes.Node) -> None
pass

def depart_captioned_literal_block(self, node):
# type: (nodes.Node) -> None
pass

def visit_literal_block(self, node):
# type: (nodes.Node) -> None
if node.rawsource != node.astext():
Expand All @@ -2229,9 +2205,11 @@ def visit_literal_block(self, node):
self.body.append('\\begin{sphinxalltt}\n')
else:
labels = self.hypertarget_to(node)
# LaTeX code will insert \phantomsection prior to \label
if isinstance(node.parent, captioned_literal_block):
labels += self.hypertarget_to(node.parent)
if labels and not self.in_footnote:
self.body.append('\n\\def\\sphinxLiteralBlockLabel{' + labels + '}')

code = node.astext()
lang = self.hlsettingstack[-1][0]
linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
Expand Down Expand Up @@ -2458,22 +2436,11 @@ def depart_compound(self, node):

def visit_container(self, node):
# type: (nodes.Node) -> None
if node.get('literal_block'):
self.in_container_literal_block += 1
ids = '' # type: unicode
for id in self.pop_hyperlink_ids('code-block'):
ids += self.hypertarget(id, anchor=False)
if node['ids']:
# suppress with anchor=False \phantomsection insertion
ids += self.hypertarget(node['ids'][0], anchor=False)
# define label for use in caption.
if ids:
self.body.append('\n\\def\\sphinxLiteralBlockLabel{' + ids + '}\n')
pass

def depart_container(self, node):
# type: (nodes.Node) -> None
if node.get('literal_block'):
self.in_container_literal_block -= 1
pass

def visit_decoration(self, node):
# type: (nodes.Node) -> None
Expand Down Expand Up @@ -2603,6 +2570,32 @@ def bibitems(self):
RemovedInSphinx30Warning)
return []

@property
def in_container_literal_block(self):
# type: () -> int
warnings.warn('LaTeXTranslator.in_container_literal_block is deprecated.',
RemovedInSphinx30Warning)
return 0

@property
def next_hyperlink_ids(self):
# type: () -> Dict
warnings.warn('LaTeXTranslator.next_hyperlink_ids is deprecated.',
RemovedInSphinx30Warning)
return {}

def push_hyperlink_ids(self, figtype, ids):
# type: (unicode, Set[unicode]) -> None
warnings.warn('LaTeXTranslator.push_hyperlink_ids() is deprecated.',
RemovedInSphinx30Warning)
pass

def pop_hyperlink_ids(self, figtype):
# type: (unicode) -> Set[unicode]
warnings.warn('LaTeXTranslator.pop_hyperlink_ids() is deprecated.',
RemovedInSphinx30Warning)
return set()


# Import old modules here for compatibility
# They should be imported after `LaTeXTranslator` to avoid recursive import.
Expand Down

0 comments on commit 489d86d

Please sign in to comment.