diff --git a/anki/cards.py b/anki/cards.py index fe58309f4..90f80fa59 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -135,6 +135,10 @@ lapses=?, left=?, odue=?, odid=?, did=? where id = ?""", else: args = tuple() self._qa = self.col._renderQA(data, *args) + if m.get("prewrap", False): + wsdiv = "
{}
" + self._qa['q'] = wsdiv.format(self._qa['q']) + self._qa['a'] = wsdiv.format(self._qa['a']) return self._qa def note(self, reload=False): diff --git a/aqt/editor.py b/aqt/editor.py index 3a9d0325e..2a66db388 100644 --- a/aqt/editor.py +++ b/aqt/editor.py @@ -61,6 +61,8 @@ background-image: -webkit-gradient(linear, left top, left bottom, border-bottom: 3px solid #000; } +.prewrap { white-space: pre-wrap; } + #fields { margin-top: 35px; } @@ -69,6 +71,7 @@ background-image: -webkit-gradient(linear, left top, left bottom, var currentField = null; var changeTimer = null; var dropTarget = null; +var prewrapMode = false; String.prototype.format = function() { var args = arguments; @@ -93,6 +96,12 @@ function onKey() { currentField.blur(); return; } + // catch enter key in prewrap mode + if (window.event.which == 13 && prewrapMode) { + window.event.preventDefault(); + insertNewline(); + return; + } clearChangeTimer(); changeTimer = setTimeout(function () { updateButtonState(); @@ -100,6 +109,40 @@ function onKey() { }, 600); }; +function insertNewline() { + if (!inPreEnvironment()) { + setFormat("insertText", "\\n"); + return; + } + + // in some cases inserting a newline will not show any changes, + // as a trailing newline at the end of a block does not render + // differently. so in such cases we note the height has not + // changed and insert an extra newline. + + var r = window.getSelection().getRangeAt(0); + if (!r.collapsed) { + // delete any currently selected text first, making + // sure the delete is undoable + setFormat("delete"); + } + + var oldHeight = currentField.clientHeight; + setFormat("inserthtml", "\\n"); + if (currentField.clientHeight == oldHeight) { + setFormat("inserthtml", "\\n"); + } +} + +// is the cursor in an environment that respects whitespace? +function inPreEnvironment() { + var n = window.getSelection().anchorNode; + if (n.nodeType == 3) { + n = n.parentNode; + } + return window.getComputedStyle(n).whiteSpace.startsWith("pre"); +} + function checkForEmptyField() { if (currentField.innerHTML == "") { currentField.innerHTML = "
"; @@ -152,8 +195,6 @@ function onFocus(elem) { if (mouseDown) { return; } // do this twice so that there's no flicker on newer versions caretToEnd(); - // need to do this in a timeout for older qt versions - setTimeout(function () { caretToEnd() }, 1); // scroll if bottom of element off the screen function pos(obj) { var cur = 0; @@ -251,7 +292,7 @@ function wrap(front, back) { } }; -function setFields(fields, focusTo) { +function setFields(fields, focusTo, prewrap) { var txt = ""; for (var i=0; iChange Note Type.""")) for node in doc(tag): node.decompose() - # convert p tags to divs - for node in doc("p"): - node.name = "div" + if not self.prewrapMode(): + # convert p tags to divs + for node in doc("p"): + node.name = "div" for tag in doc("img"): try: @@ -1123,8 +1213,6 @@ class EditorWebView(AnkiWebView): # normal text; convert it to HTML txt = html.escape(txt) - txt = txt.replace("\n", "
") - txt = txt.replace(" ", " ") return txt def _processHtml(self, mime): diff --git a/aqt/models.py b/aqt/models.py index c93f1777e..4a7a498cb 100644 --- a/aqt/models.py +++ b/aqt/models.py @@ -109,6 +109,7 @@ class Models(QDialog): frm.setupUi(d) frm.latexHeader.setText(self.model['latexPre']) frm.latexFooter.setText(self.model['latexPost']) + frm.newStyleWhitespace.setChecked(self.model.get("prewrap", False)) d.setWindowTitle(_("Options for %s") % self.model['name']) frm.buttonBox.helpRequested.connect(lambda: openHelp("latex")) restoreGeom(d, "modelopts") @@ -116,6 +117,7 @@ class Models(QDialog): saveGeom(d, "modelopts") self.model['latexPre'] = str(frm.latexHeader.toPlainText()) self.model['latexPost'] = str(frm.latexFooter.toPlainText()) + self.model['prewrap'] = frm.newStyleWhitespace.isChecked() def saveModel(self): self.mm.save(self.model) diff --git a/designer/modelopts.ui b/designer/modelopts.ui index f1d3ede49..c82a0414a 100644 --- a/designer/modelopts.ui +++ b/designer/modelopts.ui @@ -57,6 +57,33 @@ + + + General + + + + + + New style whitespace handling (EXPERIMENTAL) + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + +