novelWriter 2.6b1__py3-none-any.whl → 2.6rc1__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.6rc1.dist-info}/METADATA +4 -4
- {novelWriter-2.6b1.dist-info → novelWriter-2.6rc1.dist-info}/RECORD +114 -98
- {novelWriter-2.6b1.dist-info → novelWriter-2.6rc1.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +50 -11
- 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_ru_RU.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.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 +38 -3
- novelwriter/config.py +19 -13
- novelwriter/constants.py +60 -45
- novelwriter/core/buildsettings.py +1 -1
- novelwriter/core/coretools.py +112 -126
- novelwriter/core/docbuild.py +4 -3
- novelwriter/core/document.py +1 -1
- novelwriter/core/index.py +10 -20
- novelwriter/core/item.py +40 -7
- novelwriter/core/itemmodel.py +518 -0
- novelwriter/core/options.py +1 -1
- novelwriter/core/project.py +68 -90
- novelwriter/core/projectdata.py +8 -2
- novelwriter/core/projectxml.py +1 -1
- novelwriter/core/sessions.py +1 -1
- novelwriter/core/spellcheck.py +1 -1
- novelwriter/core/status.py +24 -8
- novelwriter/core/storage.py +1 -1
- novelwriter/core/tree.py +269 -288
- novelwriter/dialogs/about.py +1 -1
- novelwriter/dialogs/docmerge.py +8 -18
- novelwriter/dialogs/docsplit.py +1 -1
- novelwriter/dialogs/editlabel.py +1 -1
- novelwriter/dialogs/preferences.py +4 -4
- novelwriter/dialogs/projectsettings.py +148 -98
- novelwriter/dialogs/quotes.py +1 -1
- novelwriter/dialogs/wordlist.py +11 -10
- novelwriter/enum.py +8 -1
- novelwriter/error.py +2 -2
- novelwriter/extensions/configlayout.py +7 -5
- novelwriter/extensions/eventfilters.py +1 -1
- novelwriter/extensions/modified.py +17 -5
- novelwriter/extensions/novelselector.py +1 -1
- novelwriter/extensions/pagedsidebar.py +4 -4
- novelwriter/extensions/progressbars.py +4 -4
- novelwriter/extensions/statusled.py +3 -3
- novelwriter/extensions/switch.py +3 -3
- novelwriter/extensions/switchbox.py +1 -1
- novelwriter/extensions/versioninfo.py +1 -1
- novelwriter/formats/shared.py +1 -1
- novelwriter/formats/todocx.py +35 -39
- novelwriter/formats/tohtml.py +15 -16
- novelwriter/formats/tokenizer.py +26 -22
- novelwriter/formats/tomarkdown.py +1 -1
- novelwriter/formats/toodt.py +54 -125
- novelwriter/formats/toqdoc.py +93 -45
- novelwriter/formats/toraw.py +1 -1
- novelwriter/gui/doceditor.py +233 -220
- novelwriter/gui/dochighlight.py +1 -1
- novelwriter/gui/docviewer.py +39 -10
- novelwriter/gui/docviewerpanel.py +15 -23
- novelwriter/gui/editordocument.py +1 -1
- novelwriter/gui/itemdetails.py +20 -27
- novelwriter/gui/mainmenu.py +14 -9
- novelwriter/gui/noveltree.py +13 -13
- novelwriter/gui/outline.py +18 -20
- novelwriter/gui/projtree.py +545 -1201
- novelwriter/gui/search.py +11 -19
- novelwriter/gui/sidebar.py +1 -1
- novelwriter/gui/statusbar.py +20 -3
- novelwriter/gui/theme.py +8 -4
- novelwriter/guimain.py +60 -48
- novelwriter/shared.py +53 -24
- novelwriter/text/counting.py +1 -1
- novelwriter/text/patterns.py +18 -6
- novelwriter/tools/dictionaries.py +1 -1
- novelwriter/tools/lipsum.py +1 -1
- novelwriter/tools/manusbuild.py +14 -12
- novelwriter/tools/manuscript.py +7 -7
- novelwriter/tools/manussettings.py +43 -53
- novelwriter/tools/noveldetails.py +1 -1
- novelwriter/tools/welcome.py +1 -1
- novelwriter/tools/writingstats.py +1 -1
- novelwriter/types.py +9 -3
- {novelWriter-2.6b1.dist-info → novelWriter-2.6rc1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.6b1.dist-info → novelWriter-2.6rc1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.6b1.dist-info → novelWriter-2.6rc1.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,7 @@ Created: 2024-01-26 [2.3b1] NFixedPage
|
|
10
10
|
Created: 2024-03-12 [2.4b1] NWrappedWidgetBox
|
11
11
|
|
12
12
|
This file is a part of novelWriter
|
13
|
-
Copyright
|
13
|
+
Copyright (C) 2023 Veronica Berglyd Olsen and novelWriter contributors
|
14
14
|
|
15
15
|
This program is free software: you can redistribute it and/or modify
|
16
16
|
it under the terms of the GNU General Public License as published by
|
@@ -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)
|
@@ -7,7 +7,7 @@ Created: 2023-08-31 [2.1rc1] WheelEventFilter
|
|
7
7
|
Created: 2023-11-28 [2.2] StatusTipFilter
|
8
8
|
|
9
9
|
This file is a part of novelWriter
|
10
|
-
Copyright
|
10
|
+
Copyright (C) 2023 Veronica Berglyd Olsen and novelWriter contributors
|
11
11
|
|
12
12
|
This program is free software: you can redistribute it and/or modify
|
13
13
|
it under the terms of the GNU General Public License as published by
|
@@ -10,7 +10,7 @@ Created: 2024-05-01 [2.5b1] NToolDialog
|
|
10
10
|
Created: 2024-05-01 [2.5b1] NNonBlockingDialog
|
11
11
|
|
12
12
|
This file is a part of novelWriter
|
13
|
-
Copyright
|
13
|
+
Copyright (C) 2024 Veronica Berglyd Olsen and novelWriter contributors
|
14
14
|
|
15
15
|
This program is free software: you can redistribute it and/or modify
|
16
16
|
it under the terms of the GNU General Public License as published by
|
@@ -30,14 +30,15 @@ from __future__ import annotations
|
|
30
30
|
from enum import Enum
|
31
31
|
from typing import TYPE_CHECKING
|
32
32
|
|
33
|
-
from PyQt5.QtCore import QSize, Qt, pyqtSlot
|
34
|
-
from PyQt5.QtGui import QWheelEvent
|
33
|
+
from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot
|
34
|
+
from PyQt5.QtGui import QMouseEvent, QWheelEvent
|
35
35
|
from PyQt5.QtWidgets import (
|
36
|
-
QApplication, QComboBox, QDialog, QDoubleSpinBox,
|
37
|
-
QWidget
|
36
|
+
QApplication, QComboBox, QDialog, QDoubleSpinBox, QLabel, QSpinBox,
|
37
|
+
QToolButton, QWidget
|
38
38
|
)
|
39
39
|
|
40
40
|
from novelwriter import CONFIG, SHARED
|
41
|
+
from novelwriter.types import QtMouseLeft
|
41
42
|
|
42
43
|
if TYPE_CHECKING: # pragma: no cover
|
43
44
|
from novelwriter.guimain import GuiMain
|
@@ -196,3 +197,14 @@ class NIconToggleButton(QToolButton):
|
|
196
197
|
iconSize = self.iconSize()
|
197
198
|
self.setIcon(SHARED.theme.getToggleIcon(iconKey, (iconSize.width(), iconSize.height())))
|
198
199
|
return
|
200
|
+
|
201
|
+
|
202
|
+
class NClickableLabel(QLabel):
|
203
|
+
|
204
|
+
mouseClicked = pyqtSignal()
|
205
|
+
|
206
|
+
def mousePressEvent(self, event: QMouseEvent) -> None:
|
207
|
+
"""Capture a left mouse click and emit its signal."""
|
208
|
+
if event.button() == QtMouseLeft:
|
209
|
+
self.mouseClicked.emit()
|
210
|
+
return super().mousePressEvent(event)
|
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2022-11-17 [2.0] NovelSelector
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2022 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -8,7 +8,7 @@ Created: 2023-02-21 [2.1b1] NPagedToolButton
|
|
8
8
|
Created: 2023-02-21 [2.1b1] NPagedToolLabel
|
9
9
|
|
10
10
|
This file is a part of novelWriter
|
11
|
-
Copyright
|
11
|
+
Copyright (C) 2023 Veronica Berglyd Olsen and novelWriter contributors
|
12
12
|
|
13
13
|
This program is free software: you can redistribute it and/or modify
|
14
14
|
it under the terms of the GNU General Public License as published by
|
@@ -33,7 +33,7 @@ from PyQt5.QtWidgets import (
|
|
33
33
|
)
|
34
34
|
|
35
35
|
from novelwriter.types import (
|
36
|
-
QtAlignLeft, QtMouseOver, QtNoBrush, QtNoPen,
|
36
|
+
QtAlignLeft, QtMouseOver, QtNoBrush, QtNoPen, QtPaintAntiAlias,
|
37
37
|
QtSizeExpanding, QtSizeFixed
|
38
38
|
)
|
39
39
|
|
@@ -146,7 +146,7 @@ class _PagedToolButton(QToolButton):
|
|
146
146
|
opt.initFrom(self)
|
147
147
|
|
148
148
|
paint = QPainter(self)
|
149
|
-
paint.setRenderHint(
|
149
|
+
paint.setRenderHint(QtPaintAntiAlias, True)
|
150
150
|
paint.setPen(QtNoPen)
|
151
151
|
paint.setBrush(QtNoBrush)
|
152
152
|
|
@@ -213,7 +213,7 @@ class _NPagedToolLabel(QLabel):
|
|
213
213
|
label that matches the button style.
|
214
214
|
"""
|
215
215
|
paint = QPainter(self)
|
216
|
-
paint.setRenderHint(
|
216
|
+
paint.setRenderHint(QtPaintAntiAlias, True)
|
217
217
|
paint.setPen(QtNoPen)
|
218
218
|
|
219
219
|
width = self.width()
|
@@ -7,7 +7,7 @@ Created: 2023-06-07 [2.1b1] NProgressCircle
|
|
7
7
|
Created: 2023-06-09 [2.1b1] NProgressSimple
|
8
8
|
|
9
9
|
This file is a part of novelWriter
|
10
|
-
Copyright
|
10
|
+
Copyright (C) 2023 Veronica Berglyd Olsen and novelWriter contributors
|
11
11
|
|
12
12
|
This program is free software: you can redistribute it and/or modify
|
13
13
|
it under the terms of the GNU General Public License as published by
|
@@ -31,7 +31,7 @@ from PyQt5.QtGui import QBrush, QColor, QPainter, QPaintEvent, QPen
|
|
31
31
|
from PyQt5.QtWidgets import QProgressBar, QWidget
|
32
32
|
|
33
33
|
from novelwriter.types import (
|
34
|
-
QtAlignCenter,
|
34
|
+
QtAlignCenter, QtPaintAntiAlias, QtRoundCap, QtSizeFixed, QtSolidLine,
|
35
35
|
QtTransparent
|
36
36
|
)
|
37
37
|
|
@@ -91,7 +91,7 @@ class NProgressCircle(QProgressBar):
|
|
91
91
|
progress = 100.0*self.value()/self.maximum()
|
92
92
|
angle = ceil(16*3.6*progress)
|
93
93
|
painter = QPainter(self)
|
94
|
-
painter.setRenderHint(
|
94
|
+
painter.setRenderHint(QtPaintAntiAlias, True)
|
95
95
|
painter.setPen(self._dPen)
|
96
96
|
painter.setBrush(self._dBrush)
|
97
97
|
painter.drawEllipse(self._dRect)
|
@@ -119,7 +119,7 @@ class NProgressSimple(QProgressBar):
|
|
119
119
|
if (value := self.value()) > 0:
|
120
120
|
progress = ceil(self.width()*float(value)/self.maximum())
|
121
121
|
painter = QPainter(self)
|
122
|
-
painter.setRenderHint(
|
122
|
+
painter.setRenderHint(QtPaintAntiAlias, True)
|
123
123
|
painter.setPen(self.palette().highlight().color())
|
124
124
|
painter.setBrush(self.palette().highlight())
|
125
125
|
painter.drawRect(0, 0, progress, self.height())
|
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2020-05-17 [0.5.1]
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2020 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -30,7 +30,7 @@ from PyQt5.QtWidgets import QAbstractButton, QWidget
|
|
30
30
|
|
31
31
|
from novelwriter import CONFIG
|
32
32
|
from novelwriter.enum import nwTrinary
|
33
|
-
from novelwriter.types import QtBlack,
|
33
|
+
from novelwriter.types import QtBlack, QtPaintAntiAlias
|
34
34
|
|
35
35
|
logger = logging.getLogger(__name__)
|
36
36
|
|
@@ -81,7 +81,7 @@ class StatusLED(QAbstractButton):
|
|
81
81
|
def paintEvent(self, event: QPaintEvent) -> None:
|
82
82
|
"""Draw the LED."""
|
83
83
|
painter = QPainter(self)
|
84
|
-
painter.setRenderHint(
|
84
|
+
painter.setRenderHint(QtPaintAntiAlias, True)
|
85
85
|
painter.setPen(self.palette().windowText().color())
|
86
86
|
painter.setBrush(self._color)
|
87
87
|
painter.setOpacity(1.0)
|
novelwriter/extensions/switch.py
CHANGED
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2020-05-03 [0.4.5]
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2020 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -28,7 +28,7 @@ from PyQt5.QtGui import QMouseEvent, QPainter, QPaintEvent, QResizeEvent
|
|
28
28
|
from PyQt5.QtWidgets import QAbstractButton, QWidget
|
29
29
|
|
30
30
|
from novelwriter import CONFIG, SHARED
|
31
|
-
from novelwriter.types import QtMouseLeft, QtNoPen,
|
31
|
+
from novelwriter.types import QtMouseLeft, QtNoPen, QtPaintAntiAlias, QtSizeFixed
|
32
32
|
|
33
33
|
|
34
34
|
class NSwitch(QAbstractButton):
|
@@ -90,7 +90,7 @@ class NSwitch(QAbstractButton):
|
|
90
90
|
def paintEvent(self, event: QPaintEvent) -> None:
|
91
91
|
"""Drawing the switch itself."""
|
92
92
|
painter = QPainter(self)
|
93
|
-
painter.setRenderHint(
|
93
|
+
painter.setRenderHint(QtPaintAntiAlias, True)
|
94
94
|
painter.setPen(QtNoPen)
|
95
95
|
|
96
96
|
palette = self.palette()
|
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2023-04-16 [2.1b1]
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2023 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2024-02-14 [2.3b1] VersionInfoWidget
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2024 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
novelwriter/formats/shared.py
CHANGED
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2024-10-21 [2.6b1]
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2024 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
novelwriter/formats/todocx.py
CHANGED
@@ -7,7 +7,7 @@ Created: 2024-10-18 [2.6b1] ToDocX
|
|
7
7
|
Created: 2024-10-18 [2.6b1] DocXParagraph
|
8
8
|
|
9
9
|
This file is a part of novelWriter
|
10
|
-
Copyright
|
10
|
+
Copyright (C) 2024 Veronica Berglyd Olsen and novelWriter contributors
|
11
11
|
|
12
12
|
This program is free software: you can redistribute it and/or modify
|
13
13
|
it under the terms of the GNU General Public License as published by
|
@@ -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
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2019-05-07 [0.0.1] ToHtml
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2019 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -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
@@ -7,7 +7,7 @@ Created: 2019-05-05 [0.0.1] Tokenizer
|
|
7
7
|
Created: 2023-05-23 [2.1b1] HeadingFormatter
|
8
8
|
|
9
9
|
This file is a part of novelWriter
|
10
|
-
Copyright
|
10
|
+
Copyright (C) 2019 Veronica Berglyd Olsen and novelWriter contributors
|
11
11
|
|
12
12
|
This program is free software: you can redistribute it and/or modify
|
13
13
|
it under the terms of the GNU General Public License as published by
|
@@ -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
|
))
|
@@ -942,11 +946,11 @@ class Tokenizer(ABC):
|
|
942
946
|
titleCount = self._counts.get(nwStats.TITLES, 0)
|
943
947
|
paragraphCount = self._counts.get(nwStats.PARAGRAPHS, 0)
|
944
948
|
|
945
|
-
allWords = self._counts.get(nwStats.
|
949
|
+
allWords = self._counts.get(nwStats.WORDS, 0)
|
946
950
|
textWords = self._counts.get(nwStats.WORDS_TEXT, 0)
|
947
951
|
titleWords = self._counts.get(nwStats.WORDS_TITLE, 0)
|
948
952
|
|
949
|
-
allChars = self._counts.get(nwStats.
|
953
|
+
allChars = self._counts.get(nwStats.CHARS, 0)
|
950
954
|
textChars = self._counts.get(nwStats.CHARS_TEXT, 0)
|
951
955
|
titleChars = self._counts.get(nwStats.CHARS_TITLE, 0)
|
952
956
|
|
@@ -1000,11 +1004,11 @@ class Tokenizer(ABC):
|
|
1000
1004
|
self._counts[nwStats.TITLES] = titleCount
|
1001
1005
|
self._counts[nwStats.PARAGRAPHS] = paragraphCount
|
1002
1006
|
|
1003
|
-
self._counts[nwStats.
|
1007
|
+
self._counts[nwStats.WORDS] = allWords
|
1004
1008
|
self._counts[nwStats.WORDS_TEXT] = textWords
|
1005
1009
|
self._counts[nwStats.WORDS_TITLE] = titleWords
|
1006
1010
|
|
1007
|
-
self._counts[nwStats.
|
1011
|
+
self._counts[nwStats.CHARS] = allChars
|
1008
1012
|
self._counts[nwStats.CHARS_TEXT] = textChars
|
1009
1013
|
self._counts[nwStats.CHARS_TITLE] = titleChars
|
1010
1014
|
|
@@ -6,7 +6,7 @@ File History:
|
|
6
6
|
Created: 2021-02-06 [1.2b1] ToMarkdown
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright
|
9
|
+
Copyright (C) 2021 Veronica Berglyd Olsen and novelWriter contributors
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|