diff --git a/anki/cards.py b/anki/cards.py
index d796a9eae..6b4b5eb85 100644
--- a/anki/cards.py
+++ b/anki/cards.py
@@ -101,10 +101,13 @@ lapses=?, left=?, edue=? where id = ?""",
self.left, self.edue, self.id)
def q(self, reload=False):
- return self._getQA(reload)['q']
+ return self.css() + self._getQA(reload)['q']
def a(self):
- return self._getQA()['a']
+ return self.css() + self._getQA()['a']
+
+ def css(self):
+ return "" % self.template()['css']
def _getQA(self, reload=False):
if not self._qa or reload:
diff --git a/anki/models.py b/anki/models.py
index 07ffe571f..4e4031f39 100644
--- a/anki/models.py
+++ b/anki/models.py
@@ -49,6 +49,15 @@ defaultTemplate = {
'qfmt': "",
'afmt': "",
'did': None,
+ 'css': """\
+.card {
+ font-family: arial;
+ font-size: 20px;
+ text-align: center;
+ color: black;
+ background-color: white;
+}
+"""
}
class ModelManager(object):
@@ -432,7 +441,7 @@ select id from notes where mid = ?)""" % " ".join(map),
if cloze:
# need a cloze-specific filler
cloze = ""
- nums = re.findall("\{\{#cloze:(\d+):", t['qfmt'])
+ nums = re.findall("\{\{cloze:(\d+):", t['qfmt'])
for n in nums:
n = int(n)
cloze += "{{c%d::foo}}" % n
diff --git a/anki/stdmodels.py b/anki/stdmodels.py
index 32954865f..f0ad3578b 100644
--- a/anki/stdmodels.py
+++ b/anki/stdmodels.py
@@ -6,32 +6,19 @@ from anki.lang import _
models = []
-header = """\
-\n\n"""
-
-def field(name, family="arial", size=20):
- return """\
-{{%s}}\n""" % (family, size, name)
-
# Basic
##########################################################################
def addBasicModel(col):
mm = col.models
- m = mm.new(_("Basic")) #2 field note"))
+ m = mm.new(_("Basic"))
fm = mm.newField(_("Front"))
mm.addField(m, fm)
fm = mm.newField(_("Back"))
mm.addField(m, fm)
t = mm.newTemplate(_("Forward"))
- t['qfmt'] = header + field(_("Front"))
- t['afmt'] = t['qfmt'] + "\n\n
\n\n" + field(_("Back"))
+ t['qfmt'] = "{{Front}}"
+ t['afmt'] = t['qfmt'] + "\n\n
\n\n{{Back}}"
mm.addTemplate(m, t)
mm.add(m)
return m
@@ -51,10 +38,14 @@ def addClozeModel(col):
for i in range(8):
n = i+1
t = mm.newTemplate(_("Cloze") + " %d" % n)
- t['qfmt'] = header + ("{{#cloze:%d:Text}}\n"+
- field("cloze:%d:Text" % n)+
- "{{/cloze:%d:Text}}") % (n, n)
- t['afmt'] = t['qfmt'] + "
\n"+field("Notes")
+ fmt = "{{cloze:%d:Text}}%%s" % n
+ t['css'] += """
+.cloze {
+ font-weight: bold;
+ color: blue;
+}"""
+ t['qfmt'] = fmt % ""
+ t['afmt'] = fmt % "\n{{Notes}}"
mm.addTemplate(m, t)
mm.add(m)
return m
diff --git a/anki/template/template.py b/anki/template/template.py
index c4640f4a7..7135d99a6 100644
--- a/anki/template/template.py
+++ b/anki/template/template.py
@@ -138,10 +138,7 @@ class Template(object):
# {{{ functions just like {{ in anki
@modifier('{')
def render_tag(self, tag_name, context):
- raw = get_or_attr(context, tag_name, '')
- if not raw and raw is not 0:
- return ''
- return raw
+ return render_unescaped(tag_name, context)
@modifier('!')
def render_comment(self, tag_name=None, context=None):
@@ -152,6 +149,7 @@ class Template(object):
def render_unescaped(self, tag_name=None, context=None):
"""Render a tag without escaping it."""
if tag_name.startswith("text:"):
+ # strip html
tag = tag_name[5:]
txt = get_or_attr(context, tag)
if txt:
@@ -163,12 +161,14 @@ class Template(object):
return "[[%s]]" % tag_name
elif (tag_name.startswith("cq:") or
tag_name.startswith("ca:")):
+ # cloze deletion
m = re.match("c(.+):(\d+):(.+)", tag_name)
(type, ord, tag) = (m.group(1), m.group(2), m.group(3))
txt = get_or_attr(context, tag)
if txt:
return self.clozeText(txt, ord, type)
return ""
+ # regular field
return get_or_attr(context, tag_name, '{unknown field %s}' % tag_name)
def clozeText(self, txt, ord, type):
diff --git a/anki/upgrade.py b/anki/upgrade.py
index e3475edc2..64fe4c98a 100644
--- a/anki/upgrade.py
+++ b/anki/upgrade.py
@@ -411,7 +411,7 @@ order by ordinal""", mid)):
# q fields now in a
if not hideq:
conf['afmt'] = (
- conf['qfmt'] + "\n\n
\n\n" + conf['afmt'])
+ conf['qfmt'] + "\n\n
\n\n" + conf['afmt'])
tmpls.append(conf)
return tmpls
diff --git a/tests/test_models.py b/tests/test_models.py
index 56fe7ccc7..8e743e8f1 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -132,7 +132,7 @@ def test_cloze():
f = d.newNote()
f['Text'] = "hello {{c1::world::typical}}"
assert d.addNote(f) == 1
- assert "[...(typical)]" in f.cards()[0].q()
+ assert "[...typical]" in f.cards()[0].q()
assert "world" in f.cards()[0].a()
# and with 2 clozes
f = d.newNote()
@@ -150,16 +150,6 @@ def test_cloze():
assert d.addNote(f) == 1
assert "b c" in (
f.cards()[0].a())
- # clozes should be supported in sections too
- m = d.models.current()
- m['tmpls'][0]['qfmt'] = "{{#cloze:1:Text}}{{Notes}}{{/cloze:1:Text}}"
- d.models.save(m)
- f = d.newNote()
- f['Text'] = "hello"
- f['Notes'] = "world"
- assert d.addNote(f) == 0
- f['Text'] = "hello {{c1::foo}}"
- assert d.addNote(f) == 1
# if we add another cloze, a card should be generated
cnt = d.cardCount()
f['Text'] = "{{c2::hello}} {{c1::foo}}"
@@ -179,25 +169,25 @@ def test_modelChange():
mm.save(m)
f = deck.newNote()
f['Front'] = u'f'
- f['Back'] = u'b'
+ f['Back'] = u'b123'
deck.addNote(f)
# switch fields
map = {0: 1, 1: 0}
deck.models.change(basic, [f.id], basic, map, None)
f.load()
- assert f['Front'] == 'b'
+ assert f['Front'] == 'b123'
assert f['Back'] == 'f'
# switch cards
c0 = f.cards()[0]
c1 = f.cards()[1]
- assert ">b<" in c0.q()
+ assert "b123" in c0.q()
assert "f" in c1.q()
assert c0.ord == 0
assert c1.ord == 1
deck.models.change(basic, [f.id], basic, None, map)
f.load(); c0.load(); c1.load()
assert "f" in c0.q()
- assert ">b<" in c1.q()
+ assert "b123" in c1.q()
assert c0.ord == 1
assert c1.ord == 0
# .cards() returns cards in order
@@ -214,7 +204,7 @@ def test_modelChange():
pass
assert len(f.cards()) == 1
# an unmapped field becomes blank
- assert f['Front'] == 'b'
+ assert f['Front'] == 'b123'
assert f['Back'] == 'f'
deck.models.change(basic, [f.id], basic, map, None)
f.load()