comment out the unused legacy code

This commit is contained in:
Damien Elmes 2020-01-17 10:51:36 +10:00
parent d3cc63efb0
commit b1c2d271d3
2 changed files with 198 additions and 204 deletions

View file

@ -2,198 +2,208 @@
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
""" """
This file contains code that is no longer used by Anki, but left around This file contains code that is no longer used by Anki. It is left around
for the benefit of add-ons. It may go away in the future, so please copy for now as an example of how the stock field filters can be implemented using
any routines you need into your own add-on instead of using them directly the legacy addHook() API.
from this module.
If your add-on was previously calling anki.template.render(), you now
need to call anki.template.render_template(), passing col in as the first
argument.
""" """
from __future__ import annotations # from __future__ import annotations
#
import re # import re
from typing import Any, Callable # from typing import Any, Callable
#
from anki.lang import _ # from anki.lang import _
from anki.template import ( # from anki.template import (
CLOZE_REGEX_MATCH_GROUP_CONTENT, # CLOZE_REGEX_MATCH_GROUP_CONTENT,
CLOZE_REGEX_MATCH_GROUP_HINT, # CLOZE_REGEX_MATCH_GROUP_HINT,
CLOZE_REGEX_MATCH_GROUP_TAG, # CLOZE_REGEX_MATCH_GROUP_TAG,
clozeReg, # clozeReg,
) # )
from anki.utils import stripHTML # from anki.utils import stripHTML
#
# Cloze filter # # Cloze filter
########################################################################## # ##########################################################################
#
#
def _clozeText(txt: str, ord: str, type: str) -> str: # def _clozeText(txt: str, ord: str, type: str) -> str:
"""Process the given Cloze deletion within the given template.""" # """Process the given Cloze deletion within the given template."""
reg = clozeReg # reg = clozeReg
currentRegex = clozeReg % ord # currentRegex = clozeReg % ord
if not re.search(currentRegex, txt): # if not re.search(currentRegex, txt):
# No Cloze deletion was found in txt. # # No Cloze deletion was found in txt.
return "" # return ""
txt = _removeFormattingFromMathjax(txt, ord) # txt = _removeFormattingFromMathjax(txt, ord)
#
def repl(m): # def repl(m):
# replace chosen cloze with type # # replace chosen cloze with type
if type == "q": # if type == "q":
if m.group(CLOZE_REGEX_MATCH_GROUP_HINT): # if m.group(CLOZE_REGEX_MATCH_GROUP_HINT):
buf = "[%s]" % m.group(CLOZE_REGEX_MATCH_GROUP_HINT) # buf = "[%s]" % m.group(CLOZE_REGEX_MATCH_GROUP_HINT)
else: # else:
buf = "[...]" # buf = "[...]"
else: # else:
buf = m.group(CLOZE_REGEX_MATCH_GROUP_CONTENT) # buf = m.group(CLOZE_REGEX_MATCH_GROUP_CONTENT)
# uppercase = no formatting # # uppercase = no formatting
if m.group(CLOZE_REGEX_MATCH_GROUP_TAG) == "c": # if m.group(CLOZE_REGEX_MATCH_GROUP_TAG) == "c":
buf = "<span class=cloze>%s</span>" % buf # buf = "<span class=cloze>%s</span>" % buf
return buf # return buf
#
txt = re.sub(currentRegex, repl, txt) # txt = re.sub(currentRegex, repl, txt)
# and display other clozes normally # # and display other clozes normally
return re.sub(reg % r"\d+", "\\2", txt) # return re.sub(reg % r"\d+", "\\2", txt)
#
#
def _removeFormattingFromMathjax(txt, ord) -> str: # def _removeFormattingFromMathjax(txt, ord) -> str:
"""Marks all clozes within MathJax to prevent formatting them. # """Marks all clozes within MathJax to prevent formatting them.
#
Active Cloze deletions within MathJax should not be wrapped inside # Active Cloze deletions within MathJax should not be wrapped inside
a Cloze <span>, as that would interfere with MathJax. # a Cloze <span>, as that would interfere with MathJax.
#
This method finds all Cloze deletions number `ord` in `txt` which are # This method finds all Cloze deletions number `ord` in `txt` which are
inside MathJax inline or display formulas, and replaces their opening # inside MathJax inline or display formulas, and replaces their opening
'{{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>".
""" # """
creg = clozeReg.replace("(?si)", "") # creg = clozeReg.replace("(?si)", "")
#
# Scan the string left to right. # # Scan the string left to right.
# After a MathJax opening - \( or \[ - flip in_mathjax to True. # # After a MathJax opening - \( or \[ - flip in_mathjax to True.
# After a MathJax closing - \) or \] - flip in_mathjax to False. # # After a MathJax closing - \) or \] - flip in_mathjax to False.
# When a Cloze pattern number `ord` is found and we are in MathJax, # # When a Cloze pattern number `ord` is found and we are in MathJax,
# replace its '{{c' with '{{C'. # # replace its '{{c' with '{{C'.
# #
# # TODO: Report mismatching opens/closes - e.g. '\(\]'
# # TODO: Report errors in this method better than printing to stdout.
# # flags in middle of expression deprecated
# in_mathjax = False
#
# def replace(match):
# nonlocal in_mathjax
# if match.group("mathjax_open"):
# 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,
# )
#
# def test_remove_formatting_from_mathjax():
# assert _removeFormattingFromMathjax(r"\(2^{{c3::2}}\)", 3) == r"\(2^{{C3::2}}\)"
#
# txt = (
# r"{{c1::ok}} \(2^2\) {{c2::not ok}} \(2^{{c3::2}}\) \(x^3\) "
# r"{{c4::blah}} {{c5::text with \(x^2\) jax}}"
# )
# # Cloze 2 is not in MathJax, so it should not get protected against
# # formatting.
# assert _removeFormattingFromMathjax(txt, 2) == txt
#
# txt = r"\(a\) {{c1::b}} \[ {{c1::c}} \]"
# assert _removeFormattingFromMathjax(txt, 1) == (r"\(a\) {{c1::b}} \[ {{C1::c}} \]")
#
#
#
# def _cloze_filter(field_text: str, filter_args: str, q_or_a: str):
# return _clozeText(field_text, filter_args, q_or_a)
#
#
# def cloze_qfilter(field_text: str, filter_args: str, *args):
# return _cloze_filter(field_text, filter_args, "q")
#
#
# def cloze_afilter(field_text: str, filter_args: str, *args):
# return _cloze_filter(field_text, filter_args, "a")
#
# #
# TODO: Report mismatching opens/closes - e.g. '\(\]'
# TODO: Report errors in this method better than printing to stdout.
# flags in middle of expression deprecated
in_mathjax = False
def replace(match):
nonlocal in_mathjax
if match.group("mathjax_open"):
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,
)
def _cloze_filter(field_text: str, filter_args: str, q_or_a: str):
return _clozeText(field_text, filter_args, q_or_a)
def cloze_qfilter(field_text: str, filter_args: str, *args):
return _cloze_filter(field_text, filter_args, "q")
def cloze_afilter(field_text: str, filter_args: str, *args):
return _cloze_filter(field_text, filter_args, "a")
# addHook("fmod_cq", cloze_qfilter) # addHook("fmod_cq", cloze_qfilter)
# addHook("fmod_ca", cloze_afilter) # addHook("fmod_ca", cloze_afilter)
#
# Other filters # # Other filters
########################################################################## # ##########################################################################
#
#
def hint_filter(txt: str, args, context, tag: str, fullname) -> str: # def hint_filter(txt: str, args, context, tag: str, fullname) -> str:
if not txt.strip(): # if not txt.strip():
return "" # return ""
# random id # # random id
domid = "hint%d" % id(txt) # domid = "hint%d" % id(txt)
return """ # return """
<a class=hint href="#" # <a class=hint href="#"
onclick="this.style.display='none';document.getElementById('%s').style.display='block';return false;"> # onclick="this.style.display='none';document.getElementById('%s').style.display='block';return false;">
%s</a><div id="%s" class=hint style="display: none">%s</div> # %s</a><div id="%s" class=hint style="display: none">%s</div>
""" % ( # """ % (
domid, # domid,
_("Show %s") % tag, # _("Show %s") % tag,
domid, # domid,
txt, # txt,
) # )
#
#
FURIGANA_RE = r" ?([^ >]+?)\[(.+?)\]" # FURIGANA_RE = r" ?([^ >]+?)\[(.+?)\]"
RUBY_REPL = r"<ruby><rb>\1</rb><rt>\2</rt></ruby>" # RUBY_REPL = r"<ruby><rb>\1</rb><rt>\2</rt></ruby>"
#
#
def replace_if_not_audio(repl: str) -> Callable[[Any], Any]: # def replace_if_not_audio(repl: str) -> Callable[[Any], Any]:
def func(match): # def func(match):
if match.group(2).startswith("sound:"): # if match.group(2).startswith("sound:"):
# return without modification # # return without modification
return match.group(0) # return match.group(0)
else: # else:
return re.sub(FURIGANA_RE, repl, match.group(0)) # return re.sub(FURIGANA_RE, repl, match.group(0))
#
return func # return func
#
#
def without_nbsp(s: str) -> str: # def without_nbsp(s: str) -> str:
return s.replace("&nbsp;", " ") # return s.replace("&nbsp;", " ")
#
#
def kanji_filter(txt: str, *args) -> str: # def kanji_filter(txt: str, *args) -> str:
return re.sub(FURIGANA_RE, replace_if_not_audio(r"\1"), without_nbsp(txt)) # return re.sub(FURIGANA_RE, replace_if_not_audio(r"\1"), without_nbsp(txt))
#
#
def kana_filter(txt: str, *args) -> str: # def kana_filter(txt: str, *args) -> str:
return re.sub(FURIGANA_RE, replace_if_not_audio(r"\2"), without_nbsp(txt)) # return re.sub(FURIGANA_RE, replace_if_not_audio(r"\2"), without_nbsp(txt))
#
#
def furigana_filter(txt: str, *args) -> str: # def furigana_filter(txt: str, *args) -> str:
return re.sub(FURIGANA_RE, replace_if_not_audio(RUBY_REPL), without_nbsp(txt)) # return re.sub(FURIGANA_RE, replace_if_not_audio(RUBY_REPL), without_nbsp(txt))
#
#
def text_filter(txt: str, *args) -> str: # def text_filter(txt: str, *args) -> str:
return stripHTML(txt) # return stripHTML(txt)
#
#
def type_answer_filter(txt: str, filter_args: str, context, tag: str, dummy) -> str: # def type_answer_filter(txt: str, filter_args: str, context, tag: str, dummy) -> str:
# convert it to [[type:...]] for the gui code to process # # convert it to [[type:...]] for the gui code to process
if filter_args: # if filter_args:
return f"[[type:{filter_args}:{tag}]]" # return f"[[type:{filter_args}:{tag}]]"
else: # else:
return f"[[type:{tag}]]" # return f"[[type:{tag}]]"
#
#
# addHook("fmod_text", text_filter) # addHook("fmod_text", text_filter)
# addHook("fmod_type", type_answer_filter) # addHook("fmod_type", type_answer_filter)
# addHook("fmod_hint", hint_filter) # addHook("fmod_hint", hint_filter)

View file

@ -1,22 +1,6 @@
from anki.template_legacy import _removeFormattingFromMathjax
from tests.shared import getEmptyCol from tests.shared import getEmptyCol
def test_remove_formatting_from_mathjax():
assert _removeFormattingFromMathjax(r"\(2^{{c3::2}}\)", 3) == r"\(2^{{C3::2}}\)"
txt = (
r"{{c1::ok}} \(2^2\) {{c2::not ok}} \(2^{{c3::2}}\) \(x^3\) "
r"{{c4::blah}} {{c5::text with \(x^2\) jax}}"
)
# Cloze 2 is not in MathJax, so it should not get protected against
# formatting.
assert _removeFormattingFromMathjax(txt, 2) == txt
txt = r"\(a\) {{c1::b}} \[ {{c1::c}} \]"
assert _removeFormattingFromMathjax(txt, 1) == (r"\(a\) {{c1::b}} \[ {{C1::c}} \]")
def test_deferred_frontside(): def test_deferred_frontside():
d = getEmptyCol() d = getEmptyCol()
m = d.models.current() m = d.models.current()