novelWriter 2.6b1__py3-none-any.whl → 2.6b2__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.6b1.dist-info → novelWriter-2.6b2.dist-info}/METADATA +3 -3
- {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/RECORD +68 -52
- {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +49 -10
- novelwriter/assets/i18n/nw_de_DE.qm +0 -0
- novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
- novelwriter/assets/i18n/nw_ru_RU.qm +0 -0
- novelwriter/assets/i18n/project_de_DE.json +2 -2
- novelwriter/assets/i18n/project_ru_RU.json +11 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +7 -0
- novelwriter/assets/icons/typicons_dark/mixed_margin-bottom.svg +6 -0
- novelwriter/assets/icons/typicons_dark/mixed_margin-left.svg +6 -0
- novelwriter/assets/icons/typicons_dark/mixed_margin-right.svg +6 -0
- novelwriter/assets/icons/typicons_dark/mixed_margin-top.svg +6 -0
- novelwriter/assets/icons/typicons_dark/mixed_size-height.svg +6 -0
- novelwriter/assets/icons/typicons_dark/mixed_size-width.svg +6 -0
- novelwriter/assets/icons/typicons_dark/nw_toolbar.svg +5 -0
- novelwriter/assets/icons/typicons_light/icons.conf +7 -0
- novelwriter/assets/icons/typicons_light/mixed_margin-bottom.svg +6 -0
- novelwriter/assets/icons/typicons_light/mixed_margin-left.svg +6 -0
- novelwriter/assets/icons/typicons_light/mixed_margin-right.svg +6 -0
- novelwriter/assets/icons/typicons_light/mixed_margin-top.svg +6 -0
- novelwriter/assets/icons/typicons_light/mixed_size-height.svg +6 -0
- novelwriter/assets/icons/typicons_light/mixed_size-width.svg +6 -0
- novelwriter/assets/icons/typicons_light/nw_toolbar.svg +5 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/text/credits_en.htm +1 -0
- novelwriter/common.py +37 -2
- novelwriter/config.py +15 -12
- novelwriter/constants.py +24 -9
- novelwriter/core/coretools.py +111 -125
- novelwriter/core/docbuild.py +3 -2
- novelwriter/core/index.py +9 -19
- novelwriter/core/item.py +39 -6
- novelwriter/core/itemmodel.py +518 -0
- novelwriter/core/project.py +67 -89
- novelwriter/core/status.py +7 -5
- novelwriter/core/tree.py +268 -287
- novelwriter/dialogs/docmerge.py +7 -17
- novelwriter/dialogs/preferences.py +3 -3
- novelwriter/dialogs/projectsettings.py +2 -2
- novelwriter/enum.py +7 -0
- novelwriter/extensions/configlayout.py +6 -4
- novelwriter/formats/todocx.py +34 -38
- novelwriter/formats/tohtml.py +14 -15
- novelwriter/formats/tokenizer.py +21 -17
- novelwriter/formats/toodt.py +53 -124
- novelwriter/formats/toqdoc.py +92 -44
- novelwriter/gui/doceditor.py +230 -219
- novelwriter/gui/docviewer.py +38 -9
- novelwriter/gui/docviewerpanel.py +14 -22
- novelwriter/gui/itemdetails.py +17 -24
- novelwriter/gui/mainmenu.py +13 -8
- novelwriter/gui/noveltree.py +12 -12
- novelwriter/gui/outline.py +10 -11
- novelwriter/gui/projtree.py +548 -1202
- novelwriter/gui/search.py +9 -10
- novelwriter/gui/theme.py +7 -3
- novelwriter/guimain.py +59 -43
- novelwriter/shared.py +52 -23
- novelwriter/text/patterns.py +17 -5
- novelwriter/tools/manusbuild.py +13 -11
- novelwriter/tools/manussettings.py +42 -52
- novelwriter/types.py +7 -1
- {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.6b1.dist-info → novelWriter-2.6b2.dist-info}/top_level.txt +0 -0
novelwriter/dialogs/docmerge.py
CHANGED
@@ -162,23 +162,13 @@ class GuiDocMerge(NDialog):
|
|
162
162
|
self._data = {}
|
163
163
|
self._data["sHandle"] = sHandle
|
164
164
|
self._data["origItems"] = itemList
|
165
|
-
|
166
165
|
self.listBox.clear()
|
167
166
|
for tHandle in itemList:
|
168
|
-
nwItem
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
newItem = QListWidgetItem()
|
177
|
-
newItem.setIcon(itemIcon)
|
178
|
-
newItem.setText(nwItem.itemName)
|
179
|
-
newItem.setData(self.D_HANDLE, tHandle)
|
180
|
-
newItem.setCheckState(Qt.CheckState.Checked)
|
181
|
-
|
182
|
-
self.listBox.addItem(newItem)
|
183
|
-
|
167
|
+
if (nwItem := SHARED.project.tree[tHandle]) and nwItem.isFileType():
|
168
|
+
item = QListWidgetItem()
|
169
|
+
item.setIcon(nwItem.getMainIcon())
|
170
|
+
item.setText(nwItem.itemName)
|
171
|
+
item.setData(self.D_HANDLE, tHandle)
|
172
|
+
item.setCheckState(Qt.CheckState.Checked)
|
173
|
+
self.listBox.addItem(item)
|
184
174
|
return
|
@@ -574,7 +574,7 @@ class GuiPreferences(NDialog):
|
|
574
574
|
self.dialogLine.setText(CONFIG.dialogLine)
|
575
575
|
self.mainForm.addRow(
|
576
576
|
self.tr("Dialogue line symbols"), self.dialogLine,
|
577
|
-
self.tr("Lines starting with these symbols are
|
577
|
+
self.tr("Lines starting with any of these symbols are dialogue.")
|
578
578
|
)
|
579
579
|
|
580
580
|
self.narratorBreak = QLineEdit(self)
|
@@ -583,8 +583,8 @@ class GuiPreferences(NDialog):
|
|
583
583
|
self.narratorBreak.setAlignment(QtAlignCenter)
|
584
584
|
self.narratorBreak.setText(CONFIG.narratorBreak)
|
585
585
|
self.mainForm.addRow(
|
586
|
-
self.tr("
|
587
|
-
self.tr("Symbol to indicate
|
586
|
+
self.tr("Narrator break symbol"), self.narratorBreak,
|
587
|
+
self.tr("Symbol to indicate a narrator break in dialogue")
|
588
588
|
)
|
589
589
|
|
590
590
|
self.narratorDialog = QLineEdit(self)
|
@@ -185,11 +185,11 @@ class GuiProjectSettings(NDialog):
|
|
185
185
|
|
186
186
|
if self.statusPage.changed:
|
187
187
|
logger.debug("Updating status labels")
|
188
|
-
project.
|
188
|
+
project.updateStatus("s", self.statusPage.getNewList())
|
189
189
|
|
190
190
|
if self.importPage.changed:
|
191
191
|
logger.debug("Updating importance labels")
|
192
|
-
project.
|
192
|
+
project.updateStatus("i", self.importPage.getNewList())
|
193
193
|
|
194
194
|
if self.replacePage.changed:
|
195
195
|
logger.debug("Updating auto-replace settings")
|
novelwriter/enum.py
CHANGED
@@ -27,7 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
27
27
|
"""
|
28
28
|
from __future__ import annotations
|
29
29
|
|
30
|
-
from PyQt5.QtGui import QColor, QFont, QPalette
|
30
|
+
from PyQt5.QtGui import QColor, QFont, QPalette, QPixmap
|
31
31
|
from PyQt5.QtWidgets import (
|
32
32
|
QAbstractButton, QFrame, QHBoxLayout, QLabel, QLayout, QScrollArea,
|
33
33
|
QVBoxLayout, QWidget
|
@@ -183,7 +183,7 @@ class NScrollableForm(QScrollArea):
|
|
183
183
|
def addRow(
|
184
184
|
self,
|
185
185
|
label: str | None,
|
186
|
-
widget: QWidget | list[QWidget |
|
186
|
+
widget: QWidget | list[QWidget | QPixmap | int],
|
187
187
|
helpText: str = "",
|
188
188
|
unit: str | None = None,
|
189
189
|
button: QWidget | None = None,
|
@@ -200,8 +200,10 @@ class NScrollableForm(QScrollArea):
|
|
200
200
|
for item in widget:
|
201
201
|
if isinstance(item, QWidget):
|
202
202
|
wBox.addWidget(item)
|
203
|
-
elif isinstance(item,
|
204
|
-
|
203
|
+
elif isinstance(item, QPixmap):
|
204
|
+
icon = QLabel(self)
|
205
|
+
icon.setPixmap(item)
|
206
|
+
wBox.addWidget(icon)
|
205
207
|
elif isinstance(item, int):
|
206
208
|
wBox.addSpacing(CONFIG.pxInt(item))
|
207
209
|
qWidget = QWidget(self)
|
novelwriter/formats/todocx.py
CHANGED
@@ -33,7 +33,7 @@ from pathlib import Path
|
|
33
33
|
from typing import NamedTuple
|
34
34
|
from zipfile import ZIP_DEFLATED, ZipFile
|
35
35
|
|
36
|
-
from PyQt5.QtCore import
|
36
|
+
from PyQt5.QtCore import QMargins, QSize
|
37
37
|
from PyQt5.QtGui import QColor
|
38
38
|
|
39
39
|
from novelwriter import __version__
|
@@ -95,6 +95,11 @@ def _wText(parent: ET.Element, text: str) -> ET.Element:
|
|
95
95
|
return xmlSubElem(parent, _wTag("t"), text, attrib=attrib)
|
96
96
|
|
97
97
|
|
98
|
+
def _mmToSz(value: float) -> int:
|
99
|
+
"""Convert millimetres to internal margin size units"""
|
100
|
+
return int(value*20.0*72.0/25.4)
|
101
|
+
|
102
|
+
|
98
103
|
# Cached
|
99
104
|
W_VAL = _wTag("val")
|
100
105
|
|
@@ -182,8 +187,8 @@ class ToDocX(Tokenizer):
|
|
182
187
|
# Internal
|
183
188
|
self._fontFamily = "Liberation Serif"
|
184
189
|
self._fontSize = 12.0
|
185
|
-
self._pageSize =
|
186
|
-
self._pageMargins =
|
190
|
+
self._pageSize = QSize(_mmToSz(210.0), _mmToSz(297.0))
|
191
|
+
self._pageMargins = QMargins(_mmToSz(20.0), _mmToSz(20.0), _mmToSz(20.0), _mmToSz(20.0))
|
187
192
|
|
188
193
|
# Data Variables
|
189
194
|
self._pars: list[DocXParagraph] = []
|
@@ -203,8 +208,8 @@ class ToDocX(Tokenizer):
|
|
203
208
|
self, width: float, height: float, top: float, bottom: float, left: float, right: float
|
204
209
|
) -> None:
|
205
210
|
"""Set the document page size and margins in millimetres."""
|
206
|
-
self._pageSize =
|
207
|
-
self._pageMargins =
|
211
|
+
self._pageSize = QSize(_mmToSz(width), _mmToSz(height))
|
212
|
+
self._pageMargins = QMargins(_mmToSz(left), _mmToSz(top), _mmToSz(right), _mmToSz(bottom))
|
208
213
|
return
|
209
214
|
|
210
215
|
def setHeaderFormat(self, format: str, offset: int) -> None:
|
@@ -521,12 +526,6 @@ class ToDocX(Tokenizer):
|
|
521
526
|
hScale = self._scaleHeads
|
522
527
|
hColor = _docXCol(self._theme.head) if self._colorHeads else None
|
523
528
|
fSz = self._fontSize
|
524
|
-
fnSz = 0.8 * self._fontSize
|
525
|
-
fSz0 = (nwStyles.H_SIZES[0] * fSz) if hScale else fSz
|
526
|
-
fSz1 = (nwStyles.H_SIZES[1] * fSz) if hScale else fSz
|
527
|
-
fSz2 = (nwStyles.H_SIZES[2] * fSz) if hScale else fSz
|
528
|
-
fSz3 = (nwStyles.H_SIZES[3] * fSz) if hScale else fSz
|
529
|
-
fSz4 = (nwStyles.H_SIZES[4] * fSz) if hScale else fSz
|
530
529
|
|
531
530
|
# Add Normal Style
|
532
531
|
styles.append(DocXParStyle(
|
@@ -545,12 +544,12 @@ class ToDocX(Tokenizer):
|
|
545
544
|
styles.append(DocXParStyle(
|
546
545
|
name="Title",
|
547
546
|
styleId=S_TITLE,
|
548
|
-
size=
|
547
|
+
size=(nwStyles.H_SIZES[0] * fSz) if hScale else fSz,
|
549
548
|
basedOn=S_NORM,
|
550
549
|
nextStyle=S_NORM,
|
551
550
|
before=fSz * self._marginTitle[0],
|
552
551
|
after=fSz * self._marginTitle[1],
|
553
|
-
line=
|
552
|
+
line=fSz * self._lineHeight,
|
554
553
|
level=0,
|
555
554
|
bold=self._boldHeads,
|
556
555
|
))
|
@@ -559,12 +558,12 @@ class ToDocX(Tokenizer):
|
|
559
558
|
styles.append(DocXParStyle(
|
560
559
|
name="Heading 1",
|
561
560
|
styleId=S_HEAD1,
|
562
|
-
size=
|
561
|
+
size=(nwStyles.H_SIZES[1] * fSz) if hScale else fSz,
|
563
562
|
basedOn=S_NORM,
|
564
563
|
nextStyle=S_NORM,
|
565
564
|
before=fSz * self._marginHead1[0],
|
566
565
|
after=fSz * self._marginHead1[1],
|
567
|
-
line=
|
566
|
+
line=fSz * self._lineHeight,
|
568
567
|
level=0,
|
569
568
|
color=hColor,
|
570
569
|
bold=self._boldHeads,
|
@@ -574,12 +573,12 @@ class ToDocX(Tokenizer):
|
|
574
573
|
styles.append(DocXParStyle(
|
575
574
|
name="Heading 2",
|
576
575
|
styleId=S_HEAD2,
|
577
|
-
size=
|
576
|
+
size=(nwStyles.H_SIZES[2] * fSz) if hScale else fSz,
|
578
577
|
basedOn=S_NORM,
|
579
578
|
nextStyle=S_NORM,
|
580
579
|
before=fSz * self._marginHead2[0],
|
581
580
|
after=fSz * self._marginHead2[1],
|
582
|
-
line=
|
581
|
+
line=fSz * self._lineHeight,
|
583
582
|
level=1,
|
584
583
|
color=hColor,
|
585
584
|
bold=self._boldHeads,
|
@@ -589,12 +588,12 @@ class ToDocX(Tokenizer):
|
|
589
588
|
styles.append(DocXParStyle(
|
590
589
|
name="Heading 3",
|
591
590
|
styleId=S_HEAD3,
|
592
|
-
size=
|
591
|
+
size=(nwStyles.H_SIZES[3] * fSz) if hScale else fSz,
|
593
592
|
basedOn=S_NORM,
|
594
593
|
nextStyle=S_NORM,
|
595
594
|
before=fSz * self._marginHead3[0],
|
596
595
|
after=fSz * self._marginHead3[1],
|
597
|
-
line=
|
596
|
+
line=fSz * self._lineHeight,
|
598
597
|
level=1,
|
599
598
|
color=hColor,
|
600
599
|
bold=self._boldHeads,
|
@@ -604,12 +603,12 @@ class ToDocX(Tokenizer):
|
|
604
603
|
styles.append(DocXParStyle(
|
605
604
|
name="Heading 4",
|
606
605
|
styleId=S_HEAD4,
|
607
|
-
size=
|
606
|
+
size=(nwStyles.H_SIZES[4] * fSz) if hScale else fSz,
|
608
607
|
basedOn=S_NORM,
|
609
608
|
nextStyle=S_NORM,
|
610
609
|
before=fSz * self._marginHead4[0],
|
611
610
|
after=fSz * self._marginHead4[1],
|
612
|
-
line=
|
611
|
+
line=fSz * self._lineHeight,
|
613
612
|
level=1,
|
614
613
|
color=hColor,
|
615
614
|
bold=self._boldHeads,
|
@@ -653,12 +652,12 @@ class ToDocX(Tokenizer):
|
|
653
652
|
styles.append(DocXParStyle(
|
654
653
|
name="Footnote Text",
|
655
654
|
styleId=S_FNOTE,
|
656
|
-
size=
|
655
|
+
size=nwStyles.T_SMALL * fSz,
|
657
656
|
basedOn=S_NORM,
|
658
657
|
before=0.0,
|
659
|
-
after=
|
660
|
-
left=
|
661
|
-
line=
|
658
|
+
after=fSz * self._marginFoot[1],
|
659
|
+
left=fSz * self._marginFoot[0],
|
660
|
+
line=fSz * self._lineHeight,
|
662
661
|
))
|
663
662
|
|
664
663
|
# Add to Cache
|
@@ -795,6 +794,7 @@ class ToDocX(Tokenizer):
|
|
795
794
|
_wTag("before"): str(int(20.0 * firstFloat(style.before))),
|
796
795
|
_wTag("after"): str(int(20.0 * firstFloat(style.after))),
|
797
796
|
_wTag("line"): str(int(20.0 * firstFloat(style.line, size))),
|
797
|
+
_wTag("lineRule"): "auto",
|
798
798
|
})
|
799
799
|
if style.left is not None:
|
800
800
|
xmlSubElem(pPr, _wTag("ind"), attrib={
|
@@ -860,12 +860,10 @@ class ToDocX(Tokenizer):
|
|
860
860
|
xR = xmlSubElem(xP, _wTag("r"))
|
861
861
|
xmlSubElem(xR, _wTag("fldChar"), attrib={wFldCT: "begin"})
|
862
862
|
xR = xmlSubElem(xP, _wTag("r"))
|
863
|
-
|
863
|
+
xmlSubElem(xR, _wTag("instrText"), "PAGE", attrib={_mkTag("xml", "space"): "preserve"})
|
864
864
|
xR = xmlSubElem(xP, _wTag("r"))
|
865
865
|
xmlSubElem(xR, _wTag("fldChar"), attrib={wFldCT: "separate"})
|
866
866
|
xR = xmlSubElem(xP, _wTag("r"))
|
867
|
-
_wText(xR, "0")
|
868
|
-
xR = xmlSubElem(xP, _wTag("r"))
|
869
867
|
xmlSubElem(xR, _wTag("fldChar"), attrib={wFldCT: "end"})
|
870
868
|
if post:
|
871
869
|
xR = xmlSubElem(xP, _wTag("r"))
|
@@ -933,9 +931,6 @@ class ToDocX(Tokenizer):
|
|
933
931
|
for par in pars:
|
934
932
|
par.toXml(xBody)
|
935
933
|
|
936
|
-
def szScale(value: float) -> str:
|
937
|
-
return str(int(value*2.0*72.0/2.54))
|
938
|
-
|
939
934
|
# Write Settings
|
940
935
|
xSect = xmlSubElem(xBody, _wTag("sectPr"))
|
941
936
|
if hFirst and hDefault:
|
@@ -952,16 +947,16 @@ class ToDocX(Tokenizer):
|
|
952
947
|
})
|
953
948
|
|
954
949
|
xmlSubElem(xSect, _wTag("pgSz"), attrib={
|
955
|
-
_wTag("w"):
|
956
|
-
_wTag("h"):
|
950
|
+
_wTag("w"): str(self._pageSize.width()),
|
951
|
+
_wTag("h"): str(self._pageSize.height()),
|
957
952
|
_wTag("orient"): "portrait",
|
958
953
|
})
|
959
954
|
xmlSubElem(xSect, _wTag("pgMar"), attrib={
|
960
|
-
_wTag("top"):
|
961
|
-
_wTag("right"):
|
962
|
-
_wTag("bottom"):
|
963
|
-
_wTag("left"):
|
964
|
-
_wTag("header"):
|
955
|
+
_wTag("top"): str(self._pageMargins.top()),
|
956
|
+
_wTag("right"): str(self._pageMargins.right()),
|
957
|
+
_wTag("bottom"): str(self._pageMargins.bottom()),
|
958
|
+
_wTag("left"): str(self._pageMargins.left()),
|
959
|
+
_wTag("header"): str(self._pageMargins.top() - int(35.0*self._fontSize)),
|
965
960
|
_wTag("footer"): "0",
|
966
961
|
_wTag("gutter"): "0",
|
967
962
|
})
|
@@ -1171,6 +1166,7 @@ class DocXParagraph:
|
|
1171
1166
|
_wTag("before"): str(int(20.0 * firstFloat(self._topMargin, style.before))),
|
1172
1167
|
_wTag("after"): str(int(20.0 * firstFloat(self._bottomMargin, style.after))),
|
1173
1168
|
_wTag("line"): str(int(20.0 * firstFloat(style.line, style.size))),
|
1169
|
+
_wTag("lineRule"): "auto",
|
1174
1170
|
})
|
1175
1171
|
if indent:
|
1176
1172
|
xmlSubElem(pPr, _wTag("ind"), attrib=indent)
|
novelwriter/formats/tohtml.py
CHANGED
@@ -339,26 +339,25 @@ class ToHtml(Tokenizer):
|
|
339
339
|
if not self._cssStyles:
|
340
340
|
return []
|
341
341
|
|
342
|
-
mScale = self._lineHeight/1.15
|
343
342
|
tColor = self._theme.text.name(QtHexRgb)
|
344
343
|
hColor = self._theme.head.name(QtHexRgb) if self._colorHeads else tColor
|
345
344
|
lColor = self._theme.head.name(QtHexRgb)
|
346
345
|
mColor = self._theme.highlight.name(QtHexRgb)
|
347
346
|
|
348
|
-
mtH0 =
|
349
|
-
mbH0 =
|
350
|
-
mtH1 =
|
351
|
-
mbH1 =
|
352
|
-
mtH2 =
|
353
|
-
mbH2 =
|
354
|
-
mtH3 =
|
355
|
-
mbH3 =
|
356
|
-
mtH4 =
|
357
|
-
mbH4 =
|
358
|
-
mtTT =
|
359
|
-
mbTT =
|
360
|
-
mtSP =
|
361
|
-
mbSP =
|
347
|
+
mtH0 = self._marginTitle[0]
|
348
|
+
mbH0 = self._marginTitle[1]
|
349
|
+
mtH1 = self._marginHead1[0]
|
350
|
+
mbH1 = self._marginHead1[1]
|
351
|
+
mtH2 = self._marginHead2[0]
|
352
|
+
mbH2 = self._marginHead2[1]
|
353
|
+
mtH3 = self._marginHead3[0]
|
354
|
+
mbH3 = self._marginHead3[1]
|
355
|
+
mtH4 = self._marginHead4[0]
|
356
|
+
mbH4 = self._marginHead4[1]
|
357
|
+
mtTT = self._marginText[0]
|
358
|
+
mbTT = self._marginText[1]
|
359
|
+
mtSP = self._marginSep[0]
|
360
|
+
mbSP = self._marginSep[1]
|
362
361
|
|
363
362
|
font = self._textFont
|
364
363
|
fFam = font.family()
|
novelwriter/formats/tokenizer.py
CHANGED
@@ -35,7 +35,7 @@ from PyQt5.QtCore import QLocale
|
|
35
35
|
from PyQt5.QtGui import QColor, QFont
|
36
36
|
|
37
37
|
from novelwriter import CONFIG
|
38
|
-
from novelwriter.common import checkInt, numberToRoman
|
38
|
+
from novelwriter.common import checkInt, fontMatcher, numberToRoman
|
39
39
|
from novelwriter.constants import (
|
40
40
|
nwHeadFmt, nwKeyWords, nwLabels, nwShortcode, nwStats, nwStyles, nwUnicode,
|
41
41
|
trConst
|
@@ -302,9 +302,9 @@ class Tokenizer(ABC):
|
|
302
302
|
self._sceneStyle |= BlockFmt.PBB if pageBreak else BlockFmt.NONE
|
303
303
|
return
|
304
304
|
|
305
|
-
def
|
305
|
+
def setTextFont(self, font: QFont) -> None:
|
306
306
|
"""Set the build font."""
|
307
|
-
self._textFont = font
|
307
|
+
self._textFont = fontMatcher(font)
|
308
308
|
return
|
309
309
|
|
310
310
|
def setLineHeight(self, height: float) -> None:
|
@@ -490,22 +490,14 @@ class Tokenizer(ABC):
|
|
490
490
|
return
|
491
491
|
|
492
492
|
def doPreProcessing(self) -> None:
|
493
|
-
"""Run
|
493
|
+
"""Run pre-processing jobs before the text is tokenized."""
|
494
494
|
# Process the user's auto-replace dictionary
|
495
|
-
autoReplace
|
496
|
-
if len(autoReplace) > 0:
|
495
|
+
if autoReplace := self._project.data.autoReplace:
|
497
496
|
repDict = {}
|
498
497
|
for aKey, aVal in autoReplace.items():
|
499
498
|
repDict[f"<{aKey}>"] = aVal
|
500
499
|
xRep = re.compile("|".join([re.escape(k) for k in repDict.keys()]), flags=re.DOTALL)
|
501
500
|
self._text = xRep.sub(lambda x: repDict[x.group(0)], self._text)
|
502
|
-
|
503
|
-
# Process the translation map for placeholder characters
|
504
|
-
self._text = self._text.translate(str.maketrans({
|
505
|
-
nwUnicode.U_MAPOS: nwUnicode.U_RSQUO,
|
506
|
-
nwUnicode.U_HBAR: nwUnicode.U_EMDASH,
|
507
|
-
}))
|
508
|
-
|
509
501
|
return
|
510
502
|
|
511
503
|
def tokenizeText(self) -> None:
|
@@ -538,13 +530,25 @@ class Tokenizer(ABC):
|
|
538
530
|
firstIndent = self._firstIndent
|
539
531
|
|
540
532
|
# Replace all instances of [br] with a placeholder character
|
541
|
-
text = REGEX_PATTERNS.lineBreak.sub(
|
533
|
+
text = REGEX_PATTERNS.lineBreak.sub(nwUnicode.U_NAC2, self._text)
|
534
|
+
|
535
|
+
# Translation Maps
|
536
|
+
transMapA = str.maketrans({
|
537
|
+
nwUnicode.U_NAC2: "", # Used when [br] is ignored
|
538
|
+
nwUnicode.U_MAPOS: nwUnicode.U_RSQUO,
|
539
|
+
nwUnicode.U_HBAR: nwUnicode.U_EMDASH,
|
540
|
+
})
|
541
|
+
transMapB = str.maketrans({
|
542
|
+
nwUnicode.U_NAC2: "\n", # Used when [br] is not ignored
|
543
|
+
nwUnicode.U_MAPOS: nwUnicode.U_RSQUO,
|
544
|
+
nwUnicode.U_HBAR: nwUnicode.U_EMDASH,
|
545
|
+
})
|
542
546
|
|
543
547
|
nHead = 0
|
544
548
|
tHandle = self._handle or ""
|
545
549
|
tBlocks: list[T_Block] = [B_EMPTY]
|
546
550
|
for bLine in text.splitlines():
|
547
|
-
aLine = bLine.
|
551
|
+
aLine = bLine.translate(transMapA)
|
548
552
|
sLine = aLine.strip().lower()
|
549
553
|
|
550
554
|
# Check for blank lines
|
@@ -884,7 +888,7 @@ class Tokenizer(ABC):
|
|
884
888
|
if doJustify and not cStyle & BlockFmt.ALIGNED:
|
885
889
|
cStyle |= BlockFmt.JUSTIFY
|
886
890
|
|
887
|
-
pTxt = pLines[0][2].
|
891
|
+
pTxt = pLines[0][2].translate(transMapB)
|
888
892
|
sBlocks.append((
|
889
893
|
BlockTyp.TEXT, pLines[0][1], pTxt, pLines[0][3], cStyle
|
890
894
|
))
|
@@ -901,7 +905,7 @@ class Tokenizer(ABC):
|
|
901
905
|
tFmt.extend((p+tLen, fmt, key) for p, fmt, key in aBlock[3])
|
902
906
|
cStyle |= aBlock[4]
|
903
907
|
|
904
|
-
pTxt = tTxt[:-1].
|
908
|
+
pTxt = tTxt[:-1].translate(transMapB)
|
905
909
|
sBlocks.append((
|
906
910
|
BlockTyp.TEXT, pLines[0][1], pTxt, tFmt, cStyle
|
907
911
|
))
|