Add insert footnote feature in editor

This commit is contained in:
Veronica Berglyd Olsen
2024-04-14 23:33:35 +02:00
parent da102d3d5a
commit 70033cb0f3
6 changed files with 82 additions and 16 deletions
+31 -1
View File
@@ -55,7 +55,7 @@ from novelwriter import CONFIG, SHARED
from novelwriter.common import minmax, transferCase
from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
from novelwriter.core.document import NWDocument
from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary
from novelwriter.enum import nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary
from novelwriter.extensions.eventfilters import WheelEventFilter
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE
@@ -884,6 +884,9 @@ class GuiDocEditor(QPlainTextEdit):
text = GuiLipsum.getLipsum(self)
newBlock = True
goAfter = False
elif insert == nwDocInsert.FOOTNOTE:
text = ""
self._insertCommentStructure(nwComment.FOOTNOTE)
else:
return False
else:
@@ -1850,6 +1853,33 @@ class GuiDocEditor(QPlainTextEdit):
return
def _insertCommentStructure(self, style: nwComment) -> None:
"""Insert a shortcut/comment combo."""
if style == nwComment.FOOTNOTE:
key = SHARED.project.index.newCommentKey(style)
code = nwShortcode.COMMENT_STYLES[nwComment.FOOTNOTE]
cursor = self.textCursor()
block = cursor.block()
text = block.text().rstrip()
if not text or text.startswith(("@", "#", "%")):
SHARED.error(self.tr("Footnotes can only be inserted in text."))
return
cursor.beginEditBlock()
cursor.insertText(code.format(key))
cursor.setPosition(block.position() + block.length())
cursor.insertBlock()
cursor.insertText(f"%Footnote.{key}: ")
cursor.insertBlock()
cursor.endEditBlock()
cursor.setPosition(cursor.position() - 1)
self.setTextCursor(cursor)
return
##
# Internal Functions
##
+24 -5
View File
@@ -44,6 +44,10 @@ logger = logging.getLogger(__name__)
SPELLRX = QRegularExpression(r"\b[^\s\-\+\/–—\[\]:]+\b")
SPELLRX.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
SPELLSC = QRegularExpression(nwRegEx.FMT_SC)
SPELLSC.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
SPELLSV = QRegularExpression(nwRegEx.FMT_SV)
SPELLSV.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
BLOCK_NONE = 0
BLOCK_TEXT = 1
@@ -53,7 +57,10 @@ BLOCK_TITLE = 4
class GuiDocHighlighter(QSyntaxHighlighter):
__slots__ = ("_tItem", "_tHandle", "_spellCheck", "_spellErr", "_hRules", "_hStyles")
__slots__ = (
"_tHandle", "_isInactive", "_spellCheck", "_spellErr", "_hRules",
"_hStyles", "_rxRules"
)
def __init__(self, document: QTextDocument) -> None:
super().__init__(document)
@@ -67,6 +74,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
self._hRules: list[tuple[str, dict]] = []
self._hStyles: dict[str, QTextCharFormat] = {}
self._rxRules: list[tuple[QRegularExpression, dict[int, QTextCharFormat]]] = []
self.initHighlighter()
@@ -217,12 +225,12 @@ class GuiDocHighlighter(QSyntaxHighlighter):
}
))
# Build a QRegExp for each highlight pattern
self.rxRules = []
# Build a QRegularExpression for each highlight pattern
self._rxRules = []
for regEx, regRules in self._hRules:
hReg = QRegularExpression(regEx)
hReg.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
self.rxRules.append((hReg, regRules))
self._rxRules.append((hReg, regRules))
return
@@ -367,7 +375,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
# Regular Text
self.setCurrentBlockState(BLOCK_TEXT)
for rX, xFmt in self.rxRules:
for rX, xFmt in self._rxRules:
rxItt = rX.globalMatch(text, 0)
while rxItt.hasNext():
rxMatch = rxItt.next()
@@ -448,6 +456,17 @@ class TextBlockData(QTextBlockUserData):
"""Run the spell checker and cache the result, and return the
list of spell check errors.
"""
if "[" in text:
# Strip shortcodes
for rX in [SPELLSC, SPELLSV]:
rxItt = rX.globalMatch(text, 0)
while rxItt.hasNext():
rxMatch = rxItt.next()
xPos = rxMatch.capturedStart(0)
xLen = rxMatch.capturedLength(0)
xEnd = rxMatch.capturedEnd(0)
text = text[:xPos] + " "*xLen + text[xEnd:]
self._spellErrors = []
rxSpell = SPELLRX.globalMatch(text[offset:].replace("_", " "), 0)
while rxSpell.hasNext():