Add story structure to build settings (#2298)

This commit is contained in:
Veronica Berglyd Olsen
2025-04-17 16:39:45 +02:00
committed by GitHub
12 changed files with 74 additions and 59 deletions
+2
View File
@@ -78,6 +78,7 @@ SETTINGS_TEMPLATE: dict[str, tuple[type, T_BuildValue]] = {
"headings.breakScene": (bool, False), "headings.breakScene": (bool, False),
"text.includeSynopsis": (bool, False), "text.includeSynopsis": (bool, False),
"text.includeComments": (bool, False), "text.includeComments": (bool, False),
"text.includeStory": (bool, False),
"text.includeKeywords": (bool, False), "text.includeKeywords": (bool, False),
"text.includeBodyText": (bool, True), "text.includeBodyText": (bool, True),
"text.ignoredKeywords": (str, ""), "text.ignoredKeywords": (str, ""),
@@ -144,6 +145,7 @@ SETTINGS_LABELS = {
"text.grpContent": QT_TRANSLATE_NOOP("Builds", "Text Content"), "text.grpContent": QT_TRANSLATE_NOOP("Builds", "Text Content"),
"text.includeSynopsis": QT_TRANSLATE_NOOP("Builds", "Include Synopsis"), "text.includeSynopsis": QT_TRANSLATE_NOOP("Builds", "Include Synopsis"),
"text.includeComments": QT_TRANSLATE_NOOP("Builds", "Include Comments"), "text.includeComments": QT_TRANSLATE_NOOP("Builds", "Include Comments"),
"text.includeStory": QT_TRANSLATE_NOOP("Builds", "Include Story Structure"),
"text.includeKeywords": QT_TRANSLATE_NOOP("Builds", "Include Keywords"), "text.includeKeywords": QT_TRANSLATE_NOOP("Builds", "Include Keywords"),
"text.includeBodyText": QT_TRANSLATE_NOOP("Builds", "Include Body Text"), "text.includeBodyText": QT_TRANSLATE_NOOP("Builds", "Include Body Text"),
"text.ignoredKeywords": QT_TRANSLATE_NOOP("Builds", "Ignore These Keywords"), "text.ignoredKeywords": QT_TRANSLATE_NOOP("Builds", "Ignore These Keywords"),
+5 -3
View File
@@ -32,7 +32,7 @@ from PyQt6.QtGui import QFont
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.constants import nwLabels from novelwriter.constants import nwLabels
from novelwriter.core.item import NWItem from novelwriter.core.item import NWItem
from novelwriter.enum import nwBuildFmt from novelwriter.enum import nwBuildFmt, nwComment
from novelwriter.error import formatException, logException from novelwriter.error import formatException, logException
from novelwriter.formats.todocx import ToDocX from novelwriter.formats.todocx import ToDocX
from novelwriter.formats.tohtml import ToHtml from novelwriter.formats.tohtml import ToHtml
@@ -311,10 +311,12 @@ class NWBuildDocument:
) )
bldObj.setBodyText(self._build.getBool("text.includeBodyText")) bldObj.setBodyText(self._build.getBool("text.includeBodyText"))
bldObj.setSynopsis(self._build.getBool("text.includeSynopsis"))
bldObj.setComments(self._build.getBool("text.includeComments"))
bldObj.setKeywords(self._build.getBool("text.includeKeywords")) bldObj.setKeywords(self._build.getBool("text.includeKeywords"))
bldObj.setIgnoredKeywords(self._build.getStr("text.ignoredKeywords")) bldObj.setIgnoredKeywords(self._build.getStr("text.ignoredKeywords"))
bldObj.setCommentType(nwComment.PLAIN, self._build.getBool("text.includeComments"))
bldObj.setCommentType(nwComment.SYNOPSIS, self._build.getBool("text.includeSynopsis"))
bldObj.setCommentType(nwComment.SHORT, self._build.getBool("text.includeSynopsis"))
bldObj.setCommentType(nwComment.STORY, self._build.getBool("text.includeStory"))
if isinstance(bldObj, ToHtml): if isinstance(bldObj, ToHtml):
bldObj.setStyles(self._build.getBool("html.addStyles")) bldObj.setStyles(self._build.getBool("html.addStyles"))
+13 -14
View File
@@ -121,14 +121,16 @@ class Tokenizer(ABC):
self._indentFirst = False # Indent first paragraph self._indentFirst = False # Indent first paragraph
self._doJustify = False # Justify text self._doJustify = False # Justify text
self._doBodyText = True # Include body text self._doBodyText = True # Include body text
self._doSynopsis = False # Also process synopsis comments self._doComments = set() # Comment styles to allow
self._doComments = False # Also process comments
self._doKeywords = False # Also process keywords like tags and references self._doKeywords = False # Also process keywords like tags and references
self._keepBreaks = True # Keep line breaks in paragraphs self._keepBreaks = True # Keep line breaks in paragraphs
self._defaultAlign = "left" # The default text alignment self._defaultAlign = "left" # The default text alignment
self._skipKeywords: set[str] = set() # Keywords to ignore self._skipKeywords: set[str] = set() # Keywords to ignore
# Defaults
self._doComments.add(nwComment.FOOTNOTE)
# Other Setting # Other Setting
self._theme = TextDocumentTheme() self._theme = TextDocumentTheme()
self._classes: dict[str, QColor] = {} self._classes: dict[str, QColor] = {}
@@ -396,14 +398,12 @@ class Tokenizer(ABC):
self._doBodyText = state self._doBodyText = state
return return
def setSynopsis(self, state: bool) -> None: def setCommentType(self, comment: nwComment, state: bool) -> None:
"""Include synopsis comments in build.""" """Toggle the inclusion og certain comment types."""
self._doSynopsis = state if state:
return self._doComments.add(comment)
else:
def setComments(self, state: bool) -> None: self._doComments.discard(comment)
"""Include comments in build."""
self._doComments = state
return return
def setKeywords(self, state: bool) -> None: def setKeywords(self, state: bool) -> None:
@@ -607,9 +607,7 @@ class Tokenizer(ABC):
continue continue
cStyle, cKey, cText, _, _ = processComment(aLine) cStyle, cKey, cText, _, _ = processComment(aLine)
if cStyle in (nwComment.SYNOPSIS, nwComment.SHORT) and not self._doSynopsis: if cStyle not in self._doComments:
continue
if cStyle == nwComment.PLAIN and not self._doComments:
continue continue
if doJustify and not tStyle & BlockFmt.ALIGNED: if doJustify and not tStyle & BlockFmt.ALIGNED:
@@ -1043,7 +1041,8 @@ class Tokenizer(ABC):
tTxt, tFmt = self._extractFormats(text) tTxt, tFmt = self._extractFormats(text)
tFmt.insert(0, (0, TextFmt.COL_B, style.textClass)) tFmt.insert(0, (0, TextFmt.COL_B, style.textClass))
tFmt.append((len(tTxt), TextFmt.COL_E, "")) tFmt.append((len(tTxt), TextFmt.COL_E, ""))
if label := (self._localLookup(style.label) + (f" ({key})" if key else "")).strip(): term = f" ({key.title()})" if key else ""
if label := f"{self._localLookup(style.label)}{term}".strip():
shift = len(label) + 2 shift = len(label) + 2
tTxt = f"{label}: {tTxt}" tTxt = f"{label}: {tTxt}"
rFmt = [(0, TextFmt.B_B, ""), (shift - 1, TextFmt.B_E, "")] rFmt = [(0, TextFmt.B_B, ""), (shift - 1, TextFmt.B_E, "")]
+4 -3
View File
@@ -43,7 +43,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import decodeMimeHandles, qtAddAction, qtLambda from novelwriter.common import decodeMimeHandles, qtAddAction, qtLambda
from novelwriter.constants import nwConst, nwStyles, nwUnicode from novelwriter.constants import nwConst, nwStyles, nwUnicode
from novelwriter.enum import nwChange, nwDocAction, nwDocMode, nwItemType from novelwriter.enum import nwChange, nwComment, nwDocAction, nwDocMode, nwItemType
from novelwriter.error import logException from novelwriter.error import logException
from novelwriter.extensions.configlayout import NColorLabel from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.eventfilters import WheelEventFilter from novelwriter.extensions.eventfilters import WheelEventFilter
@@ -228,8 +228,9 @@ class GuiDocViewer(QTextBrowser):
qDoc.setTheme(self._docTheme) qDoc.setTheme(self._docTheme)
qDoc.initDocument() qDoc.initDocument()
qDoc.setKeywords(True) qDoc.setKeywords(True)
qDoc.setComments(CONFIG.viewComments) qDoc.setCommentType(nwComment.PLAIN, CONFIG.viewComments)
qDoc.setSynopsis(CONFIG.viewSynopsis) qDoc.setCommentType(nwComment.SYNOPSIS, CONFIG.viewSynopsis)
qDoc.setCommentType(nwComment.SHORT, CONFIG.viewSynopsis)
# Be extra careful here to prevent crashes when first opening a # Be extra careful here to prevent crashes when first opening a
# project as a crash here leaves no way of recovering. # project as a crash here leaves no way of recovering.
+1 -1
View File
@@ -629,7 +629,7 @@ class _DetailsWidget(QWidget):
item.setText(1, "") item.setText(1, "")
self.listView.addTopLevelItem(item) self.listView.addTopLevelItem(item)
for key in [ for key in [
"text.includeSynopsis", "text.includeComments", "text.includeSynopsis", "text.includeComments", "text.includeStory",
"text.includeKeywords", "text.includeBodyText", "text.includeKeywords", "text.includeBodyText",
]: ]:
sub = QTreeWidgetItem() sub = QTreeWidgetItem()
+4
View File
@@ -951,11 +951,13 @@ class _FormattingTab(NScrollableForm):
self.incBodyText = NSwitch(self, height=iPx) self.incBodyText = NSwitch(self, height=iPx)
self.incSynopsis = NSwitch(self, height=iPx) self.incSynopsis = NSwitch(self, height=iPx)
self.incComments = NSwitch(self, height=iPx) self.incComments = NSwitch(self, height=iPx)
self.incStory = NSwitch(self, height=iPx)
self.incKeywords = NSwitch(self, height=iPx) self.incKeywords = NSwitch(self, height=iPx)
self.addRow(self._build.getLabel("text.includeBodyText"), self.incBodyText) self.addRow(self._build.getLabel("text.includeBodyText"), self.incBodyText)
self.addRow(self._build.getLabel("text.includeSynopsis"), self.incSynopsis) self.addRow(self._build.getLabel("text.includeSynopsis"), self.incSynopsis)
self.addRow(self._build.getLabel("text.includeComments"), self.incComments) self.addRow(self._build.getLabel("text.includeComments"), self.incComments)
self.addRow(self._build.getLabel("text.includeStory"), self.incStory)
self.addRow(self._build.getLabel("text.includeKeywords"), self.incKeywords) self.addRow(self._build.getLabel("text.includeKeywords"), self.incKeywords)
# Ignored Keywords # Ignored Keywords
@@ -1264,6 +1266,7 @@ class _FormattingTab(NScrollableForm):
self.incBodyText.setChecked(self._build.getBool("text.includeBodyText")) self.incBodyText.setChecked(self._build.getBool("text.includeBodyText"))
self.incSynopsis.setChecked(self._build.getBool("text.includeSynopsis")) self.incSynopsis.setChecked(self._build.getBool("text.includeSynopsis"))
self.incComments.setChecked(self._build.getBool("text.includeComments")) self.incComments.setChecked(self._build.getBool("text.includeComments"))
self.incStory.setChecked(self._build.getBool("text.includeStory"))
self.incKeywords.setChecked(self._build.getBool("text.includeKeywords")) self.incKeywords.setChecked(self._build.getBool("text.includeKeywords"))
self.ignoredKeywords.setText(self._build.getStr("text.ignoredKeywords")) self.ignoredKeywords.setText(self._build.getStr("text.ignoredKeywords"))
self.addNoteHead.setChecked(self._build.getBool("text.addNoteHeadings")) self.addNoteHead.setChecked(self._build.getBool("text.addNoteHeadings"))
@@ -1362,6 +1365,7 @@ class _FormattingTab(NScrollableForm):
self._build.setValue("text.includeBodyText", self.incBodyText.isChecked()) self._build.setValue("text.includeBodyText", self.incBodyText.isChecked())
self._build.setValue("text.includeSynopsis", self.incSynopsis.isChecked()) self._build.setValue("text.includeSynopsis", self.incSynopsis.isChecked())
self._build.setValue("text.includeComments", self.incComments.isChecked()) self._build.setValue("text.includeComments", self.incComments.isChecked())
self._build.setValue("text.includeStory", self.incStory.isChecked())
self._build.setValue("text.includeKeywords", self.incKeywords.isChecked()) self._build.setValue("text.includeKeywords", self.incKeywords.isChecked())
self._build.setValue("text.ignoredKeywords", self.ignoredKeywords.text()) self._build.setValue("text.ignoredKeywords", self.ignoredKeywords.text())
self._build.setValue("text.addNoteHeadings", self.addNoteHead.isChecked()) self._build.setValue("text.addNoteHeadings", self.addNoteHead.isChecked())
+7 -6
View File
@@ -30,7 +30,7 @@ from novelwriter.constants import nwHeadFmt
from novelwriter.core.buildsettings import BuildSettings from novelwriter.core.buildsettings import BuildSettings
from novelwriter.core.docbuild import NWBuildDocument from novelwriter.core.docbuild import NWBuildDocument
from novelwriter.core.project import NWProject from novelwriter.core.project import NWProject
from novelwriter.enum import nwBuildFmt from novelwriter.enum import nwBuildFmt, nwComment
from novelwriter.formats.shared import BlockFmt, BlockTyp from novelwriter.formats.shared import BlockFmt, BlockTyp
from novelwriter.formats.todocx import OOXML_SCM, ToDocX, _mkTag, _wTag from novelwriter.formats.todocx import OOXML_SCM, ToDocX, _mkTag, _wTag
@@ -226,8 +226,9 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
"""Test formatting of paragraphs.""" """Test formatting of paragraphs."""
project = NWProject() project = NWProject()
doc = ToDocX(project) doc = ToDocX(project)
doc.setSynopsis(True) doc.setCommentType(nwComment.PLAIN, True)
doc.setComments(True) doc.setCommentType(nwComment.SYNOPSIS, True)
doc.setCommentType(nwComment.SHORT, True)
doc.setKeywords(True) doc.setKeywords(True)
doc.initDocument() doc.initDocument()
@@ -389,8 +390,8 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
"""Test formatting of paragraphs.""" """Test formatting of paragraphs."""
project = NWProject() project = NWProject()
doc = ToDocX(project) doc = ToDocX(project)
doc.setSynopsis(True) doc.setCommentType(nwComment.PLAIN, True)
doc.setComments(True) doc.setCommentType(nwComment.SYNOPSIS, True)
doc.setKeywords(True) doc.setKeywords(True)
doc.initDocument() doc.initDocument()
@@ -743,7 +744,7 @@ def testFmtToDocX_SaveDocument(mockGUI, prjLipsum, fncPath, tstPaths):
def prettifyXml(inFile, outFile): def prettifyXml(inFile, outFile):
with open(outFile, mode="wb") as fStream: with open(outFile, mode="wb") as fStream:
xml = ET.parse(inFile) xml = ET.parse(inFile)
xmlIndent(xml) xmlIndent(xml) # type: ignore
xml.write(fStream, encoding="utf-8", xml_declaration=True) xml.write(fStream, encoding="utf-8", xml_declaration=True)
expected = [ expected = [
+5 -4
View File
@@ -27,6 +27,7 @@ import pytest
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.constants import nwHeadFmt from novelwriter.constants import nwHeadFmt
from novelwriter.core.project import NWProject from novelwriter.core.project import NWProject
from novelwriter.enum import nwComment
from novelwriter.formats.shared import BlockFmt, BlockTyp from novelwriter.formats.shared import BlockFmt, BlockTyp
from novelwriter.formats.tohtml import ToHtml from novelwriter.formats.tohtml import ToHtml
@@ -185,7 +186,7 @@ def testFmtToHtml_ConvertParagraphs(mockGUI):
html.doConvert() html.doConvert()
assert html._pages[-1] == "" assert html._pages[-1] == ""
html.setSynopsis(True) html.setCommentType(nwComment.SYNOPSIS, True)
html._text = "%synopsis: The synopsis ...\n" html._text = "%synopsis: The synopsis ...\n"
html.tokenizeText() html.tokenizeText()
html.doConvert() html.doConvert()
@@ -196,7 +197,7 @@ def testFmtToHtml_ConvertParagraphs(mockGUI):
"</p>\n" "</p>\n"
) )
html.setSynopsis(True) html.setCommentType(nwComment.SHORT, True)
html._text = "%short: A short description ...\n" html._text = "%short: A short description ...\n"
html.tokenizeText() html.tokenizeText()
html.doConvert() html.doConvert()
@@ -213,7 +214,7 @@ def testFmtToHtml_ConvertParagraphs(mockGUI):
html.doConvert() html.doConvert()
assert html._pages[-1] == "" assert html._pages[-1] == ""
html.setComments(True) html.setCommentType(nwComment.PLAIN, True)
html._text = "% A comment ...\n" html._text = "% A comment ...\n"
html.tokenizeText() html.tokenizeText()
html.doConvert() html.doConvert()
@@ -575,7 +576,7 @@ def testFmtToHtml_SpecialCases(mockGUI):
# =================== # ===================
# See: https://github.com/vkbo/novelWriter/issues/950 # See: https://github.com/vkbo/novelWriter/issues/950
html.setComments(True) html.setCommentType(nwComment.PLAIN, True)
html._text = "% Test > text _<**bold**>_ and more.\n" html._text = "% Test > text _<**bold**>_ and more.\n"
html.tokenizeText() html.tokenizeText()
html.doConvert() html.doConvert()
+20 -19
View File
@@ -99,8 +99,7 @@ def testFmtToken_Setters(mockGUI):
assert tokens._hideSection is False assert tokens._hideSection is False
assert tokens._linkHeadings is False assert tokens._linkHeadings is False
assert tokens._doBodyText is True assert tokens._doBodyText is True
assert tokens._doSynopsis is False assert tokens._doComments == {nwComment.FOOTNOTE}
assert tokens._doComments is False
assert tokens._doKeywords is False assert tokens._doKeywords is False
# Set new values # Set new values
@@ -124,8 +123,9 @@ def testFmtToken_Setters(mockGUI):
tokens.setSeparatorMargins(2.0, 2.0) tokens.setSeparatorMargins(2.0, 2.0)
tokens.setLinkHeadings(True) tokens.setLinkHeadings(True)
tokens.setBodyText(False) tokens.setBodyText(False)
tokens.setSynopsis(True) tokens.setCommentType(nwComment.PLAIN, True)
tokens.setComments(True) tokens.setCommentType(nwComment.SHORT, True)
tokens.setCommentType(nwComment.SYNOPSIS, True)
tokens.setKeywords(True) tokens.setKeywords(True)
# Check new values # Check new values
@@ -155,8 +155,9 @@ def testFmtToken_Setters(mockGUI):
assert tokens._hideSection is True assert tokens._hideSection is True
assert tokens._linkHeadings is True assert tokens._linkHeadings is True
assert tokens._doBodyText is False assert tokens._doBodyText is False
assert tokens._doSynopsis is True assert tokens._doComments == {
assert tokens._doComments is True nwComment.FOOTNOTE, nwComment.PLAIN, nwComment.SYNOPSIS, nwComment.SHORT,
}
assert tokens._doKeywords is True assert tokens._doKeywords is True
# Properties # Properties
@@ -756,12 +757,12 @@ def testFmtToken_MetaFormat(mockGUI):
assert tokens._blocks == [] assert tokens._blocks == []
# Comment # Comment
tokens.setComments(False) tokens.setCommentType(nwComment.PLAIN, False)
tokens._text = "% A comment\n" tokens._text = "% A comment\n"
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [] assert tokens._blocks == []
tokens.setComments(True) tokens.setCommentType(nwComment.PLAIN, True)
tokens._text = "% A comment\n" tokens._text = "% A comment\n"
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [( assert tokens._blocks == [(
@@ -773,12 +774,12 @@ def testFmtToken_MetaFormat(mockGUI):
)] )]
# Synopsis # Synopsis
tokens.setSynopsis(False) tokens.setCommentType(nwComment.SYNOPSIS, False)
tokens._text = "%synopsis: The synopsis\n" tokens._text = "%synopsis: The synopsis\n"
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [] assert tokens._blocks == []
tokens.setSynopsis(True) tokens.setCommentType(nwComment.SYNOPSIS, True)
tokens._text = "% synopsis: The synopsis\n" tokens._text = "% synopsis: The synopsis\n"
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [( assert tokens._blocks == [(
@@ -790,12 +791,12 @@ def testFmtToken_MetaFormat(mockGUI):
)] )]
# Short # Short
tokens.setSynopsis(False) tokens.setCommentType(nwComment.SHORT, False)
tokens._text = "% short: A short description\n" tokens._text = "% short: A short description\n"
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [] assert tokens._blocks == []
tokens.setSynopsis(True) tokens.setCommentType(nwComment.SHORT, True)
tokens._text = "% short: A short description\n" tokens._text = "% short: A short description\n"
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [( assert tokens._blocks == [(
@@ -1151,7 +1152,7 @@ def testFmtToken_LineBreak(mockGUI):
project = NWProject() project = NWProject()
tokens = BareTokenizer(project) tokens = BareTokenizer(project)
tokens._handle = TMH tokens._handle = TMH
tokens.setComments(True) tokens.setCommentType(nwComment.PLAIN, True)
# They are stripped in headers # They are stripped in headers
tokens._text = "## Hello[br] World" tokens._text = "## Hello[br] World"
@@ -1516,7 +1517,7 @@ def testFmtToken_TextIndent(mockGUI):
"""Test the handling of text indent in the Tokenizer class.""" """Test the handling of text indent in the Tokenizer class."""
project = NWProject() project = NWProject()
tokens = BareTokenizer(project) tokens = BareTokenizer(project)
tokens.setSynopsis(True) tokens.setCommentType(nwComment.SYNOPSIS, True)
tokens._handle = TMH tokens._handle = TMH
# No First Indent # No First Indent
@@ -1987,7 +1988,7 @@ def testFmtToken_CountStats(mockGUI, ipsumText):
tokens._counts = {} tokens._counts = {}
tokens.setChapterFormat(nwHeadFmt.TITLE) tokens.setChapterFormat(nwHeadFmt.TITLE)
tokens.setSceneFormat("* * *", False) tokens.setSceneFormat("* * *", False)
tokens.setSynopsis(True) tokens.setCommentType(nwComment.SYNOPSIS, True)
tokens.tokenizeText() tokens.tokenizeText()
tokens.countStats() tokens.countStats()
assert [t[2] for t in tokens._blocks] == ["Chapter", "Synopsis: Stuff", "Text"] assert [t[2] for t in tokens._blocks] == ["Chapter", "Synopsis: Stuff", "Text"]
@@ -2004,7 +2005,7 @@ def testFmtToken_CountStats(mockGUI, ipsumText):
tokens._counts = {} tokens._counts = {}
tokens.setChapterFormat(nwHeadFmt.TITLE) tokens.setChapterFormat(nwHeadFmt.TITLE)
tokens.setSceneFormat("* * *", False) tokens.setSceneFormat("* * *", False)
tokens.setSynopsis(True) tokens.setCommentType(nwComment.SHORT, True)
tokens.tokenizeText() tokens.tokenizeText()
tokens.countStats() tokens.countStats()
assert [t[2] for t in tokens._blocks] == ["Chapter", "Short Description: Stuff", "Text"] assert [t[2] for t in tokens._blocks] == ["Chapter", "Short Description: Stuff", "Text"]
@@ -2021,7 +2022,7 @@ def testFmtToken_CountStats(mockGUI, ipsumText):
tokens._counts = {} tokens._counts = {}
tokens.setChapterFormat(nwHeadFmt.TITLE) tokens.setChapterFormat(nwHeadFmt.TITLE)
tokens.setSceneFormat("* * *", False) tokens.setSceneFormat("* * *", False)
tokens.setComments(True) tokens.setCommentType(nwComment.PLAIN, True)
tokens.tokenizeText() tokens.tokenizeText()
tokens.countStats() tokens.countStats()
assert [t[2] for t in tokens._blocks] == ["Chapter", "Comment: Stuff", "Text"] assert [t[2] for t in tokens._blocks] == ["Chapter", "Comment: Stuff", "Text"]
@@ -2095,8 +2096,8 @@ def testFmtToken_CountStats(mockGUI, ipsumText):
tokens.setPartitionFormat(f"T: {nwHeadFmt.TITLE}") tokens.setPartitionFormat(f"T: {nwHeadFmt.TITLE}")
tokens.setChapterFormat(f"C {nwHeadFmt.CH_NUM}: {nwHeadFmt.TITLE}") tokens.setChapterFormat(f"C {nwHeadFmt.CH_NUM}: {nwHeadFmt.TITLE}")
tokens.setSceneFormat("* * *", False) tokens.setSceneFormat("* * *", False)
tokens.setSynopsis(True) tokens.setCommentType(nwComment.SYNOPSIS, True)
tokens.setComments(True) tokens.setCommentType(nwComment.PLAIN, True)
tokens.setKeywords(True) tokens.setKeywords(True)
tokens.tokenizeText() tokens.tokenizeText()
+4 -3
View File
@@ -24,6 +24,7 @@ import pytest
from novelwriter.constants import nwHeadFmt from novelwriter.constants import nwHeadFmt
from novelwriter.core.project import NWProject from novelwriter.core.project import NWProject
from novelwriter.enum import nwComment
from novelwriter.formats.shared import BlockFmt, BlockTyp from novelwriter.formats.shared import BlockFmt, BlockTyp
from novelwriter.formats.tomarkdown import ToMarkdown from novelwriter.formats.tomarkdown import ToMarkdown
@@ -148,13 +149,13 @@ def testFmtToMarkdown_ConvertParagraphs(mockGUI):
md.doConvert() md.doConvert()
assert md._pages[-1] == "" assert md._pages[-1] == ""
md.setSynopsis(True) md.setCommentType(nwComment.SYNOPSIS, True)
md._text = "%synopsis: The synopsis ...\n" md._text = "%synopsis: The synopsis ...\n"
md.tokenizeText() md.tokenizeText()
md.doConvert() md.doConvert()
assert md._pages[-1] == "**Synopsis:** The synopsis ...\n\n" assert md._pages[-1] == "**Synopsis:** The synopsis ...\n\n"
md.setSynopsis(True) md.setCommentType(nwComment.SHORT, True)
md._text = "%short: A description ...\n" md._text = "%short: A description ...\n"
md.tokenizeText() md.tokenizeText()
md.doConvert() md.doConvert()
@@ -166,7 +167,7 @@ def testFmtToMarkdown_ConvertParagraphs(mockGUI):
md.doConvert() md.doConvert()
assert md._pages[-1] == "" assert md._pages[-1] == ""
md.setComments(True) md.setCommentType(nwComment.PLAIN, True)
md._text = "% A comment ...\n" md._text = "% A comment ...\n"
md.tokenizeText() md.tokenizeText()
md.doConvert() md.doConvert()
+4 -2
View File
@@ -32,6 +32,7 @@ from PyQt6.QtGui import QColor
from novelwriter.common import xmlIndent from novelwriter.common import xmlIndent
from novelwriter.constants import nwHeadFmt from novelwriter.constants import nwHeadFmt
from novelwriter.core.project import NWProject from novelwriter.core.project import NWProject
from novelwriter.enum import nwComment
from novelwriter.formats.shared import BlockFmt, BlockTyp, TextFmt from novelwriter.formats.shared import BlockFmt, BlockTyp, TextFmt
from novelwriter.formats.toodt import ODTParagraphStyle, ODTTextStyle, ToOdt, XMLParagraph, _mkTag from novelwriter.formats.toodt import ODTParagraphStyle, ODTTextStyle, ToOdt, XMLParagraph, _mkTag
@@ -611,8 +612,9 @@ def testFmtToOdt_ConvertParagraphs(mockGUI):
"% short: Then what\n\n" "% short: Then what\n\n"
"% A plain comment\n\n" "% A plain comment\n\n"
) )
odt.setSynopsis(True) odt.setCommentType(nwComment.SYNOPSIS, True)
odt.setComments(True) odt.setCommentType(nwComment.SHORT, True)
odt.setCommentType(nwComment.PLAIN, True)
odt.setKeywords(True) odt.setKeywords(True)
odt.tokenizeText() odt.tokenizeText()
odt.initDocument() odt.initDocument()
+5 -4
View File
@@ -27,6 +27,7 @@ from PyQt6.QtGui import QFont, QTextBlock, QTextCharFormat, QTextCursor
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.constants import nwUnicode from novelwriter.constants import nwUnicode
from novelwriter.core.project import NWProject from novelwriter.core.project import NWProject
from novelwriter.enum import nwComment
from novelwriter.formats.shared import BlockFmt, BlockTyp, TextDocumentTheme from novelwriter.formats.shared import BlockFmt, BlockTyp, TextDocumentTheme
from novelwriter.formats.toqdoc import ToQTextDocument from novelwriter.formats.toqdoc import ToQTextDocument
from novelwriter.types import ( from novelwriter.types import (
@@ -195,8 +196,8 @@ def testFmtToQTextDocument_NovelMeta(mockGUI):
doc._isNovel = True doc._isNovel = True
doc._isFirst = True doc._isFirst = True
doc.setComments(True) doc.setCommentType(nwComment.PLAIN, True)
doc.setSynopsis(True) doc.setCommentType(nwComment.SYNOPSIS, True)
doc.setKeywords(True) doc.setKeywords(True)
doc._text = ( doc._text = (
"### Scene\n\n" "### Scene\n\n"
@@ -272,8 +273,8 @@ def testFmtToQTextDocument_NoteMeta(mockGUI):
doc._isNovel = False doc._isNovel = False
doc._isFirst = True doc._isFirst = True
doc.setComments(True) doc.setCommentType(nwComment.PLAIN, True)
doc.setSynopsis(True) doc.setCommentType(nwComment.SHORT, True)
doc.setKeywords(True) doc.setKeywords(True)
doc._text = ( doc._text = (
"# Jane Smith\n\n" "# Jane Smith\n\n"