mirror of
https://github.com/ankitects/anki.git
synced 2025-09-22 07:52:24 -04:00
type in answer patch from bernhard
This commit is contained in:
parent
57b816d573
commit
50e547d685
1 changed files with 54 additions and 20 deletions
|
@ -10,6 +10,7 @@ from anki.utils import stripHTML
|
||||||
from anki.hooks import runHook, runFilter
|
from anki.hooks import runHook, runFilter
|
||||||
from anki.media import stripMedia
|
from anki.media import stripMedia
|
||||||
import types, time, re, os, urllib, sys, difflib
|
import types, time, re, os, urllib, sys, difflib
|
||||||
|
import unicodedata as ucd
|
||||||
from ankiqt import ui
|
from ankiqt import ui
|
||||||
from ankiqt.ui.utils import mungeQA, getBase
|
from ankiqt.ui.utils import mungeQA, getBase
|
||||||
from anki.utils import fmtTimeSpan
|
from anki.utils import fmtTimeSpan
|
||||||
|
@ -141,13 +142,8 @@ class View(object):
|
||||||
and self.main.config['autoplaySounds']):
|
and self.main.config['autoplaySounds']):
|
||||||
playFromText(q)
|
playFromText(q)
|
||||||
|
|
||||||
def correct(self, a, b):
|
def calculateOkBadStyle(self):
|
||||||
if b == "":
|
"Precalculates styles for correct and incorrect part of answer"
|
||||||
return "";
|
|
||||||
|
|
||||||
ret = "";
|
|
||||||
s = difflib.SequenceMatcher(None, b, a)
|
|
||||||
|
|
||||||
sz = 20
|
sz = 20
|
||||||
fn = u"Arial"
|
fn = u"Arial"
|
||||||
for fm in self.main.currentCard.fact.model.fieldModels:
|
for fm in self.main.currentCard.fact.model.fieldModels:
|
||||||
|
@ -156,24 +152,61 @@ class View(object):
|
||||||
fn = fm.quizFontFamily or fn
|
fn = fm.quizFontFamily or fn
|
||||||
break
|
break
|
||||||
st = "background: %s; color: #000; font-size: %dpx; font-family: %s;"
|
st = "background: %s; color: #000; font-size: %dpx; font-family: %s;"
|
||||||
ok = st % (passedCharColour, sz, fn)
|
self.styleOk = st % (passedCharColour, sz, fn)
|
||||||
bad = st % (failedCharColour, sz, fn)
|
self.styleBad = st % (failedCharColour, sz, fn)
|
||||||
|
|
||||||
|
def ok(self, a):
|
||||||
|
"returns given sring in style correct (green)"
|
||||||
|
if len(a) == 0:
|
||||||
|
return ""
|
||||||
|
return "<span style='%s'>%s</span>" % (self.styleOk, a)
|
||||||
|
|
||||||
|
def bad(self, a):
|
||||||
|
"returns given sring in style incorrect (red)"
|
||||||
|
if len(a) == 0:
|
||||||
|
return ""
|
||||||
|
return "<span style='%s'>%s</span>" % (self.styleBad, a)
|
||||||
|
|
||||||
|
def head(self, a):
|
||||||
|
return a[:len(a) - 1]
|
||||||
|
|
||||||
|
def tail(self, a):
|
||||||
|
return a[len(a) - 1:]
|
||||||
|
|
||||||
|
def applyStyle(self, testChar, correct, wrong):
|
||||||
|
"Calculates answer fragment depending on testChar's unicode category"
|
||||||
|
ZERO_SIZE = 'Mn'
|
||||||
|
if ucd.category(testChar) == ZERO_SIZE:
|
||||||
|
return self.ok(self.head(correct)) + self.bad(self.tail(correct) + wrong)
|
||||||
|
return self.ok(correct) + self.bad(wrong)
|
||||||
|
|
||||||
|
def correct(self, a, b):
|
||||||
|
"Diff-corrects the typed-in answer."
|
||||||
|
if b == "":
|
||||||
|
return "";
|
||||||
|
|
||||||
|
self.calculateOkBadStyle()
|
||||||
|
|
||||||
|
ret = ""
|
||||||
|
lastEqual = ""
|
||||||
|
s = difflib.SequenceMatcher(None, b, a)
|
||||||
|
|
||||||
for tag, i1, i2, j1, j2 in s.get_opcodes():
|
for tag, i1, i2, j1, j2 in s.get_opcodes():
|
||||||
if tag == "equal":
|
if tag == "equal":
|
||||||
ret += ("<span style='%s'>%s</span>" % (ok, b[i1:i2]))
|
lastEqual = b[i1:i2]
|
||||||
elif tag == "replace":
|
elif tag == "replace":
|
||||||
ret += ("<span style='%s'>%s</span>"
|
ret += self.applyStyle(b[i1], lastEqual,
|
||||||
% (bad, b[i1:i2] + (" " * ((j2 - j1) - (i2 - i1)))))
|
b[i1:i2] + ("-" * ((j2 - j1) - (i2 - i1))))
|
||||||
|
lastEqual = ""
|
||||||
elif tag == "delete":
|
elif tag == "delete":
|
||||||
p = re.compile(r"^\s*$")
|
ret += self.applyStyle(b[i1], lastEqual, b[i1:i2])
|
||||||
if p.match(b[i1:i2]):
|
lastEqual = ""
|
||||||
ret += ("<span style='%s'>%s</span>" % (ok, b[i1:i2]))
|
|
||||||
else:
|
|
||||||
ret += ("<span style='%s'>%s</span>" % (bad, b[i1:i2]))
|
|
||||||
elif tag == "insert":
|
elif tag == "insert":
|
||||||
ret += ("<span style='%s'>%s</span>" % (bad, " " * (j2 - j1)))
|
dashNum = (j2 - j1) if ucd.category(a[i1]) != 'Mn' else ((j2 - j1) - 1)
|
||||||
return ret
|
ret += self.applyStyle(a[i1], lastEqual, "-" * dashNum)
|
||||||
|
lastEqual = ""
|
||||||
|
|
||||||
|
return ret + self.ok(lastEqual)
|
||||||
|
|
||||||
def drawAnswer(self):
|
def drawAnswer(self):
|
||||||
"Show the answer."
|
"Show the answer."
|
||||||
|
@ -188,7 +221,8 @@ class View(object):
|
||||||
cor = ""
|
cor = ""
|
||||||
if cor:
|
if cor:
|
||||||
given = unicode(self.main.typeAnswerField.text())
|
given = unicode(self.main.typeAnswerField.text())
|
||||||
res = self.correct(given, cor)
|
res = self.correct(ucd.normalize('NFC', cor),
|
||||||
|
ucd.normalize('NFC', given))
|
||||||
a = res + "<br>" + a
|
a = res + "<br>" + a
|
||||||
self.write(self.center('<span id=answer />'
|
self.write(self.center('<span id=answer />'
|
||||||
+ self.mungeQA(self.main.deck, a)))
|
+ self.mungeQA(self.main.deck, a)))
|
||||||
|
|
Loading…
Reference in a new issue