mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
clean up _renderQA(), and split rendering part out
This commit is contained in:
parent
fb5e6f3d01
commit
4bca26161b
2 changed files with 78 additions and 38 deletions
|
@ -29,8 +29,8 @@ from anki.notes import Note
|
||||||
from anki.rsbackend import RustBackend
|
from anki.rsbackend import RustBackend
|
||||||
from anki.sched import Scheduler as V1Scheduler
|
from anki.sched import Scheduler as V1Scheduler
|
||||||
from anki.schedv2 import Scheduler as V2Scheduler
|
from anki.schedv2 import Scheduler as V2Scheduler
|
||||||
from anki.sound import stripSounds
|
|
||||||
from anki.tags import TagManager
|
from anki.tags import TagManager
|
||||||
|
from anki.template2 import renderFromFieldMap
|
||||||
from anki.types import NoteType, QAData, Template
|
from anki.types import NoteType, QAData, Template
|
||||||
from anki.utils import (
|
from anki.utils import (
|
||||||
devMode,
|
devMode,
|
||||||
|
@ -629,51 +629,58 @@ where c.nid = n.id and c.id in %s group by nid"""
|
||||||
raise Exception()
|
raise Exception()
|
||||||
return [self._renderQA(*row) for row in self._qaData(where)]
|
return [self._renderQA(*row) for row in self._qaData(where)]
|
||||||
|
|
||||||
def _renderQA(self, data: QAData, qfmt: None = None, afmt: None = None) -> Dict:
|
|
||||||
"Returns hash of id, question, answer."
|
|
||||||
# data is [cid, nid, mid, did, ord, tags, flds, cardFlags]
|
# data is [cid, nid, mid, did, ord, tags, flds, cardFlags]
|
||||||
# unpack fields and create dict
|
def _renderQA(
|
||||||
flist = splitFields(data[6])
|
self, data: QAData, qfmt: Optional[str] = None, afmt: Optional[str] = None
|
||||||
fields = {}
|
) -> Dict[str, Union[str, int]]:
|
||||||
|
"Returns hash of id, question, answer."
|
||||||
|
# extract info from data
|
||||||
|
split_fields = splitFields(data[6])
|
||||||
|
card_ord = data[4]
|
||||||
model = self.models.get(data[2])
|
model = self.models.get(data[2])
|
||||||
assert model
|
|
||||||
for (name, (idx, conf)) in list(self.models.fieldMap(model).items()):
|
|
||||||
fields[name] = flist[idx]
|
|
||||||
fields["Tags"] = data[5].strip()
|
|
||||||
fields["Type"] = model["name"]
|
|
||||||
fields["Deck"] = self.decks.name(data[3])
|
|
||||||
fields["Subdeck"] = fields["Deck"].split("::")[-1]
|
|
||||||
fields["CardFlag"] = self._flagNameFromCardFlags(data[7])
|
|
||||||
if model["type"] == MODEL_STD:
|
if model["type"] == MODEL_STD:
|
||||||
template = model["tmpls"][data[4]]
|
template = model["tmpls"][data[4]]
|
||||||
else:
|
else:
|
||||||
template = model["tmpls"][0]
|
template = model["tmpls"][0]
|
||||||
fields["Card"] = template["name"]
|
flag = data[7]
|
||||||
fields["c%d" % (data[4] + 1)] = "1"
|
deck_id = data[3]
|
||||||
# render q & a
|
card_id = data[0]
|
||||||
d: Dict[str, Any] = dict(id=data[0])
|
tags = data[5]
|
||||||
qfmt = qfmt or template["qfmt"]
|
qfmt = qfmt or template["qfmt"]
|
||||||
afmt = afmt or template["afmt"]
|
afmt = afmt or template["afmt"]
|
||||||
for (type, format) in (("q", qfmt), ("a", afmt)):
|
|
||||||
if type == "q":
|
# create map of field names -> field content
|
||||||
format = re.sub(
|
fields: Dict[str, str] = {}
|
||||||
"{{(?!type:)(.*?)cloze:", r"{{\1cq-%d:" % (data[4] + 1), format
|
for (name, (idx, conf)) in list(self.models.fieldMap(model).items()):
|
||||||
)
|
fields[name] = split_fields[idx]
|
||||||
format = format.replace("<%cloze:", "<%%cq:%d:" % (data[4] + 1))
|
|
||||||
else:
|
# add special fields
|
||||||
format = re.sub("{{(.*?)cloze:", r"{{\1ca-%d:" % (data[4] + 1), format)
|
fields["Tags"] = tags.strip()
|
||||||
format = format.replace("<%cloze:", "<%%ca:%d:" % (data[4] + 1))
|
fields["Type"] = model["name"]
|
||||||
fields["FrontSide"] = stripSounds(d["q"])
|
fields["Deck"] = self.decks.name(deck_id)
|
||||||
|
fields["Subdeck"] = fields["Deck"].split("::")[-1]
|
||||||
|
fields["Card"] = template["name"]
|
||||||
|
fields["CardFlag"] = self._flagNameFromCardFlags(flag)
|
||||||
|
fields["c%d" % (card_ord + 1)] = "1"
|
||||||
|
|
||||||
fields = runFilter("mungeFields", fields, model, data, self)
|
fields = runFilter("mungeFields", fields, model, data, self)
|
||||||
html = anki.template.render(format, fields)
|
|
||||||
d[type] = runFilter("mungeQA", html, type, fields, model, data, self)
|
# render fields
|
||||||
|
qatext = renderFromFieldMap(qfmt, afmt, fields, card_ord)
|
||||||
|
ret: Dict[str, Any] = dict(q=qatext[0], a=qatext[1], id=card_id)
|
||||||
|
|
||||||
|
# allow add-ons to modify the generated result
|
||||||
|
for type in "q", "a":
|
||||||
|
ret[type] = runFilter("mungeQA", ret[type], type, fields, model, data, self)
|
||||||
|
|
||||||
# empty cloze?
|
# empty cloze?
|
||||||
if type == "q" and model["type"] == MODEL_CLOZE:
|
if type == "q" and model["type"] == MODEL_CLOZE:
|
||||||
if not self.models._availClozeOrds(model, data[6], False):
|
if not self.models._availClozeOrds(model, data[6], False):
|
||||||
d["q"] += "<p>" + _(
|
ret["q"] += "<p>" + _(
|
||||||
"Please edit this note and add some cloze deletions. (%s)"
|
"Please edit this note and add some cloze deletions. (%s)"
|
||||||
) % ("<a href=%s#cloze>%s</a>" % (HELP_SITE, _("help")))
|
) % ("<a href=%s#cloze>%s</a>" % (HELP_SITE, _("help")))
|
||||||
return d
|
|
||||||
|
return ret
|
||||||
|
|
||||||
def _qaData(self, where="") -> Any:
|
def _qaData(self, where="") -> Any:
|
||||||
"Return [cid, nid, mid, did, ord, tags, flds, cardFlags] db query"
|
"Return [cid, nid, mid, did, ord, tags, flds, cardFlags] db query"
|
||||||
|
|
33
pylib/anki/template2.py
Normal file
33
pylib/anki/template2.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
"""
|
||||||
|
This file contains some code related to templates that is not directly
|
||||||
|
connected to pystache. It may be renamed in the future.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from typing import Dict, Tuple
|
||||||
|
|
||||||
|
import anki
|
||||||
|
from anki.sound import stripSounds
|
||||||
|
|
||||||
|
|
||||||
|
def renderFromFieldMap(
|
||||||
|
qfmt: str, afmt: str, fields: Dict[str, str], card_ord: int
|
||||||
|
) -> Tuple[str, str]:
|
||||||
|
"Renders the provided templates, returning rendered q & a text."
|
||||||
|
# question
|
||||||
|
format = re.sub("{{(?!type:)(.*?)cloze:", r"{{\1cq-%d:" % (card_ord + 1), qfmt)
|
||||||
|
format = format.replace("<%cloze:", "<%%cq:%d:" % (card_ord + 1))
|
||||||
|
qtext = anki.template.render(format, fields)
|
||||||
|
|
||||||
|
# answer
|
||||||
|
format = re.sub("{{(.*?)cloze:", r"{{\1ca-%d:" % (card_ord + 1), afmt)
|
||||||
|
format = format.replace("<%cloze:", "<%%ca:%d:" % (card_ord + 1))
|
||||||
|
fields["FrontSide"] = stripSounds(qtext)
|
||||||
|
atext = anki.template.render(format, fields)
|
||||||
|
|
||||||
|
return qtext, atext
|
Loading…
Reference in a new issue