Fix #4438: math: math with labels with whitespace cause html error

This commit is contained in:
Takeshi KOMIYA 2018-01-19 23:12:25 +09:00
parent f9a53f50c6
commit f91c732749
3 changed files with 13 additions and 9 deletions

View File

@ -18,6 +18,7 @@ Bugs fixed
* #1922: html search: Upper characters problem in French * #1922: html search: Upper characters problem in French
* #4412: Updated jQuery version from 3.1.0 to 3.2.1 * #4412: Updated jQuery version from 3.1.0 to 3.2.1
* #4438: math: math with labels with whitespace cause html error
Testing Testing
-------- --------

View File

@ -10,6 +10,7 @@
""" """
from docutils import nodes, utils from docutils import nodes, utils
from docutils.nodes import make_id
from docutils.parsers.rst import Directive, directives from docutils.parsers.rst import Directive, directives
from sphinx.roles import XRefRole from sphinx.roles import XRefRole
@ -51,7 +52,8 @@ class MathDomain(Domain):
label = 'mathematics' label = 'mathematics'
initial_data = { initial_data = {
'objects': {}, # labelid -> (docname, eqno) 'nameids': {}, # label -> equation ID
'objects': {}, # equation ID -> (docname, eqno)
} # type: Dict[unicode, Dict[unicode, Tuple[unicode, int]]] } # type: Dict[unicode, Dict[unicode, Tuple[unicode, int]]]
dangling_warnings = { dangling_warnings = {
'eq': 'equation not found: %(target)s', 'eq': 'equation not found: %(target)s',
@ -59,9 +61,9 @@ class MathDomain(Domain):
def clear_doc(self, docname): def clear_doc(self, docname):
# type: (unicode) -> None # type: (unicode) -> None
for labelid, (doc, eqno) in list(self.data['objects'].items()): for equation_id, (doc, eqno) in list(self.data['objects'].items()):
if doc == docname: if doc == docname:
del self.data['objects'][labelid] del self.data['objects'][equation_id]
def merge_domaindata(self, docnames, otherdata): def merge_domaindata(self, docnames, otherdata):
# type: (Iterable[unicode], Dict) -> None # type: (Iterable[unicode], Dict) -> None
@ -81,8 +83,8 @@ class MathDomain(Domain):
return newnode return newnode
else: else:
title = nodes.Text("(%d)" % number) title = nodes.Text("(%d)" % number)
return make_refnode(builder, fromdocname, docname, node_id = make_id('equation-%s' % target)
"equation-" + target, title) return make_refnode(builder, fromdocname, docname, node_id, title)
else: else:
return None return None
@ -226,7 +228,8 @@ class MathDirective(Directive):
node['number'] = eqno node['number'] = eqno
# add target node # add target node
target = nodes.target('', '', ids=['equation-' + node['label']]) node_id = make_id('equation-%s' % node['label'])
target = nodes.target('', '', ids=[node_id])
self.state.document.note_explicit_target(target) self.state.document.note_explicit_target(target)
ret.insert(0, target) ret.insert(0, target)
except UserWarning as exc: except UserWarning as exc:

View File

@ -27,9 +27,9 @@ def test_jsmath(app, status, warning):
assert (u'<span class="eqno">(1)<a class="headerlink" href="#equation-foo" ' assert (u'<span class="eqno">(1)<a class="headerlink" href="#equation-foo" '
u'title="Permalink to this equation">\xb6</a></span>' u'title="Permalink to this equation">\xb6</a></span>'
u'<div class="math" id="equation-foo">\ne^{i\\pi} = 1</div>' in content) u'<div class="math" id="equation-foo">\ne^{i\\pi} = 1</div>' in content)
assert (u'<span class="eqno">(2)<a class="headerlink" href="#equation-math:0" ' assert (u'<span class="eqno">(2)<a class="headerlink" href="#equation-math-0" '
u'title="Permalink to this equation">\xb6</a></span>' u'title="Permalink to this equation">\xb6</a></span>'
u'<div class="math" id="equation-math:0">\n' u'<div class="math" id="equation-math-0">\n'
u'e^{ix} = \\cos x + i\\sin x</div>' in content) u'e^{ix} = \\cos x + i\\sin x</div>' in content)
assert '<div class="math">\nn \\in \\mathbb N</div>' in content assert '<div class="math">\nn \\in \\mathbb N</div>' in content
assert '<div class="math">\na + 1 &lt; b</div>' in content assert '<div class="math">\na + 1 &lt; b</div>' in content
@ -85,7 +85,7 @@ def test_math_number_all_mathjax(app, status, warning):
app.builder.build_all() app.builder.build_all()
content = (app.outdir / 'index.html').text() content = (app.outdir / 'index.html').text()
html = (r'<div class="math" id="equation-index:0">\s*' html = (r'<div class="math" id="equation-index-0">\s*'
r'<span class="eqno">\(1\)<a .*>\xb6</a></span>\\\[a\^2\+b\^2=c\^2\\\]</div>') r'<span class="eqno">\(1\)<a .*>\xb6</a></span>\\\[a\^2\+b\^2=c\^2\\\]</div>')
assert re.search(html, content, re.S) assert re.search(html, content, re.S)