mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
cloze basics
This commit is contained in:
parent
e0c4c9e896
commit
ea515a5141
2 changed files with 41 additions and 78 deletions
117
aqt/editor.py
117
aqt/editor.py
|
@ -11,7 +11,7 @@ from anki.sound import play
|
||||||
from anki.hooks import addHook, removeHook, runHook, runFilter
|
from anki.hooks import addHook, removeHook, runHook, runFilter
|
||||||
from aqt.sound import getAudio
|
from aqt.sound import getAudio
|
||||||
from aqt.webview import AnkiWebView
|
from aqt.webview import AnkiWebView
|
||||||
from aqt.utils import shortcut
|
from aqt.utils import shortcut, showInfo
|
||||||
import anki.js
|
import anki.js
|
||||||
|
|
||||||
# fixme: add code to escape from text field
|
# fixme: add code to escape from text field
|
||||||
|
@ -95,7 +95,16 @@ function onBlur() {
|
||||||
function saveField(type) {
|
function saveField(type) {
|
||||||
// type is either 'focus' or 'key'
|
// type is either 'focus' or 'key'
|
||||||
py.run(type + ":" + currentField.id.substring(1) + ":" + currentField.innerHTML);
|
py.run(type + ":" + currentField.id.substring(1) + ":" + currentField.innerHTML);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
function cloze() {
|
||||||
|
var s = window.getSelection()
|
||||||
|
var r = s.getRangeAt(0).cloneContents();
|
||||||
|
var c = document.createElement('div');
|
||||||
|
c.appendChild(r);
|
||||||
|
var txt = c.innerHTML;
|
||||||
|
py.run("cloze:" + currentField.id.substring(1) + ":" + txt);
|
||||||
|
};
|
||||||
|
|
||||||
function setFields(fields) {
|
function setFields(fields) {
|
||||||
var txt = "";
|
var txt = "";
|
||||||
|
@ -264,6 +273,33 @@ class Editor(object):
|
||||||
self._buttons['text_under'].setChecked(r['under'])
|
self._buttons['text_under'].setChecked(r['under'])
|
||||||
self._buttons['text_super'].setChecked(r['super'])
|
self._buttons['text_super'].setChecked(r['super'])
|
||||||
self._buttons['text_sub'].setChecked(r['sub'])
|
self._buttons['text_sub'].setChecked(r['sub'])
|
||||||
|
elif str.startswith("cloze"):
|
||||||
|
(cmd, num, txt) = str.split(":", 2)
|
||||||
|
if not txt:
|
||||||
|
showInfo(_("Please select some text first."),
|
||||||
|
help="ClozeDeletion")
|
||||||
|
return
|
||||||
|
# check that the model is set up for cloze deletion
|
||||||
|
ok = False
|
||||||
|
for t in self.fact.model().templates:
|
||||||
|
if "cloze" in t['qfmt'] or "cloze" in t['afmt']:
|
||||||
|
ok = True
|
||||||
|
break
|
||||||
|
if not ok:
|
||||||
|
showInfo(_("Please add a cloze deletion model."),
|
||||||
|
help="ClozeDeletion")
|
||||||
|
return
|
||||||
|
num = int(num)
|
||||||
|
f = self.fact._fields[num]
|
||||||
|
# find the highest existing cloze
|
||||||
|
m = re.findall("\{\{c(\d+)::", f)
|
||||||
|
if m:
|
||||||
|
next = sorted([int(x) for x in m])[-1] + 1
|
||||||
|
else:
|
||||||
|
next = 1
|
||||||
|
self.fact._fields[num] = f.replace(
|
||||||
|
txt, "{{c%d::%s}}" % (next, txt))
|
||||||
|
self.loadFact()
|
||||||
|
|
||||||
def _loadFinished(self, w):
|
def _loadFinished(self, w):
|
||||||
self._loaded = True
|
self._loaded = True
|
||||||
|
@ -717,82 +753,9 @@ class Editor(object):
|
||||||
type = 0; ord = 0
|
type = 0; ord = 0
|
||||||
CardLayout(self.mw, self.fact, type=type, ord=ord, parent=self.widget)
|
CardLayout(self.mw, self.fact, type=type, ord=ord, parent=self.widget)
|
||||||
|
|
||||||
# FIXME: in some future version, we should use a different delimiter, as
|
|
||||||
# [sound] et al conflicts
|
|
||||||
def onCloze(self):
|
def onCloze(self):
|
||||||
src = self.focusedEdit()
|
self.removeFormat()
|
||||||
if not src:
|
self.web.eval("cloze();")
|
||||||
return
|
|
||||||
re1 = "\[(?:<.+?>)?.+?(:(.+?))?\](?:</.+?>)?"
|
|
||||||
re2 = "\[(?:<.+?>)?(.+?)(:.+?)?\](?:</.+?>)?"
|
|
||||||
# add brackets because selected?
|
|
||||||
cursor = src.textCursor()
|
|
||||||
oldSrc = None
|
|
||||||
if cursor.hasSelection():
|
|
||||||
oldSrc = src.toHtml()
|
|
||||||
s = cursor.selectionStart()
|
|
||||||
e = cursor.selectionEnd()
|
|
||||||
cursor.setPosition(e)
|
|
||||||
cursor.insertText("]]")
|
|
||||||
cursor.setPosition(s)
|
|
||||||
cursor.insertText("[[")
|
|
||||||
re1 = "\[" + re1 + "\]"
|
|
||||||
re2 = "\[" + re2 + "\]"
|
|
||||||
dst = None
|
|
||||||
for field in self.fact.fields:
|
|
||||||
w = self.fields[field.name][1]
|
|
||||||
if w.hasFocus():
|
|
||||||
dst = False
|
|
||||||
continue
|
|
||||||
if dst is False:
|
|
||||||
dst = w
|
|
||||||
break
|
|
||||||
if not dst:
|
|
||||||
dst = self.fields[self.fact.fields[0].name][1]
|
|
||||||
if dst == w:
|
|
||||||
return
|
|
||||||
# check if there's alredy something there
|
|
||||||
if not oldSrc:
|
|
||||||
oldSrc = src.toHtml()
|
|
||||||
oldDst = dst.toHtml()
|
|
||||||
if unicode(dst.toPlainText()):
|
|
||||||
if (self.lastCloze and
|
|
||||||
self.lastCloze[1] == oldSrc and
|
|
||||||
self.lastCloze[2] == oldDst):
|
|
||||||
src.setHtml(self.lastCloze[0])
|
|
||||||
dst.setHtml("")
|
|
||||||
self.lastCloze = None
|
|
||||||
self.saveFields()
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
ui.utils.showInfo(
|
|
||||||
_("Next field must be blank."),
|
|
||||||
help="ClozeDeletion",
|
|
||||||
parent=self.widget)
|
|
||||||
return
|
|
||||||
# check if there's anything to change
|
|
||||||
if not re.search("\[.+?\]", unicode(src.toPlainText())):
|
|
||||||
ui.utils.showInfo(
|
|
||||||
_("You didn't specify anything to occlude."),
|
|
||||||
help="ClozeDeletion",
|
|
||||||
parent=self.widget)
|
|
||||||
return
|
|
||||||
# create
|
|
||||||
s = unicode(src.toHtml())
|
|
||||||
def repl(match):
|
|
||||||
exp = ""
|
|
||||||
if match.group(2):
|
|
||||||
exp = match.group(2)
|
|
||||||
return '<font color="%s"><b>[...%s]</b></font>' % (
|
|
||||||
clozeColour, exp)
|
|
||||||
new = re.sub(re1, repl, s)
|
|
||||||
old = re.sub(re2, '<font color="%s"><b>\\1</b></font>'
|
|
||||||
% clozeColour, s)
|
|
||||||
src.setHtml(new)
|
|
||||||
dst.setHtml(old)
|
|
||||||
self.lastCloze = (oldSrc, unicode(src.toHtml()),
|
|
||||||
unicode(dst.toHtml()))
|
|
||||||
self.saveFields()
|
|
||||||
|
|
||||||
def onHtmlEdit(self):
|
def onHtmlEdit(self):
|
||||||
def helpRequested():
|
def helpRequested():
|
||||||
|
|
|
@ -22,7 +22,7 @@ def showCritical(text, parent=None, help=""):
|
||||||
def showInfo(text, parent=None, help="", func=None):
|
def showInfo(text, parent=None, help="", func=None):
|
||||||
"Show a small info window with an OK button."
|
"Show a small info window with an OK button."
|
||||||
if not parent:
|
if not parent:
|
||||||
parent = aqt.mw
|
parent = aqt.mw.app.activeWindow() or aqt.mw
|
||||||
if not func:
|
if not func:
|
||||||
func = QMessageBox.information
|
func = QMessageBox.information
|
||||||
sb = QMessageBox.Ok
|
sb = QMessageBox.Ok
|
||||||
|
|
Loading…
Reference in a new issue