mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add docname attribute to every footnote and footnote_reference nodes
This commit is contained in:
parent
1c65ff762e
commit
ff0f008574
@ -19,7 +19,7 @@ from six import text_type
|
|||||||
|
|
||||||
from sphinx import package_dir, addnodes, highlighting
|
from sphinx import package_dir, addnodes, highlighting
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.builders.latex.transforms import ShowUrlsTransform
|
from sphinx.builders.latex.transforms import FootnoteDocnameUpdater, ShowUrlsTransform
|
||||||
from sphinx.config import string_classes, ENUM
|
from sphinx.config import string_classes, ENUM
|
||||||
from sphinx.environment import NoUri
|
from sphinx.environment import NoUri
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
@ -316,6 +316,7 @@ def setup(app):
|
|||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[unicode, Any]
|
||||||
app.add_builder(LaTeXBuilder)
|
app.add_builder(LaTeXBuilder)
|
||||||
app.connect('config-inited', validate_config_values)
|
app.connect('config-inited', validate_config_values)
|
||||||
|
app.add_transform(FootnoteDocnameUpdater)
|
||||||
|
|
||||||
app.add_config_value('latex_engine', default_latex_engine, None,
|
app.add_config_value('latex_engine', default_latex_engine, None,
|
||||||
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex'))
|
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex'))
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
|
from sphinx import addnodes
|
||||||
from sphinx.transforms import SphinxTransform
|
from sphinx.transforms import SphinxTransform
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
@ -20,6 +21,16 @@ if False:
|
|||||||
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
|
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
|
||||||
|
|
||||||
|
|
||||||
|
class FootnoteDocnameUpdater(SphinxTransform):
|
||||||
|
"""Add docname to footnote and footnote_reference nodes."""
|
||||||
|
default_priority = 200
|
||||||
|
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
|
||||||
|
|
||||||
|
def apply(self):
|
||||||
|
for node in self.document.traverse(lambda n: isinstance(n, self.TARGET_NODES)):
|
||||||
|
node['docname'] = self.env.docname
|
||||||
|
|
||||||
|
|
||||||
class ShowUrlsTransform(SphinxTransform):
|
class ShowUrlsTransform(SphinxTransform):
|
||||||
"""Expand references to inline text or footnotes.
|
"""Expand references to inline text or footnotes.
|
||||||
|
|
||||||
@ -57,8 +68,9 @@ class ShowUrlsTransform(SphinxTransform):
|
|||||||
uri = uri[7:]
|
uri = uri[7:]
|
||||||
if node.astext() != uri:
|
if node.astext() != uri:
|
||||||
index = node.parent.index(node)
|
index = node.parent.index(node)
|
||||||
|
docname = self.get_docname_for_node(node)
|
||||||
if show_urls == 'footnote':
|
if show_urls == 'footnote':
|
||||||
fn, fnref = self.create_footnote(uri)
|
fn, fnref = self.create_footnote(uri, docname)
|
||||||
node.parent.insert(index + 1, fn)
|
node.parent.insert(index + 1, fn)
|
||||||
node.parent.insert(index + 2, fnref)
|
node.parent.insert(index + 2, fnref)
|
||||||
|
|
||||||
@ -67,18 +79,30 @@ class ShowUrlsTransform(SphinxTransform):
|
|||||||
textnode = nodes.Text(" (%s)" % uri)
|
textnode = nodes.Text(" (%s)" % uri)
|
||||||
node.parent.insert(index + 1, textnode)
|
node.parent.insert(index + 1, textnode)
|
||||||
|
|
||||||
def create_footnote(self, uri):
|
def get_docname_for_node(self, node):
|
||||||
# type: (unicode) -> Tuple[nodes.footnote, nodes.footnote_ref]
|
# type: (nodes.Node) -> unicode
|
||||||
|
while node:
|
||||||
|
if isinstance(node, nodes.document):
|
||||||
|
return self.env.path2doc(node['source'])
|
||||||
|
elif isinstance(node, addnodes.start_of_file):
|
||||||
|
return node['docname']
|
||||||
|
else:
|
||||||
|
node = node.parent
|
||||||
|
|
||||||
|
return None # never reached here. only for type hinting
|
||||||
|
|
||||||
|
def create_footnote(self, uri, docname):
|
||||||
|
# type: (unicode, unicode) -> Tuple[nodes.footnote, nodes.footnote_ref]
|
||||||
label = nodes.label('', '#')
|
label = nodes.label('', '#')
|
||||||
para = nodes.paragraph()
|
para = nodes.paragraph()
|
||||||
para.append(nodes.reference('', nodes.Text(uri), refuri=uri, nolinkurl=True))
|
para.append(nodes.reference('', nodes.Text(uri), refuri=uri, nolinkurl=True))
|
||||||
footnote = nodes.footnote(uri, label, para, auto=1)
|
footnote = nodes.footnote(uri, label, para, auto=1, docname=docname)
|
||||||
footnote['names'].append('#')
|
footnote['names'].append('#')
|
||||||
self.document.note_autofootnote(footnote)
|
self.document.note_autofootnote(footnote)
|
||||||
|
|
||||||
label = nodes.Text('#')
|
label = nodes.Text('#')
|
||||||
footnote_ref = nodes.footnote_reference('[#]_', label, auto=1,
|
footnote_ref = nodes.footnote_reference('[#]_', label, auto=1,
|
||||||
refid=footnote['ids'][0])
|
refid=footnote['ids'][0], docname=docname)
|
||||||
self.document.note_autofootnote_ref(footnote_ref)
|
self.document.note_autofootnote_ref(footnote_ref)
|
||||||
footnote.add_backref(footnote_ref['ids'][0])
|
footnote.add_backref(footnote_ref['ids'][0])
|
||||||
|
|
||||||
@ -90,7 +114,7 @@ class ShowUrlsTransform(SphinxTransform):
|
|||||||
self.document.walkabout(collector)
|
self.document.walkabout(collector)
|
||||||
|
|
||||||
num = 0
|
num = 0
|
||||||
for document, footnote in collector.auto_footnotes:
|
for footnote in collector.auto_footnotes:
|
||||||
# search unused footnote number
|
# search unused footnote number
|
||||||
while True:
|
while True:
|
||||||
num += 1
|
num += 1
|
||||||
@ -105,8 +129,9 @@ class ShowUrlsTransform(SphinxTransform):
|
|||||||
footnote['names'].append(str(num))
|
footnote['names'].append(str(num))
|
||||||
|
|
||||||
# update footnote_references by new footnote number
|
# update footnote_references by new footnote number
|
||||||
for ref in collector.footnote_refs.get(document, []):
|
docname = footnote['docname']
|
||||||
if footnote['ids'][0] == ref['refid']:
|
for ref in collector.footnote_refs:
|
||||||
|
if docname == ref['docname'] and footnote['ids'][0] == ref['refid']:
|
||||||
ref.remove(ref[0])
|
ref.remove(ref[0])
|
||||||
ref += nodes.Text(str(num))
|
ref += nodes.Text(str(num))
|
||||||
|
|
||||||
@ -118,8 +143,7 @@ class FootnoteCollector(nodes.NodeVisitor):
|
|||||||
# type: (nodes.document) -> None
|
# type: (nodes.document) -> None
|
||||||
self.auto_footnotes = [] # type: List[nodes.footnote]
|
self.auto_footnotes = [] # type: List[nodes.footnote]
|
||||||
self.used_footnote_numbers = set() # type: Set[unicode]
|
self.used_footnote_numbers = set() # type: Set[unicode]
|
||||||
self.footnote_refs = {} # type: Dict[nodes.Node, List[nodes.footnote_reference]] # NOQA
|
self.footnote_refs = [] # type: List[nodes.footnote_reference]
|
||||||
self.current_document = [] # type: List[nodes.Node]
|
|
||||||
nodes.NodeVisitor.__init__(self, document)
|
nodes.NodeVisitor.__init__(self, document)
|
||||||
|
|
||||||
def unknown_visit(self, node):
|
def unknown_visit(self, node):
|
||||||
@ -130,33 +154,14 @@ class FootnoteCollector(nodes.NodeVisitor):
|
|||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def visit_document(self, node):
|
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
self.current_document.append(node)
|
|
||||||
|
|
||||||
def depart_document(self, node):
|
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
self.current_document.pop()
|
|
||||||
|
|
||||||
def visit_start_of_file(self, node):
|
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
self.current_document.append(node)
|
|
||||||
|
|
||||||
def depart_start_of_file(self, node):
|
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
self.current_document.pop()
|
|
||||||
|
|
||||||
def visit_footnote(self, node):
|
def visit_footnote(self, node):
|
||||||
# type: (nodes.footnote) -> None
|
# type: (nodes.footnote) -> None
|
||||||
document = self.current_document[-1]
|
|
||||||
if node.get('auto'):
|
if node.get('auto'):
|
||||||
self.auto_footnotes.append((document, node))
|
self.auto_footnotes.append(node)
|
||||||
else:
|
else:
|
||||||
for name in node['names']:
|
for name in node['names']:
|
||||||
self.used_footnote_numbers.add(name)
|
self.used_footnote_numbers.add(name)
|
||||||
|
|
||||||
def visit_footnote_reference(self, node):
|
def visit_footnote_reference(self, node):
|
||||||
# type: (nodes.footnote_reference) -> None
|
# type: (nodes.footnote_reference) -> None
|
||||||
document = self.current_document[-1]
|
self.footnote_refs.append(node)
|
||||||
footnote_refs = self.footnote_refs.setdefault(document, [])
|
|
||||||
footnote_refs.append(node)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user