diff --git a/anki/deck.py b/anki/deck.py
index 9211922ec..e1b57cf12 100644
--- a/anki/deck.py
+++ b/anki/deck.py
@@ -482,7 +482,11 @@ select id from cards where fid in (select id from facts where mid = ?)""",
if type == "q":
format = format.replace("cloze:", "cq:")
else:
- format = format.replace("cloze:", "ca:")
+ if model.conf['clozectx']:
+ name = "cactx:"
+ else:
+ name = "ca:"
+ format = format.replace("cloze:", name)
fields = runFilter("mungeFields", fields, model, gname, data, self)
html = anki.template.render(format, fields)
d[type] = runFilter(
diff --git a/anki/models.py b/anki/models.py
index bb0b99a1a..a3360cc19 100644
--- a/anki/models.py
+++ b/anki/models.py
@@ -13,6 +13,7 @@ from anki.lang import _
defaultConf = {
'sortf': 0,
'gid': 1,
+ 'clozectx': False,
}
defaultField = {
@@ -40,7 +41,7 @@ defaultTemplate = {
'bg': "#fff",
'emptyAns': True,
'typeAns': None,
- 'gid': None
+ 'gid': None,
}
class Model(object):
diff --git a/anki/template/template.py b/anki/template/template.py
index 34bc98378..6cc596820 100644
--- a/anki/template/template.py
+++ b/anki/template/template.py
@@ -130,7 +130,7 @@ class Template(object):
func = modifiers[tag_type]
replacement = func(self, tag_name, context)
template = template.replace(tag, replacement)
- except:
+ except SyntaxError:
return u"{{invalid template}}"
return template
@@ -157,8 +157,10 @@ class Template(object):
if txt:
return stripHTML(txt)
return ""
- elif tag_name.startswith("cq:") or tag_name.startswith("ca:"):
- m = re.match("c(.):(\d+):(.+)", tag_name)
+ elif (tag_name.startswith("cq:") or
+ tag_name.startswith("ca:") or
+ tag_name.startswith("cactx:")):
+ 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:
@@ -166,8 +168,6 @@ class Template(object):
return ""
return get_or_attr(context, tag_name, '{unknown field %s}' % tag_name)
- # fixme: need a way to conditionally add these, so that including extra
- # fields in the question fmt doesn't make empty clozes
def clozeText(self, txt, ord, type):
reg = clozeReg
m = re.search(reg%ord, txt)
@@ -180,8 +180,13 @@ class Template(object):
txt = re.sub(reg%ord, "...(\\3)", txt)
else:
txt = re.sub(reg%ord, "...", txt)
- else:
+ elif type == "actx":
txt = re.sub(reg%ord, "\\1", txt)
+ else:
+ # just the answers
+ ans = re.findall(reg%ord, txt)
+ ans = [""+a[0]+"" for a in ans]
+ return ", ".join(ans)
# and display other clozes normally
return re.sub(reg%".*?", "\\1", txt)
diff --git a/tests/test_models.py b/tests/test_models.py
index 8c8483677..7b9969058 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -120,6 +120,11 @@ def test_cloze():
f['Text'] = "hello {{c1::world}}"
assert d.addFact(f) == 1
assert "hello ..." in f.cards()[0].q()
+ # the default is no context
+ assert "world" in f.cards()[0].a()
+ assert "hello world" not in f.cards()[0].a()
+ # check context works too
+ f.model().conf['clozectx'] = True
assert "hello world" in f.cards()[0].a()
# and with a comment
f = d.newFact()
@@ -136,6 +141,13 @@ def test_cloze():
assert "world bar" in c1.a()
assert "world ..." in c2.q()
assert "world bar" in c2.a()
+ # if there are multiple answers for a single cloze, they are given in a
+ # list
+ f.model().conf['clozectx'] = False
+ f = d.newFact()
+ f['Text'] = "a {{c1::b}} {{c1::c}}"
+ assert d.addFact(f) == 1
+ assert "b, c" in f.cards()[0].a()
# clozes should be supported in sections too
m = d.currentModel()
m.templates[0]['qfmt'] = "{{#cloze:1:Text}}{{Notes}}{{/cloze:1:Text}}"