Process field values in QTextDocuments
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -594,7 +594,7 @@ def testFmtToQTextDocument_Footnotes(mockGUI):
|
||||
)
|
||||
doc.tokenizeText()
|
||||
doc.doConvert()
|
||||
doc.appendFootnotes()
|
||||
doc.closeDocument()
|
||||
assert doc.document.blockCount() == 4
|
||||
|
||||
# 0: Scene
|
||||
|
||||
Reference in New Issue
Block a user