mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #6467 from tk0miya/refactor_math
refactor: Add data accessors to MathDomain
This commit is contained in:
commit
564d23be7a
2
CHANGES
2
CHANGES
@ -10,6 +10,8 @@ Incompatible changes
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
* ``sphinx.domains.math.MathDomain.add_equation()``
|
||||
* ``sphinx.domains.math.MathDomain.get_next_equation_number()``
|
||||
* The ``info`` and ``warn`` arguments of
|
||||
``sphinx.ext.autosummary.generate.generate_autosummary_docs()``
|
||||
* ``sphinx.ext.autosummary.generate._simple_info()``
|
||||
|
@ -26,6 +26,16 @@ The following is a list of deprecated interfaces.
|
||||
- (will be) Removed
|
||||
- Alternatives
|
||||
|
||||
* - ``sphinx.domains.math.MathDomain.add_equation()``
|
||||
- 2.2
|
||||
- 4.0
|
||||
- ``sphinx.domains.math.MathDomain.note_equation()``
|
||||
|
||||
* - ``sphinx.domains.math.MathDomain.get_next_equation_number()``
|
||||
- 2.2
|
||||
- 4.0
|
||||
- ``sphinx.domains.math.MathDomain.note_equation()``
|
||||
|
||||
* - The ``info`` and ``warn`` arguments of
|
||||
``sphinx.ext.autosummary.generate.generate_autosummary_docs()``
|
||||
- 2.2
|
||||
|
@ -16,6 +16,7 @@ from docutils.parsers.rst.directives import images, html, tables
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.directives import optional_int
|
||||
from sphinx.domains.math import MathDomain
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import set_source_info
|
||||
|
||||
@ -194,18 +195,15 @@ class MathDirective(SphinxDirective):
|
||||
return
|
||||
|
||||
# register label to domain
|
||||
domain = self.env.get_domain('math')
|
||||
try:
|
||||
eqno = domain.add_equation(self.env, self.env.docname, node['label']) # type: ignore # NOQA
|
||||
node['number'] = eqno
|
||||
domain = cast(MathDomain, self.env.get_domain('math'))
|
||||
domain.note_equation(self.env.docname, node['label'], location=node)
|
||||
node['number'] = domain.get_equation_number_for(node['label'])
|
||||
|
||||
# add target node
|
||||
node_id = make_id('equation-%s' % node['label'])
|
||||
target = nodes.target('', '', ids=[node_id])
|
||||
self.state.document.note_explicit_target(target)
|
||||
ret.insert(0, target)
|
||||
except UserWarning as exc:
|
||||
self.state_machine.reporter.warning(exc, line=self.lineno)
|
||||
# add target node
|
||||
node_id = make_id('equation-%s' % node['label'])
|
||||
target = nodes.target('', '', ids=[node_id])
|
||||
self.state.document.note_explicit_target(target)
|
||||
ret.insert(0, target)
|
||||
|
||||
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
|
@ -8,10 +8,13 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import warnings
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import make_id
|
||||
|
||||
from sphinx.addnodes import math_block as displaymath
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.locale import __
|
||||
from sphinx.roles import XRefRole
|
||||
@ -44,7 +47,7 @@ class MathDomain(Domain):
|
||||
initial_data = {
|
||||
'objects': {}, # labelid -> (docname, eqno)
|
||||
'has_equations': {}, # docname -> bool
|
||||
} # type: Dict[str, Dict[str, Tuple[str, int]]]
|
||||
} # type: Dict
|
||||
dangling_warnings = {
|
||||
'eq': 'equation not found: %(target)s',
|
||||
}
|
||||
@ -56,6 +59,27 @@ class MathDomain(Domain):
|
||||
'numref': MathReferenceRole(),
|
||||
}
|
||||
|
||||
@property
|
||||
def equations(self):
|
||||
# type: () -> Dict[str, Tuple[str, int]]
|
||||
return self.data.setdefault('objects', {}) # labelid -> (docname, eqno)
|
||||
|
||||
def note_equation(self, docname, labelid, location=None):
|
||||
# type: (str, str, Any) -> None
|
||||
if labelid in self.equations:
|
||||
other = self.equations[labelid][0]
|
||||
logger.warning(__('duplicate label of equation %s, other instance in %s') %
|
||||
(labelid, other), location=location)
|
||||
|
||||
self.equations[labelid] = (docname, self.env.new_serialno('eqno') + 1)
|
||||
|
||||
def get_equation_number_for(self, labelid):
|
||||
# type: (str) -> int
|
||||
if labelid in self.equations:
|
||||
return self.equations[labelid][1]
|
||||
else:
|
||||
return None
|
||||
|
||||
def process_doc(self, env, docname, document):
|
||||
# type: (BuildEnvironment, str, nodes.document) -> None
|
||||
def math_node(node):
|
||||
@ -66,9 +90,9 @@ class MathDomain(Domain):
|
||||
|
||||
def clear_doc(self, docname):
|
||||
# type: (str) -> None
|
||||
for equation_id, (doc, eqno) in list(self.data['objects'].items()):
|
||||
for equation_id, (doc, eqno) in list(self.equations.items()):
|
||||
if doc == docname:
|
||||
del self.data['objects'][equation_id]
|
||||
del self.equations[equation_id]
|
||||
|
||||
self.data['has_equations'].pop(docname, None)
|
||||
|
||||
@ -76,7 +100,7 @@ class MathDomain(Domain):
|
||||
# type: (Iterable[str], Dict) -> None
|
||||
for labelid, (doc, eqno) in otherdata['objects'].items():
|
||||
if doc in docnames:
|
||||
self.data['objects'][labelid] = (doc, eqno)
|
||||
self.equations[labelid] = (doc, eqno)
|
||||
|
||||
for docname in docnames:
|
||||
self.data['has_equations'][docname] = otherdata['has_equations'][docname]
|
||||
@ -84,19 +108,22 @@ class MathDomain(Domain):
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, str, Builder, str, str, addnodes.pending_xref, nodes.Element) -> nodes.Element # NOQA
|
||||
assert typ in ('eq', 'numref')
|
||||
docname, number = self.data['objects'].get(target, (None, None))
|
||||
docname, number = self.equations.get(target, (None, None))
|
||||
if docname:
|
||||
# TODO: perhaps use rather a sphinx-core provided prefix here?
|
||||
node_id = make_id('equation-%s' % target)
|
||||
if env.config.math_numfig and env.config.numfig:
|
||||
if docname in env.toc_fignumbers:
|
||||
number = env.toc_fignumbers[docname]['displaymath'].get(node_id, ())
|
||||
number = '.'.join(map(str, number))
|
||||
numbers = env.toc_fignumbers[docname]['displaymath'].get(node_id, ())
|
||||
eqno = '.'.join(map(str, numbers))
|
||||
else:
|
||||
number = ''
|
||||
eqno = ''
|
||||
else:
|
||||
eqno = str(number)
|
||||
|
||||
try:
|
||||
eqref_format = env.config.math_eqref_format or "({number})"
|
||||
title = nodes.Text(eqref_format.format(number=number))
|
||||
title = nodes.Text(eqref_format.format(number=eqno))
|
||||
except KeyError as exc:
|
||||
logger.warning(__('Invalid math_eqref_format: %r'), exc,
|
||||
location=node)
|
||||
@ -120,19 +147,22 @@ class MathDomain(Domain):
|
||||
|
||||
def add_equation(self, env, docname, labelid):
|
||||
# type: (BuildEnvironment, str, str) -> int
|
||||
equations = self.data['objects']
|
||||
if labelid in equations:
|
||||
path = env.doc2path(equations[labelid][0])
|
||||
warnings.warn('MathDomain.add_equation() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
if labelid in self.equations:
|
||||
path = env.doc2path(self.equations[labelid][0])
|
||||
msg = __('duplicate label of equation %s, other instance in %s') % (labelid, path)
|
||||
raise UserWarning(msg)
|
||||
else:
|
||||
eqno = self.get_next_equation_number(docname)
|
||||
equations[labelid] = (docname, eqno)
|
||||
self.equations[labelid] = (docname, eqno)
|
||||
return eqno
|
||||
|
||||
def get_next_equation_number(self, docname):
|
||||
# type: (str) -> int
|
||||
targets = [eq for eq in self.data['objects'].values() if eq[0] == docname]
|
||||
warnings.warn('MathDomain.get_next_equation_number() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
targets = [eq for eq in self.equations.values() if eq[0] == docname]
|
||||
return len(targets) + 1
|
||||
|
||||
def has_equations(self):
|
||||
|
@ -52,3 +52,35 @@ def test_code_directive(app):
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, [nodes.document, nodes.literal_block, 'print("hello world")'])
|
||||
assert_node(doctree[0], language="python", linenos=True, highlight_args={'linenostart': 5})
|
||||
|
||||
|
||||
def test_math_directive(app):
|
||||
# normal case
|
||||
text = '.. math:: E = mc^2'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, [nodes.document, nodes.math_block, 'E = mc^2\n\n'])
|
||||
|
||||
# :name: option
|
||||
text = ('.. math:: E = mc^2\n'
|
||||
' :name: eq1\n')
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, [nodes.document, (nodes.target,
|
||||
[nodes.math_block, "E = mc^2\n\n"])])
|
||||
assert_node(doctree[1], nodes.math_block, docname='index', label="eq1", number=1)
|
||||
|
||||
# :label: option
|
||||
text = ('.. math:: E = mc^2\n'
|
||||
' :label: eq2\n')
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, [nodes.document, (nodes.target,
|
||||
[nodes.math_block, 'E = mc^2\n\n'])])
|
||||
assert_node(doctree[1], nodes.math_block, docname='index', label="eq2", number=2)
|
||||
|
||||
# :label: option without value
|
||||
text = ('.. math:: E = mc^2\n'
|
||||
' :label:\n')
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, [nodes.document, (nodes.target,
|
||||
[nodes.math_block, 'E = mc^2\n\n'])])
|
||||
assert_node(doctree[1], nodes.math_block, ids=['equation-index-0'],
|
||||
docname='index', label="index:0", number=3)
|
||||
|
Loading…
Reference in New Issue
Block a user