novelWriter 2.4.3__py3-none-any.whl → 2.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/METADATA +4 -5
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/RECORD +122 -112
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +33 -39
- novelwriter/assets/i18n/nw_de_DE.qm +0 -0
- novelwriter/assets/i18n/nw_en_US.qm +0 -0
- novelwriter/assets/i18n/nw_es_419.qm +0 -0
- novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
- novelwriter/assets/i18n/nw_it_IT.qm +0 -0
- novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
- novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
- novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
- novelwriter/assets/i18n/nw_pl_PL.qm +0 -0
- novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/i18n/project_en_GB.json +1 -0
- novelwriter/assets/i18n/project_pl_PL.json +116 -0
- novelwriter/assets/i18n/project_pt_BR.json +74 -74
- novelwriter/assets/icons/typicons_dark/icons.conf +2 -0
- novelwriter/assets/icons/typicons_dark/nw_font.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_quote.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +2 -0
- novelwriter/assets/icons/typicons_light/nw_font.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_quote.svg +4 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/syntax/cyberpunk_night.conf +5 -3
- novelwriter/assets/syntax/default_dark.conf +32 -18
- novelwriter/assets/syntax/default_light.conf +24 -10
- novelwriter/assets/syntax/dracula.conf +44 -0
- novelwriter/assets/syntax/grey_dark.conf +5 -4
- novelwriter/assets/syntax/grey_light.conf +5 -4
- novelwriter/assets/syntax/light_owl.conf +7 -6
- novelwriter/assets/syntax/night_owl.conf +7 -6
- novelwriter/assets/syntax/snazzy.conf +42 -0
- novelwriter/assets/syntax/solarized_dark.conf +4 -3
- novelwriter/assets/syntax/solarized_light.conf +4 -3
- novelwriter/assets/syntax/tango.conf +27 -11
- novelwriter/assets/syntax/tomorrow.conf +6 -5
- novelwriter/assets/syntax/tomorrow_night.conf +7 -6
- novelwriter/assets/syntax/tomorrow_night_blue.conf +6 -5
- novelwriter/assets/syntax/tomorrow_night_bright.conf +6 -5
- novelwriter/assets/syntax/tomorrow_night_eighties.conf +6 -5
- novelwriter/assets/text/credits_en.htm +52 -41
- novelwriter/assets/themes/cyberpunk_night.conf +3 -0
- novelwriter/assets/themes/default_dark.conf +2 -0
- novelwriter/assets/themes/default_light.conf +2 -0
- novelwriter/assets/themes/dracula.conf +48 -0
- novelwriter/assets/themes/solarized_dark.conf +2 -0
- novelwriter/assets/themes/solarized_light.conf +2 -0
- novelwriter/common.py +33 -12
- novelwriter/config.py +184 -98
- novelwriter/constants.py +47 -35
- novelwriter/core/buildsettings.py +68 -69
- novelwriter/core/coretools.py +5 -23
- novelwriter/core/docbuild.py +52 -40
- novelwriter/core/document.py +3 -5
- novelwriter/core/index.py +115 -45
- novelwriter/core/item.py +8 -19
- novelwriter/core/options.py +2 -4
- novelwriter/core/project.py +37 -61
- novelwriter/core/projectdata.py +1 -3
- novelwriter/core/projectxml.py +12 -15
- novelwriter/core/sessions.py +3 -5
- novelwriter/core/spellcheck.py +4 -9
- novelwriter/core/status.py +211 -164
- novelwriter/core/storage.py +0 -8
- novelwriter/core/tohtml.py +139 -105
- novelwriter/core/tokenizer.py +278 -122
- novelwriter/core/{tomd.py → tomarkdown.py} +97 -78
- novelwriter/core/toodt.py +257 -166
- novelwriter/core/toqdoc.py +419 -0
- novelwriter/core/tree.py +5 -7
- novelwriter/dialogs/about.py +11 -18
- novelwriter/dialogs/docmerge.py +17 -19
- novelwriter/dialogs/docsplit.py +17 -19
- novelwriter/dialogs/editlabel.py +6 -10
- novelwriter/dialogs/preferences.py +200 -164
- novelwriter/dialogs/projectsettings.py +225 -189
- novelwriter/dialogs/quotes.py +12 -9
- novelwriter/dialogs/wordlist.py +9 -15
- novelwriter/enum.py +35 -30
- novelwriter/error.py +8 -15
- novelwriter/extensions/configlayout.py +55 -21
- novelwriter/extensions/eventfilters.py +1 -5
- novelwriter/extensions/modified.py +70 -14
- novelwriter/extensions/novelselector.py +1 -3
- novelwriter/extensions/pagedsidebar.py +9 -12
- novelwriter/extensions/{circularprogress.py → progressbars.py} +30 -8
- novelwriter/extensions/statusled.py +40 -26
- novelwriter/extensions/switch.py +4 -6
- novelwriter/extensions/switchbox.py +7 -6
- novelwriter/extensions/versioninfo.py +3 -9
- novelwriter/gui/doceditor.py +120 -139
- novelwriter/gui/dochighlight.py +231 -186
- novelwriter/gui/docviewer.py +69 -108
- novelwriter/gui/docviewerpanel.py +3 -10
- novelwriter/gui/editordocument.py +1 -3
- novelwriter/gui/itemdetails.py +7 -11
- novelwriter/gui/mainmenu.py +22 -18
- novelwriter/gui/noveltree.py +11 -24
- novelwriter/gui/outline.py +15 -26
- novelwriter/gui/projtree.py +39 -65
- novelwriter/gui/search.py +10 -3
- novelwriter/gui/sidebar.py +2 -6
- novelwriter/gui/statusbar.py +29 -37
- novelwriter/gui/theme.py +26 -48
- novelwriter/guimain.py +162 -160
- novelwriter/shared.py +36 -19
- novelwriter/text/patterns.py +113 -0
- novelwriter/tools/dictionaries.py +10 -20
- novelwriter/tools/lipsum.py +10 -16
- novelwriter/tools/manusbuild.py +9 -11
- novelwriter/tools/manuscript.py +75 -149
- novelwriter/tools/manussettings.py +74 -76
- novelwriter/tools/noveldetails.py +16 -21
- novelwriter/tools/welcome.py +21 -26
- novelwriter/tools/writingstats.py +9 -12
- novelwriter/types.py +49 -4
- novelwriter/extensions/simpleprogress.py +0 -55
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/top_level.txt +0 -0
@@ -25,21 +25,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
25
|
from __future__ import annotations
|
26
26
|
|
27
27
|
import json
|
28
|
-
import uuid
|
29
28
|
import logging
|
29
|
+
import uuid
|
30
30
|
|
31
|
+
from collections.abc import Iterable
|
31
32
|
from enum import Enum
|
32
33
|
from pathlib import Path
|
33
|
-
from collections.abc import Iterable
|
34
34
|
|
35
35
|
from PyQt5.QtCore import QT_TRANSLATE_NOOP, QCoreApplication
|
36
36
|
|
37
37
|
from novelwriter import CONFIG
|
38
|
-
from novelwriter.enum import nwBuildFmt
|
39
|
-
from novelwriter.error import logException
|
40
38
|
from novelwriter.common import checkUuid, isHandle, jsonEncode
|
41
39
|
from novelwriter.constants import nwFiles, nwHeadFmt
|
42
40
|
from novelwriter.core.project import NWProject
|
41
|
+
from novelwriter.enum import nwBuildFmt
|
42
|
+
from novelwriter.error import logException
|
43
43
|
|
44
44
|
logger = logging.getLogger(__name__)
|
45
45
|
|
@@ -76,12 +76,16 @@ SETTINGS_TEMPLATE = {
|
|
76
76
|
"text.includeBodyText": (bool, True),
|
77
77
|
"text.ignoredKeywords": (str, ""),
|
78
78
|
"text.addNoteHeadings": (bool, True),
|
79
|
-
"format.textFont": (str, CONFIG.textFont),
|
80
|
-
"format.textSize": (int, 12),
|
79
|
+
"format.textFont": (str, CONFIG.textFont.toString()),
|
81
80
|
"format.lineHeight": (float, 1.15, 0.75, 3.0),
|
82
81
|
"format.justifyText": (bool, False),
|
83
82
|
"format.stripUnicode": (bool, False),
|
84
83
|
"format.replaceTabs": (bool, False),
|
84
|
+
"format.keepBreaks": (bool, True),
|
85
|
+
"format.showDialogue": (bool, False),
|
86
|
+
"format.firstLineIndent": (bool, False),
|
87
|
+
"format.firstIndentWidth": (float, 1.4),
|
88
|
+
"format.indentFirstPar": (bool, False),
|
85
89
|
"format.pageUnit": (str, "cm"),
|
86
90
|
"format.pageSize": (str, "A4"),
|
87
91
|
"format.pageWidth": (float, 21.0),
|
@@ -93,65 +97,66 @@ SETTINGS_TEMPLATE = {
|
|
93
97
|
"odt.addColours": (bool, True),
|
94
98
|
"odt.pageHeader": (str, nwHeadFmt.ODT_AUTO),
|
95
99
|
"odt.pageCountOffset": (int, 0),
|
96
|
-
"odt.firstLineIndent": (bool, False),
|
97
|
-
"md.preserveBreaks": (bool, True),
|
98
100
|
"html.addStyles": (bool, True),
|
99
101
|
"html.preserveTabs": (bool, False),
|
100
102
|
}
|
101
103
|
|
102
104
|
SETTINGS_LABELS = {
|
103
|
-
"filter":
|
104
|
-
"filter.includeNovel":
|
105
|
-
"filter.includeNotes":
|
106
|
-
"filter.includeInactive":
|
107
|
-
|
108
|
-
"headings":
|
109
|
-
"headings.fmtTitle":
|
110
|
-
"headings.fmtChapter":
|
111
|
-
"headings.fmtUnnumbered":
|
112
|
-
"headings.fmtScene":
|
113
|
-
"headings.fmtAltScene":
|
114
|
-
"headings.fmtSection":
|
115
|
-
|
116
|
-
"text.grpContent":
|
117
|
-
"text.includeSynopsis":
|
118
|
-
"text.includeComments":
|
119
|
-
"text.includeKeywords":
|
120
|
-
"text.includeBodyText":
|
121
|
-
"text.ignoredKeywords":
|
122
|
-
"text.grpInsert":
|
123
|
-
"text.addNoteHeadings":
|
124
|
-
|
125
|
-
"format.grpFormat":
|
126
|
-
"format.textFont":
|
127
|
-
"format.
|
128
|
-
"format.
|
129
|
-
"format.
|
130
|
-
"format.
|
131
|
-
"format.
|
132
|
-
"format.
|
133
|
-
"format.
|
134
|
-
|
135
|
-
"format.
|
136
|
-
"format.
|
137
|
-
"format.
|
138
|
-
"format.
|
139
|
-
|
140
|
-
"format.
|
141
|
-
"format.
|
142
|
-
|
143
|
-
"
|
144
|
-
"
|
145
|
-
"
|
146
|
-
"
|
147
|
-
"
|
148
|
-
|
149
|
-
|
150
|
-
"
|
151
|
-
|
152
|
-
"
|
153
|
-
"
|
154
|
-
|
105
|
+
"filter": QT_TRANSLATE_NOOP("Builds", "Document Filters"),
|
106
|
+
"filter.includeNovel": QT_TRANSLATE_NOOP("Builds", "Novel Documents"),
|
107
|
+
"filter.includeNotes": QT_TRANSLATE_NOOP("Builds", "Project Notes"),
|
108
|
+
"filter.includeInactive": QT_TRANSLATE_NOOP("Builds", "Inactive Documents"),
|
109
|
+
|
110
|
+
"headings": QT_TRANSLATE_NOOP("Builds", "Headings"),
|
111
|
+
"headings.fmtTitle": QT_TRANSLATE_NOOP("Builds", "Partition Format"),
|
112
|
+
"headings.fmtChapter": QT_TRANSLATE_NOOP("Builds", "Chapter Format"),
|
113
|
+
"headings.fmtUnnumbered": QT_TRANSLATE_NOOP("Builds", "Unnumbered Format"),
|
114
|
+
"headings.fmtScene": QT_TRANSLATE_NOOP("Builds", "Scene Format"),
|
115
|
+
"headings.fmtAltScene": QT_TRANSLATE_NOOP("Builds", "Alt. Scene Format"),
|
116
|
+
"headings.fmtSection": QT_TRANSLATE_NOOP("Builds", "Section Format"),
|
117
|
+
|
118
|
+
"text.grpContent": QT_TRANSLATE_NOOP("Builds", "Text Content"),
|
119
|
+
"text.includeSynopsis": QT_TRANSLATE_NOOP("Builds", "Include Synopsis"),
|
120
|
+
"text.includeComments": QT_TRANSLATE_NOOP("Builds", "Include Comments"),
|
121
|
+
"text.includeKeywords": QT_TRANSLATE_NOOP("Builds", "Include Keywords"),
|
122
|
+
"text.includeBodyText": QT_TRANSLATE_NOOP("Builds", "Include Body Text"),
|
123
|
+
"text.ignoredKeywords": QT_TRANSLATE_NOOP("Builds", "Ignore These Keywords"),
|
124
|
+
"text.grpInsert": QT_TRANSLATE_NOOP("Builds", "Insert Content"),
|
125
|
+
"text.addNoteHeadings": QT_TRANSLATE_NOOP("Builds", "Add Titles for Notes"),
|
126
|
+
|
127
|
+
"format.grpFormat": QT_TRANSLATE_NOOP("Builds", "Text Format"),
|
128
|
+
"format.textFont": QT_TRANSLATE_NOOP("Builds", "Text Font"),
|
129
|
+
"format.lineHeight": QT_TRANSLATE_NOOP("Builds", "Line Height"),
|
130
|
+
"format.grpOptions": QT_TRANSLATE_NOOP("Builds", "Text Options"),
|
131
|
+
"format.justifyText": QT_TRANSLATE_NOOP("Builds", "Justify Text Margins"),
|
132
|
+
"format.stripUnicode": QT_TRANSLATE_NOOP("Builds", "Replace Unicode Characters"),
|
133
|
+
"format.replaceTabs": QT_TRANSLATE_NOOP("Builds", "Replace Tabs with Spaces"),
|
134
|
+
"format.keepBreaks": QT_TRANSLATE_NOOP("Builds", "Preserve Hard Line Breaks"),
|
135
|
+
"format.showDialogue": QT_TRANSLATE_NOOP("Builds", "Apply Dialogue Highlighting"),
|
136
|
+
|
137
|
+
"format.grpParIndent": QT_TRANSLATE_NOOP("Builds", "First Line Indent"),
|
138
|
+
"format.firstLineIndent": QT_TRANSLATE_NOOP("Builds", "Enable Indent"),
|
139
|
+
"format.firstIndentWidth": QT_TRANSLATE_NOOP("Builds", "Indent Width"),
|
140
|
+
"format.indentFirstPar": QT_TRANSLATE_NOOP("Builds", "Indent First Paragraph"),
|
141
|
+
|
142
|
+
"format.grpPage": QT_TRANSLATE_NOOP("Builds", "Page Layout"),
|
143
|
+
"format.pageUnit": QT_TRANSLATE_NOOP("Builds", "Unit"),
|
144
|
+
"format.pageSize": QT_TRANSLATE_NOOP("Builds", "Page Size"),
|
145
|
+
"format.pageWidth": QT_TRANSLATE_NOOP("Builds", "Page Width"),
|
146
|
+
"format.pageHeight": QT_TRANSLATE_NOOP("Builds", "Page Height"),
|
147
|
+
"format.topMargin": QT_TRANSLATE_NOOP("Builds", "Top Margin"),
|
148
|
+
"format.bottomMargin": QT_TRANSLATE_NOOP("Builds", "Bottom Margin"),
|
149
|
+
"format.leftMargin": QT_TRANSLATE_NOOP("Builds", "Left Margin"),
|
150
|
+
"format.rightMargin": QT_TRANSLATE_NOOP("Builds", "Right Margin"),
|
151
|
+
|
152
|
+
"odt": QT_TRANSLATE_NOOP("Builds", "Open Document (.odt)"),
|
153
|
+
"odt.addColours": QT_TRANSLATE_NOOP("Builds", "Add Highlight Colours"),
|
154
|
+
"odt.pageHeader": QT_TRANSLATE_NOOP("Builds", "Page Header"),
|
155
|
+
"odt.pageCountOffset": QT_TRANSLATE_NOOP("Builds", "Page Counter Offset"),
|
156
|
+
|
157
|
+
"html": QT_TRANSLATE_NOOP("Builds", "HTML (.html)"),
|
158
|
+
"html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"),
|
159
|
+
"html.preserveTabs": QT_TRANSLATE_NOOP("Builds", "Preserve Tab Characters"),
|
155
160
|
}
|
156
161
|
|
157
162
|
|
@@ -165,8 +170,6 @@ class FilterMode(Enum):
|
|
165
170
|
SKIPPED = 4
|
166
171
|
ROOT = 5
|
167
172
|
|
168
|
-
# END Enum FilterMode
|
169
|
-
|
170
173
|
|
171
174
|
class BuildSettings:
|
172
175
|
"""Core: Build Settings Class
|
@@ -216,7 +219,7 @@ class BuildSettings:
|
|
216
219
|
return self._order
|
217
220
|
|
218
221
|
@property
|
219
|
-
def
|
222
|
+
def lastBuildPath(self) -> Path:
|
220
223
|
"""The last used build path."""
|
221
224
|
if self._path.is_dir():
|
222
225
|
return self._path
|
@@ -290,7 +293,7 @@ class BuildSettings:
|
|
290
293
|
self._order = value
|
291
294
|
return
|
292
295
|
|
293
|
-
def
|
296
|
+
def setLastBuildPath(self, path: Path | str | None) -> None:
|
294
297
|
"""Set the last used build path."""
|
295
298
|
if isinstance(path, str):
|
296
299
|
path = Path(path)
|
@@ -458,7 +461,7 @@ class BuildSettings:
|
|
458
461
|
self.setName(data.get("name", ""))
|
459
462
|
self.setBuildID(data.get("uuid", ""))
|
460
463
|
self.setOrder(data.get("order", 0))
|
461
|
-
self.
|
464
|
+
self.setLastBuildPath(data.get("path", None))
|
462
465
|
self.setLastBuildName(data.get("build", ""))
|
463
466
|
|
464
467
|
buildFmt = str(data.get("format", ""))
|
@@ -481,8 +484,6 @@ class BuildSettings:
|
|
481
484
|
|
482
485
|
return
|
483
486
|
|
484
|
-
# END Class BuildSettings
|
485
|
-
|
486
487
|
|
487
488
|
class BuildCollection:
|
488
489
|
"""Core: Build Collection Class
|
@@ -630,5 +631,3 @@ class BuildCollection:
|
|
630
631
|
return False
|
631
632
|
|
632
633
|
return True
|
633
|
-
|
634
|
-
# END Class BuildCollection
|
novelwriter/core/coretools.py
CHANGED
@@ -104,7 +104,7 @@ class DocMerger:
|
|
104
104
|
docText = self._project.storage.getDocumentText(srcHandle).rstrip("\n")
|
105
105
|
if addComment:
|
106
106
|
docInfo = srcItem.describeMe()
|
107
|
-
docSt, _ = srcItem.getImportStatus(
|
107
|
+
docSt, _ = srcItem.getImportStatus()
|
108
108
|
cmtLine = f"% {cmtPrefix} {docInfo}: {srcItem.itemName} [{docSt}]\n\n"
|
109
109
|
docText = cmtLine + docText
|
110
110
|
|
@@ -129,8 +129,6 @@ class DocMerger:
|
|
129
129
|
|
130
130
|
return status
|
131
131
|
|
132
|
-
# END Class DocMerger
|
133
|
-
|
134
132
|
|
135
133
|
class DocSplitter:
|
136
134
|
"""Document tool for splitting a document into a set of new
|
@@ -257,8 +255,6 @@ class DocSplitter:
|
|
257
255
|
|
258
256
|
return
|
259
257
|
|
260
|
-
# END Class DocSplitter
|
261
|
-
|
262
258
|
|
263
259
|
class DocDuplicator:
|
264
260
|
"""A class that will duplicate all documents and folders starting
|
@@ -297,8 +293,6 @@ class DocDuplicator:
|
|
297
293
|
nHandle = None
|
298
294
|
return
|
299
295
|
|
300
|
-
# END Class DocDuplicator
|
301
|
-
|
302
296
|
|
303
297
|
class DocSearch:
|
304
298
|
|
@@ -354,7 +348,9 @@ class DocSearch:
|
|
354
348
|
rxMatch = rxItt.next()
|
355
349
|
pos = rxMatch.capturedStart()
|
356
350
|
num = rxMatch.capturedLength()
|
357
|
-
|
351
|
+
lim = text[:pos].rfind("\n") + 1
|
352
|
+
cut = text[lim:pos].rfind(" ") + lim + 1
|
353
|
+
context = text[cut:cut+100].partition("\n")[0]
|
358
354
|
if context:
|
359
355
|
results.append((pos, num, context))
|
360
356
|
count += 1
|
@@ -370,23 +366,11 @@ class DocSearch:
|
|
370
366
|
def _buildPattern(self, search: str) -> str:
|
371
367
|
"""Build the search pattern string."""
|
372
368
|
if self._escape:
|
373
|
-
|
374
|
-
search = QRegularExpression.escape(search)
|
375
|
-
else:
|
376
|
-
# For older Qt versions, we escape manually
|
377
|
-
escaped = ""
|
378
|
-
for c in search:
|
379
|
-
if c.isalnum() or c == "_":
|
380
|
-
escaped += c
|
381
|
-
else:
|
382
|
-
escaped += f"\\{c}"
|
383
|
-
search = escaped
|
369
|
+
search = QRegularExpression.escape(search)
|
384
370
|
if self._words:
|
385
371
|
search = f"(?:^|\\b){search}(?:$|\\b)"
|
386
372
|
return search
|
387
373
|
|
388
|
-
# END Class DocSearch
|
389
|
-
|
390
374
|
|
391
375
|
class ProjectBuilder:
|
392
376
|
"""A class to build a new project from a set of user-defined
|
@@ -619,5 +603,3 @@ class ProjectBuilder:
|
|
619
603
|
return False
|
620
604
|
|
621
605
|
return True
|
622
|
-
|
623
|
-
# END Class ProjectBuilder
|
novelwriter/core/docbuild.py
CHANGED
@@ -25,22 +25,23 @@ from __future__ import annotations
|
|
25
25
|
|
26
26
|
import logging
|
27
27
|
|
28
|
-
from pathlib import Path
|
29
28
|
from collections.abc import Iterable
|
29
|
+
from pathlib import Path
|
30
30
|
|
31
|
-
from PyQt5.QtGui import QFont
|
31
|
+
from PyQt5.QtGui import QFont
|
32
32
|
|
33
33
|
from novelwriter import CONFIG
|
34
|
-
from novelwriter.enum import nwBuildFmt
|
35
|
-
from novelwriter.error import formatException, logException
|
36
34
|
from novelwriter.constants import nwLabels
|
35
|
+
from novelwriter.core.buildsettings import BuildSettings
|
37
36
|
from novelwriter.core.item import NWItem
|
38
|
-
from novelwriter.core.tomd import ToMarkdown
|
39
|
-
from novelwriter.core.toodt import ToOdt
|
40
|
-
from novelwriter.core.tohtml import ToHtml
|
41
37
|
from novelwriter.core.project import NWProject
|
38
|
+
from novelwriter.core.tohtml import ToHtml
|
42
39
|
from novelwriter.core.tokenizer import Tokenizer
|
43
|
-
from novelwriter.core.
|
40
|
+
from novelwriter.core.tomarkdown import ToMarkdown
|
41
|
+
from novelwriter.core.toodt import ToOdt
|
42
|
+
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
|
43
|
+
from novelwriter.enum import nwBuildFmt
|
44
|
+
from novelwriter.error import formatException, logException
|
44
45
|
|
45
46
|
logger = logging.getLogger(__name__)
|
46
47
|
|
@@ -54,7 +55,7 @@ class NWBuildDocument:
|
|
54
55
|
|
55
56
|
__slots__ = (
|
56
57
|
"_project", "_build", "_queue", "_error", "_cache", "_count",
|
57
|
-
"_outline",
|
58
|
+
"_outline",
|
58
59
|
)
|
59
60
|
|
60
61
|
def __init__(self, project: NWProject, build: BuildSettings) -> None:
|
@@ -65,7 +66,6 @@ class NWBuildDocument:
|
|
65
66
|
self._cache = None
|
66
67
|
self._count = False
|
67
68
|
self._outline = False
|
68
|
-
self._preview = False
|
69
69
|
return
|
70
70
|
|
71
71
|
##
|
@@ -99,15 +99,6 @@ class NWBuildDocument:
|
|
99
99
|
self._outline = state
|
100
100
|
return
|
101
101
|
|
102
|
-
def setPreviewMode(self, state: bool) -> None:
|
103
|
-
"""Set the preview mode of the build. This also enables stats
|
104
|
-
count and outline mode.
|
105
|
-
"""
|
106
|
-
self._preview = state
|
107
|
-
self._outline = state
|
108
|
-
self._count = state
|
109
|
-
return
|
110
|
-
|
111
102
|
##
|
112
103
|
# Special Methods
|
113
104
|
##
|
@@ -134,6 +125,32 @@ class NWBuildDocument:
|
|
134
125
|
self._queue.append(item.itemHandle)
|
135
126
|
return
|
136
127
|
|
128
|
+
def iterBuildPreview(self, theme: TextDocumentTheme) -> Iterable[tuple[int, bool]]:
|
129
|
+
"""Build a preview QTextDocument."""
|
130
|
+
makeObj = ToQTextDocument(self._project)
|
131
|
+
filtered = self._setupBuild(makeObj)
|
132
|
+
|
133
|
+
self._outline = True
|
134
|
+
self._count = True
|
135
|
+
|
136
|
+
font = QFont()
|
137
|
+
font.fromString(self._build.getStr("format.textFont"))
|
138
|
+
|
139
|
+
makeObj.initDocument(font, theme)
|
140
|
+
for i, tHandle in enumerate(self._queue):
|
141
|
+
self._error = None
|
142
|
+
if filtered.get(tHandle, (False, 0))[0]:
|
143
|
+
yield i, self._doBuild(makeObj, tHandle)
|
144
|
+
else:
|
145
|
+
yield i, False
|
146
|
+
|
147
|
+
makeObj.appendFootnotes()
|
148
|
+
|
149
|
+
self._error = None
|
150
|
+
self._cache = makeObj
|
151
|
+
|
152
|
+
return
|
153
|
+
|
137
154
|
def iterBuild(self, path: Path, bFormat: nwBuildFmt) -> Iterable[tuple[int, bool]]:
|
138
155
|
"""Wrapper for builders based on format."""
|
139
156
|
if bFormat in (nwBuildFmt.ODT, nwBuildFmt.FODT):
|
@@ -182,8 +199,6 @@ class NWBuildDocument:
|
|
182
199
|
makeObj = ToHtml(self._project)
|
183
200
|
filtered = self._setupBuild(makeObj)
|
184
201
|
|
185
|
-
makeObj.setPreview(self._preview)
|
186
|
-
makeObj.setLinkHeadings(self._preview)
|
187
202
|
for i, tHandle in enumerate(self._queue):
|
188
203
|
self._error = None
|
189
204
|
if filtered.get(tHandle, (False, 0))[0]:
|
@@ -191,7 +206,9 @@ class NWBuildDocument:
|
|
191
206
|
else:
|
192
207
|
yield i, False
|
193
208
|
|
194
|
-
|
209
|
+
makeObj.appendFootnotes()
|
210
|
+
|
211
|
+
if not self._build.getBool("html.preserveTabs"):
|
195
212
|
makeObj.replaceTabs()
|
196
213
|
|
197
214
|
self._error = None
|
@@ -214,16 +231,10 @@ class NWBuildDocument:
|
|
214
231
|
makeObj = ToMarkdown(self._project)
|
215
232
|
filtered = self._setupBuild(makeObj)
|
216
233
|
|
217
|
-
|
218
|
-
makeObj.setExtendedMarkdown()
|
219
|
-
else:
|
220
|
-
makeObj.setStandardMarkdown()
|
221
|
-
|
234
|
+
makeObj.setExtendedMarkdown(extendedMd)
|
222
235
|
if self._build.getBool("format.replaceTabs"):
|
223
236
|
makeObj.replaceTabs(nSpaces=4, spaceChar=" ")
|
224
237
|
|
225
|
-
makeObj.setPreserveBreaks(self._build.getBool("md.preserveBreaks"))
|
226
|
-
|
227
238
|
for i, tHandle in enumerate(self._queue):
|
228
239
|
self._error = None
|
229
240
|
if filtered.get(tHandle, (False, 0))[0]:
|
@@ -231,6 +242,8 @@ class NWBuildDocument:
|
|
231
242
|
else:
|
232
243
|
yield i, False
|
233
244
|
|
245
|
+
makeObj.appendFootnotes()
|
246
|
+
|
234
247
|
self._error = None
|
235
248
|
self._cache = makeObj
|
236
249
|
|
@@ -281,13 +294,9 @@ class NWBuildDocument:
|
|
281
294
|
def _setupBuild(self, bldObj: Tokenizer) -> dict:
|
282
295
|
"""Configure the build object."""
|
283
296
|
# Get Settings
|
284
|
-
textFont =
|
285
|
-
|
286
|
-
|
287
|
-
fontFamily = textFont or CONFIG.textFont
|
288
|
-
bldFont = QFont(fontFamily, textSize)
|
289
|
-
fontInfo = QFontInfo(bldFont)
|
290
|
-
textFixed = fontInfo.fixedPitch()
|
297
|
+
textFont = QFont(CONFIG.textFont)
|
298
|
+
textFont.fromString(self._build.getStr("format.textFont"))
|
299
|
+
bldObj.setFont(textFont)
|
291
300
|
|
292
301
|
bldObj.setTitleFormat(
|
293
302
|
self._build.getStr("headings.fmtTitle"),
|
@@ -326,9 +335,15 @@ class NWBuildDocument:
|
|
326
335
|
self._build.getBool("headings.breakScene")
|
327
336
|
)
|
328
337
|
|
329
|
-
bldObj.setFont(fontFamily, textSize, textFixed)
|
330
338
|
bldObj.setJustify(self._build.getBool("format.justifyText"))
|
331
339
|
bldObj.setLineHeight(self._build.getFloat("format.lineHeight"))
|
340
|
+
bldObj.setKeepLineBreaks(self._build.getBool("format.keepBreaks"))
|
341
|
+
bldObj.setDialogueHighlight(self._build.getBool("format.showDialogue"))
|
342
|
+
bldObj.setFirstLineIndent(
|
343
|
+
self._build.getBool("format.firstLineIndent"),
|
344
|
+
self._build.getFloat("format.firstIndentWidth"),
|
345
|
+
self._build.getBool("format.indentFirstPar"),
|
346
|
+
)
|
332
347
|
|
333
348
|
bldObj.setBodyText(self._build.getBool("text.includeBodyText"))
|
334
349
|
bldObj.setSynopsis(self._build.getBool("text.includeSynopsis"))
|
@@ -346,7 +361,6 @@ class NWBuildDocument:
|
|
346
361
|
bldObj.setHeaderFormat(
|
347
362
|
self._build.getStr("odt.pageHeader"), self._build.getInt("odt.pageCountOffset")
|
348
363
|
)
|
349
|
-
bldObj.setFirstLineIndent(self._build.getBool("odt.firstLineIndent"))
|
350
364
|
|
351
365
|
scale = nwLabels.UNIT_SCALE.get(self._build.getStr("format.pageUnit"), 1.0)
|
352
366
|
pW, pH = nwLabels.PAPER_SIZE.get(self._build.getStr("format.pageSize"), (-1.0, -1.0))
|
@@ -397,5 +411,3 @@ class NWBuildDocument:
|
|
397
411
|
return False
|
398
412
|
|
399
413
|
return True
|
400
|
-
|
401
|
-
# END Class NWBuildDocument
|
novelwriter/core/document.py
CHANGED
@@ -26,14 +26,14 @@ from __future__ import annotations
|
|
26
26
|
import hashlib
|
27
27
|
import logging
|
28
28
|
|
29
|
+
from pathlib import Path
|
29
30
|
from time import time
|
30
31
|
from typing import TYPE_CHECKING
|
31
|
-
from pathlib import Path
|
32
32
|
|
33
|
-
from novelwriter.enum import nwItemLayout, nwItemClass
|
34
|
-
from novelwriter.error import formatException, logException
|
35
33
|
from novelwriter.common import formatTimeStamp, isHandle
|
36
34
|
from novelwriter.core.item import NWItem
|
35
|
+
from novelwriter.enum import nwItemClass, nwItemLayout
|
36
|
+
from novelwriter.error import formatException, logException
|
37
37
|
|
38
38
|
if TYPE_CHECKING: # pragma: no cover
|
39
39
|
from novelwriter.core.project import NWProject
|
@@ -359,5 +359,3 @@ class NWDocument:
|
|
359
359
|
logger.debug("Unknown meta data: '%s'", metaLine.strip())
|
360
360
|
|
361
361
|
return
|
362
|
-
|
363
|
-
# END Class NWDocument
|