Process field values in QTextDocuments

This commit is contained in:
Veronica Berglyd Olsen
2024-10-28 17:30:34 +01:00
parent 041183f914
commit f92521c93a
13 changed files with 50 additions and 22 deletions
+5 -4
View File
@@ -132,7 +132,7 @@ class NWBuildDocument:
yield from self._iterBuild(makeObj, filtered)
makeObj.appendFootnotes()
makeObj.closeDocument()
self._error = None
self._cache = makeObj
@@ -164,7 +164,7 @@ class NWBuildDocument:
yield from self._iterBuild(makeObj, filtered)
makeObj.appendFootnotes()
makeObj.closeDocument()
if not self._build.getBool("html.preserveTabs"):
makeObj.replaceTabs()
@@ -174,7 +174,7 @@ class NWBuildDocument:
yield from self._iterBuild(makeObj, filtered)
makeObj.appendFootnotes()
makeObj.closeDocument()
if self._build.getBool("format.replaceTabs"):
makeObj.replaceTabs(nSpaces=4, spaceChar=" ")
@@ -184,6 +184,7 @@ class NWBuildDocument:
yield from self._iterBuild(makeObj, filtered)
makeObj.closeDocument()
if self._build.getBool("format.replaceTabs"):
makeObj.replaceTabs(nSpaces=4, spaceChar=" ")
@@ -203,7 +204,7 @@ class NWBuildDocument:
yield from self._iterBuild(makeObj, filtered)
makeObj.appendFootnotes()
makeObj.closeDocument()
else:
logger.error("Unsupported document format")
+1 -1
View File
@@ -249,7 +249,7 @@ class ToHtml(Tokenizer):
return
def appendFootnotes(self) -> None:
def closeDocument(self) -> None:
"""Append the footnotes in the buffer."""
if self._usedNotes:
footnotes = self._localLookup("Footnotes")
+4
View File
@@ -428,6 +428,10 @@ class Tokenizer(ABC):
def doConvert(self) -> None:
raise NotImplementedError
@abstractmethod
def closeDocument(self) -> None:
raise NotImplementedError
@abstractmethod
def saveDocument(self, path: Path) -> None:
raise NotImplementedError
+1 -1
View File
@@ -149,7 +149,7 @@ class ToMarkdown(Tokenizer):
return
def appendFootnotes(self) -> None:
def closeDocument(self) -> None:
"""Append the footnotes in the buffer."""
if self._usedNotes:
tags = EXT_MD if self._extended else STD_MD
+23 -7
View File
@@ -40,8 +40,8 @@ from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt
from novelwriter.formats.tokenizer import HEADINGS, Tokenizer
from novelwriter.types import (
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
QtPageBreakAfter, QtPageBreakBefore, QtTransparent, QtVAlignNormal,
QtVAlignSub, QtVAlignSuper
QtKeepAnchor, QtMoveAnchor, QtPageBreakAfter, QtPageBreakBefore,
QtTransparent, QtVAlignNormal, QtVAlignSub, QtVAlignSuper
)
logger = logging.getLogger(__name__)
@@ -70,6 +70,7 @@ class ToQTextDocument(Tokenizer):
self._document.setDocumentMargin(0)
self._usedNotes: dict[str, int] = {}
self._usedFields: list[tuple[int, str]] = []
self._init = False
self._bold = QFont.Weight.Bold
@@ -246,11 +247,21 @@ class ToQTextDocument(Tokenizer):
return
def appendFootnotes(self) -> None:
"""Append the footnotes in the buffer."""
if self._usedNotes:
self._document.blockSignals(True)
def closeDocument(self) -> None:
"""Run close document tasks."""
self._document.blockSignals(True)
# Replace fields if there are stats available
if self._usedFields and self._counts:
cursor = QTextCursor(self._document)
for pos, field in reversed(self._usedFields):
if (value := self._counts.get(field)) is not None:
cursor.setPosition(pos, QtMoveAnchor)
cursor.setPosition(pos + 1, QtKeepAnchor)
cursor.insertText(f"{value:n}")
# Add footnotes
if self._usedNotes:
cursor = QTextCursor(self._document)
cursor.movePosition(QTextCursor.MoveOperation.End)
@@ -268,7 +279,7 @@ class ToQTextDocument(Tokenizer):
cursor.insertText(f"{index}. ", cFmt)
self._insertFragments(*content, cursor, self._charFmt)
self._document.blockSignals(False)
self._document.blockSignals(False)
return
@@ -361,6 +372,11 @@ class ToQTextDocument(Tokenizer):
cursor.insertText(f"[{index}]", xFmt)
else:
cursor.insertText("[ERR]", cFmt)
elif fmt == TextFmt.FIELD:
if field := data.partition(":")[2]:
self._usedFields.append((cursor.position(), field))
cursor.insertText("0", cFmt)
pass
# Move pos for next pass
start = pos
+4
View File
@@ -52,6 +52,10 @@ class ToRaw(Tokenizer):
"""No conversion to perform."""
return
def closeDocument(self) -> None:
"""Nothing to close."""
return
def saveDocument(self, path: Path) -> None:
"""Save the raw text to a plain text file."""
if path.suffix.lower() == ".json":
+1 -1
View File
@@ -229,7 +229,7 @@ class GuiDocViewer(QTextBrowser):
qDoc.doPreProcessing()
qDoc.tokenizeText()
qDoc.doConvert()
qDoc.appendFootnotes()
qDoc.closeDocument()
except Exception:
logger.error("Failed to generate preview for document with handle '%s'", tHandle)
logException()
+1 -1
View File
@@ -955,7 +955,7 @@ class _StatsWidget(QWidget):
# Maximal
self.maxTotalWords.setText("{0:n}".format(data.get(nwStats.WORDS_ALL, 0)))
self.maxHeadWords.setText("{0:n}".format(data.get(nwStats.WORDS_TITLE, 0)))
self.maxTextWords.setText("{0:n}".format(data.get(nwStats.WORDS_TITLE, 0)))
self.maxTextWords.setText("{0:n}".format(data.get(nwStats.WORDS_TEXT, 0)))
self.maxTitleCount.setText("{0:n}".format(data.get(nwStats.TITLES, 0)))
self.maxParCount.setText("{0:n}".format(data.get(nwStats.PARAGRAPHS, 0)))
+4 -4
View File
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="2.6a3" hexVersion="0x020600a3" fileVersion="1.5" fileRevision="4" timeStamp="2024-10-28 16:42:35">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="2134" autoCount="279" editTime="95103">
<novelWriterXML appVersion="2.6a3" hexVersion="0x020600a3" fileVersion="1.5" fileRevision="4" timeStamp="2024-10-28 17:26:03">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="2135" autoCount="279" editTime="95108">
<name>Sample Project</name>
<author>Jane Smith</author>
</project>
@@ -9,8 +9,8 @@
<language>en_GB</language>
<spellChecking auto="yes">None</spellChecking>
<lastHandle>
<entry key="editor">53b69b83cdafc</entry>
<entry key="viewer">53b69b83cdafc</entry>
<entry key="editor">636b6aa9b697b</entry>
<entry key="viewer">636b6aa9b697b</entry>
<entry key="novelTree">7031beac91f75</entry>
<entry key="outline">7031beac91f75</entry>
</lastHandle>
+1 -1
View File
@@ -315,7 +315,7 @@ def testFmtToHtml_ConvertParagraphs(mockGUI):
"or two<sup>ERR</sup> footnotes.</p>\n"
)
html.appendFootnotes()
html.closeDocument()
assert html._pages[-2] == (
"<p>Text with one<sup><a href='#footnote_1'>1</a></sup> "
"or two<sup>ERR</sup> footnotes.</p>\n"
+3
View File
@@ -44,6 +44,9 @@ class BareTokenizer(Tokenizer):
def doConvert(self):
super().doConvert() # type: ignore (deliberate check)
def closeDocument(self):
super().doConvert() # type: ignore (deliberate check)
def saveDocument(self, path) -> None:
super().saveDocument(path) # type: ignore (deliberate check)
+1 -1
View File
@@ -205,7 +205,7 @@ def testFmtToMarkdown_ConvertParagraphs(mockGUI):
md.doConvert()
assert md._pages[-1] == "Text with one[1] or two[ERR] footnotes.\n\n"
md.appendFootnotes()
md.closeDocument()
assert md._pages[-2] == (
"Text with one[1] or two[ERR] footnotes.\n\n"
)
+1 -1
View File
@@ -594,7 +594,7 @@ def testFmtToQTextDocument_Footnotes(mockGUI):
)
doc.tokenizeText()
doc.doConvert()
doc.appendFootnotes()
doc.closeDocument()
assert doc.document.blockCount() == 4
# 0: Scene