Пример #1
0
    def render(self) -> TemplateRenderOutput:
        try:
            partial = self._partially_render()
        except TemplateError as e:
            return TemplateRenderOutput(
                question_text=str(e),
                answer_text=str(e),
                question_av_tags=[],
                answer_av_tags=[],
            )

        qtext = apply_custom_filters(partial.qnodes, self, front_side=None)
        qout = self.col()._backend.extract_av_tags(text=qtext,
                                                   question_side=True)

        atext = apply_custom_filters(partial.anodes,
                                     self,
                                     front_side=qout.text)
        aout = self.col()._backend.extract_av_tags(text=atext,
                                                   question_side=False)

        output = TemplateRenderOutput(
            question_text=qout.text,
            answer_text=aout.text,
            question_av_tags=av_tags_to_native(qout.av_tags),
            answer_av_tags=av_tags_to_native(aout.av_tags),
            css=self.note_type()["css"],
        )

        if not self._browser:
            hooks.card_did_render(output, self)

        return output
Пример #2
0
    def render(self) -> TemplateRenderOutput:
        try:
            partial = self._partially_render()
        except anki.rsbackend.TemplateError as e:
            return TemplateRenderOutput(
                question_text=str(e),
                answer_text=str(e),
                question_av_tags=[],
                answer_av_tags=[],
            )

        qtext = apply_custom_filters(partial.qnodes, self, front_side=None)
        qtext, q_avtags = self.col().backend.extract_av_tags(qtext, True)

        atext = apply_custom_filters(partial.anodes, self, front_side=qtext)
        atext, a_avtags = self.col().backend.extract_av_tags(atext, False)

        output = TemplateRenderOutput(
            question_text=qtext,
            answer_text=atext,
            question_av_tags=q_avtags,
            answer_av_tags=a_avtags,
            css=self.note_type()["css"],
        )

        if not self._browser:
            hooks.card_did_render(output, self)

        return output
Пример #3
0
def render_card(col: anki.storage._Collection, card: Card, note: Note,
                browser: bool) -> TemplateRenderOutput:
    "Render a card."
    # collect data
    fields = fields_for_rendering(col, card, note)
    qfmt, afmt = templates_for_card(card, browser)
    ctx = TemplateRenderContext(col=col,
                                card=card,
                                note=note,
                                fields=fields,
                                qfmt=qfmt,
                                afmt=afmt)

    # render
    try:
        output = render_card_from_context(ctx)
    except anki.rsbackend.TemplateError as e:
        output = TemplateRenderOutput(
            question_text=str(e),
            answer_text=str(e),
            question_av_tags=[],
            answer_av_tags=[],
        )

    hooks.card_did_render(output, ctx)

    return output
Пример #4
0
def render_card(col: anki.storage._Collection, card: Card, note: Note,
                browser: bool) -> TemplateRenderOutput:
    "Render a card."
    # collect data
    fields = fields_for_rendering(col, card, note)
    qfmt, afmt = templates_for_card(card, browser)
    ctx = TemplateRenderContext(col=col,
                                card=card,
                                note=note,
                                fields=fields,
                                qfmt=qfmt,
                                afmt=afmt)

    # render
    try:
        output = render_card_from_context(ctx)
    except anki.rsbackend.BackendException as e:
        errmsg = _("Card template has a problem:") + f"<br>{e}"
        output = TemplateRenderOutput(
            question_text=errmsg,
            answer_text=errmsg,
            question_av_tags=[],
            answer_av_tags=[],
        )

    if not output.question_text.strip():
        msg = _("The front of this card is blank.")
        help = _("More info")
        helplink = CARD_BLANK_HELP
        msg += f"<br><a href='{helplink}'>{help}</a>"
        output.question_text = msg

    hooks.card_did_render(output, ctx)

    return output
