Fix bug in _removeFormattingFromMathjax

This commit is contained in:
Michal Pokorný (Rai) 2019-12-22 05:47:45 +01:00
parent 331781cf45
commit 2d2f21bfe3
3 changed files with 41 additions and 36 deletions

View file

@ -232,34 +232,45 @@ class Template:
'{{c123' with a '{{C123'. The clozeText method interprets the upper-case '{{c123' with a '{{C123'. The clozeText method interprets the upper-case
C as "don't wrap this Cloze in a <span>". C as "don't wrap this Cloze in a <span>".
""" """
# TODO: There is a bug in this method.
# Say txt = r'\(a\) {{c1::b}} \[ {{c1::c}} \]', ord = 1.
#
# This method should return: '\(a\) {{c1::b}} \[ {{C1::c}} \]'.
# Since the {{c1::c}} occurs within a MathJax display formula.
# However, it returns '\(a\) {{c1::b}} \[ {{c1::c}} \]'.
# This causes the Cloze within the MathJax display formula
# to be erroneously formatted with a <span>.
opening = ["\\(", "\\["]
closing = ["\\)", "\\]"]
# flags in middle of expression deprecated
creg = clozeReg.replace("(?si)", "") creg = clozeReg.replace("(?si)", "")
regex = r"(?si)(\\[([])(.*?)"+(creg%ord)+r"(.*?)(\\[\])])"
def repl(m): # Scan the string left to right.
enclosed = True # After a MathJax opening - \( or \[ - flip in_mathjax to True.
for s in closing: # After a MathJax closing - \) or \] - flip in_mathjax to False.
if s in m.group(1): # When a Cloze pattern number `ord` is found and we are in MathJax,
enclosed = False # replace its '{{c' with '{{C'.
for s in opening: #
if s in m.group(7): # TODO: Report mismatching opens/closes - e.g. '\(\]'
enclosed = False # TODO: Report errors in this method better than printing to stdout.
if not enclosed: # flags in middle of expression deprecated
return m.group(0) in_mathjax = False
# remove formatting def replace(match):
return m.group(0).replace("{{c", "{{C") nonlocal in_mathjax
txt = re.sub(regex, repl, txt) if match.group('mathjax_open'):
return txt if in_mathjax:
print("MathJax opening found while already in MathJax")
in_mathjax = True
elif match.group('mathjax_close'):
if not in_mathjax:
print("MathJax close found while not in MathJax")
in_mathjax = False
elif match.group('cloze'):
if in_mathjax:
return match.group(0).replace(
'{{c{}::'.format(ord),
'{{C{}::'.format(ord))
else:
print("Unexpected: no expected capture group is present")
return match.group(0)
# The following regex matches one of:
# - MathJax opening
# - MathJax close
# - Cloze deletion number `ord`
return re.sub(
r"(?si)"
r"(?P<mathjax_open>\\[([])|"
r"(?P<mathjax_close>\\[\])])|"
r"(?P<cloze>" + (creg%ord) + ")", replace, txt)
@modifier('=') @modifier('=')
def render_delimiter(self, tag_name=None, context=None) -> str: def render_delimiter(self, tag_name=None, context=None) -> str:

View file

@ -199,18 +199,12 @@ def test_cloze_mathjax():
assert "class=cloze" in f.cards()[3].q() assert "class=cloze" in f.cards()[3].q()
assert "class=cloze" in f.cards()[4].q() assert "class=cloze" in f.cards()[4].q()
def test_cloze_mathjax_bug():
d = getEmptyCol()
d.models.setCurrent(d.models.byName("Cloze"))
f = d.newNote() f = d.newNote()
f['Text'] = r'\(a\) {{c1::b}} \[ {{c1::c}} \]' f['Text'] = r'\(a\) {{c1::b}} \[ {{c1::c}} \]'
assert d.addNote(f) assert d.addNote(f)
assert len(f.cards()) == 1 assert len(f.cards()) == 1
assert f.cards()[0].q().endswith('\(a\) <span class=cloze>[...]</span> \[ [...] \]')
# TODO: The following assertion should work, but currently fails due
# to a bug in _removeFormatingFromMathjax.
# assert f.cards()[0].q() == '\(a\) <span class=cloze>[...]</span> \[ [...] \]'
def test_chained_mods(): def test_chained_mods():
d = getEmptyCol() d = getEmptyCol()

View file

@ -11,6 +11,6 @@ def test_remove_formatting_from_mathjax():
# formatting. # formatting.
assert t._removeFormattingFromMathjax(txt, 2) == txt assert t._removeFormattingFromMathjax(txt, 2) == txt
# TODO: r'\(a\) {{c1::b}} \[ {{c1::c}} \]', ord=1 should return txt = r'\(a\) {{c1::b}} \[ {{c1::c}} \]'
# r'\(a\) {{c1::b}} \[ {{C1::c}} \]', but actually fails to mark the cloze assert t._removeFormattingFromMathjax(txt, 1) == (
# as not-to-be-formatted. r'\(a\) {{c1::b}} \[ {{C1::c}} \]')