def from_card(cls, card: Card) -> "CardInfo":
     return cls(
         card.id,
         question=strip_html(card.question()),
         answer=strip_html(card.answer()),
         due=card.due,
         reviews=get_card_reviews(card.id),
     )
Esempio n. 2
0
    def typeAnsAnswerFilter(self, buf: str) -> str:
        if not self.typeCorrect:
            return re.sub(self.typeAnsPat, "", buf)
        origSize = len(buf)
        buf = buf.replace("<hr id=answer>", "")
        hadHR = len(buf) != origSize
        # munge correct value
        cor = self.mw.col.media.strip(self.typeCorrect)
        cor = re.sub("(\n|<br ?/?>|</?div>)+", " ", cor)
        cor = strip_html(cor)
        # ensure we don't chomp multiple whitespace
        cor = cor.replace(" ", "&nbsp;")
        cor = html.unescape(cor)
        cor = cor.replace("\xa0", " ")
        cor = cor.strip()
        given = self.typedAnswer
        # compare with typed answer
        res = self.correct(given, cor, showBad=False)
        # and update the type answer area
        def repl(match: Match) -> str:
            # can't pass a string in directly, and can't use re.escape as it
            # escapes too much
            s = """
<span style="font-family: '{}'; font-size: {}px">{}</span>""".format(
                self.typeFont,
                self.typeSize,
                res,
            )
            if hadHR:
                # a hack to ensure the q/a separator falls before the answer
                # comparison when user is using {{FrontSide}}
                s = f"<hr id=answer>{s}"
            return s

        return re.sub(self.typeAnsPat, repl, buf)
Esempio n. 3
0
 def stripHTML(self, text: str) -> str:
     # very basic conversion to text
     s = text
     s = re.sub(r"(?i)<(br ?/?|div|p)>", " ", s)
     s = re.sub(r"\[sound:[^]]+\]", "", s)
     s = strip_html(s)
     s = re.sub(r"[ \n\t]+", " ", s)
     s = s.strip()
     return s
Esempio n. 4
0
def get_reschedule_message(reschedule: Reschedule):
    question = strip_html(reschedule.sibling.question())
    today = get_today()
    interval = reschedule.sibling.ivl

    return (
        f"Sibling: {question} (interval: <b>{interval}</b> days)<br>"
        f"Rescheduling: <b>{reschedule.old_absolute_due - today}</b> → "
        f"<span style='color: crimson'><b>{reschedule.new_absolute_due - today}</b></span> "
        f"days after today")
Esempio n. 5
0
def test_templates():
    col = getEmptyCol()
    m = col.models.current()
    mm = col.models
    t = mm.new_template("Reverse")
    t["qfmt"] = "{{Back}}"
    t["afmt"] = "{{Front}}"
    mm.add_template(m, t)
    mm.save(m)
    note = col.newNote()
    note["Front"] = "1"
    note["Back"] = "2"
    col.addNote(note)
    assert col.card_count() == 2
    (c, c2) = note.cards()
    # first card should have first ord
    assert c.ord == 0
    assert c2.ord == 1
    # switch templates
    col.models.reposition_template(m, c.template(), 1)
    col.models.update(m)
    c.load()
    c2.load()
    assert c.ord == 1
    assert c2.ord == 0
    # removing a template should delete its cards
    col.models.remove_template(m, m["tmpls"][0])
    col.models.update(m)
    assert col.card_count() == 1
    # and should have updated the other cards' ordinals
    c = note.cards()[0]
    assert c.ord == 0
    assert strip_html(c.question()) == "1"
    # it shouldn't be possible to orphan notes by removing templates
    t = mm.new_template("template name")
    t["qfmt"] = "{{Front}}2"
    mm.add_template(m, t)
    col.models.remove_template(m, m["tmpls"][0])
    col.models.update(m)
    assert (
        col.db.scalar(
            "select count() from cards where nid not in (select id from notes)"
        )
        == 0
    )