Пример #5
0
    def _renderQA(self,
                  data: QAData,
                  qfmt: Optional[str] = None,
                  afmt: Optional[str] = None) -> 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])
        if model["type"] == MODEL_STD:
            template = model["tmpls"][data[4]]
        else:
            template = model["tmpls"][0]
        flag = data[7]
        deck_id = data[3]
        card_id = data[0]
        tags = data[5]
        qfmt = qfmt or template["qfmt"]
        afmt = afmt or template["afmt"]

        # create map of field names -> field content
        fields: Dict[str, str] = {}
        for (name, (idx, conf)) in list(self.models.fieldMap(model).items()):
            fields[name] = split_fields[idx]

        # add special fields
        fields["Tags"] = tags.strip()
        fields["Type"] = model["name"]
        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"

        # legacy
        fields = runFilter("mungeFields", fields, model, data, self)

        # allow add-ons to modify the available fields & templates
        (qfmt, afmt) = hooks.card_will_render((qfmt, afmt), fields, model,
                                              data)

        # render fields
        qatext = render_card(self, 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] = hooks.card_did_render(ret[type], type, fields, model,
                                              data, self)

        # empty cloze?
        if type == "q" and model["type"] == MODEL_CLOZE:
            if not self.models._availClozeOrds(model, data[6], False):
                ret["q"] += "<p>" + _(
                    "Please edit this note and add some cloze deletions. (%s)"
                ) % ("<a href=%s#cloze>%s</a>" % (HELP_SITE, _("help")))

        return ret
Пример #6
0
def render_card(col: anki.storage._Collection, card: Card, note: Note,
                browser: bool) -> TemplateRenderOutput:
    "Render a card."
    # collect data
    fields = fields_for_rendering(col, card, note)
    qfmt, afmt = templates_for_card(card, browser)
    ctx = TemplateRenderContext(col=col,
                                card=card,
                                note=note,
                                fields=fields,
                                qfmt=qfmt,
                                afmt=afmt)

    # render
    try:
        output = render_card_from_context(ctx)
    except anki.rsbackend.BackendException as e:
        # fixme: specific exception in 2.1.21
        err = e.args[0].template_parse  # pylint: disable=no-member
        if err.q_side:
            side = _("Front")
        else:
            side = _("Back")
        errmsg = _("{} template has a problem:").format(side) + f"<br>{e}"
        errmsg += "<br><a href=https://anki.tenderapp.com/kb/problems/card-template-has-a-problem>{}</a>".format(
            _("More info"))
        output = TemplateRenderOutput(
            question_text=errmsg,
            answer_text=errmsg,
            question_av_tags=[],
            answer_av_tags=[],
        )

    if not output.question_text.strip():
        msg = _("The front of this card is blank.")
        help = _("More info")
        helplink = CARD_BLANK_HELP
        msg += f"<br><a href='{helplink}'>{help}</a>"
        output.question_text = msg

    hooks.card_did_render(output, ctx)

    return output
Пример #7
0
    def _renderQA(self,
                  data: QAData,
                  qfmt: Optional[str] = None,
                  afmt: Optional[str] = None) -> Dict[str, Union[str, int]]:
        # extract info from data
        split_fields = splitFields(data[6])
        card_ord = data[4]
        model = self.models.get(data[2])
        if model["type"] == MODEL_STD:
            template = model["tmpls"][data[4]]
        else:
            template = model["tmpls"][0]
        flag = data[7]
        deck_id = data[3]
        card_id = data[0]
        tags = data[5]
        qfmt = qfmt or template["qfmt"]
        afmt = afmt or template["afmt"]

        # create map of field names -> field content
        fields: Dict[str, str] = {}
        for (name, (idx, conf)) in list(self.models.fieldMap(model).items()):
            fields[name] = split_fields[idx]

        # add special fields
        fields["Tags"] = tags.strip()
        fields["Type"] = model["name"]
        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"

        # legacy hook
        fields = runFilter("mungeFields", fields, model, data, self)

        ctx = TemplateRenderContext(self, data, fields)

        # render fields. if any custom filters are encountered,
        # the field_filter hook will be called.
        try:
            qtext, atext = render_card(self, qfmt, afmt, ctx)
        except anki.rsbackend.BackendException as e:
            errmsg = _("Card template has a problem:") + f"<br>{e}"
            qtext = errmsg
            atext = errmsg

        # avoid showing the user a confusing blank card if they've
        # forgotten to add a cloze deletion
        if model["type"] == MODEL_CLOZE:
            if not self.models._availClozeOrds(model, data[6], False):
                qtext = (qtext + "<p>" + _(
                    "Please edit this note and add some cloze deletions. (%s)")
                         % ("<a href=%s#cloze>%s</a>" %
                            (HELP_SITE, _("help"))))

        # allow add-ons to modify the generated result
        (qtext, atext) = hooks.card_did_render((qtext, atext), ctx)

        # legacy hook
        qtext = runFilter("mungeQA", qtext, "q", fields, model, data, self)
        atext = runFilter("mungeQA", atext, "a", fields, model, data, self)

        return dict(q=qtext, a=atext, id=card_id)