novelWriter 2.4b1__py3-none-any.whl → 2.4.1__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.4b1.dist-info → novelWriter-2.4.1.dist-info}/METADATA +5 -6
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/RECORD +79 -83
- novelwriter/__init__.py +15 -8
- 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_pt_BR.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/icons/none.svg +4 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +2 -2
- novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +2 -2
- novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +4 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/common.py +11 -3
- novelwriter/config.py +12 -4
- novelwriter/core/buildsettings.py +7 -7
- novelwriter/core/coretools.py +21 -22
- novelwriter/core/docbuild.py +2 -2
- novelwriter/core/projectxml.py +1 -1
- novelwriter/core/spellcheck.py +3 -3
- novelwriter/core/status.py +3 -2
- novelwriter/core/tokenizer.py +3 -3
- novelwriter/core/toodt.py +333 -356
- novelwriter/dialogs/about.py +9 -11
- novelwriter/dialogs/docmerge.py +17 -14
- novelwriter/dialogs/docsplit.py +14 -12
- novelwriter/dialogs/editlabel.py +5 -4
- novelwriter/dialogs/preferences.py +29 -34
- novelwriter/dialogs/projectsettings.py +31 -28
- novelwriter/dialogs/quotes.py +10 -9
- novelwriter/dialogs/wordlist.py +17 -14
- novelwriter/error.py +14 -12
- novelwriter/extensions/circularprogress.py +12 -8
- novelwriter/extensions/configlayout.py +1 -3
- novelwriter/extensions/modified.py +33 -2
- novelwriter/extensions/pagedsidebar.py +16 -14
- novelwriter/extensions/simpleprogress.py +3 -1
- novelwriter/extensions/statusled.py +3 -1
- novelwriter/extensions/switch.py +10 -9
- novelwriter/extensions/switchbox.py +14 -13
- novelwriter/gui/doceditor.py +205 -246
- novelwriter/gui/dochighlight.py +26 -9
- novelwriter/gui/docviewer.py +55 -59
- novelwriter/gui/docviewerpanel.py +16 -13
- novelwriter/gui/editordocument.py +4 -4
- novelwriter/gui/itemdetails.py +45 -48
- novelwriter/gui/mainmenu.py +2 -2
- novelwriter/gui/noveltree.py +23 -21
- novelwriter/gui/outline.py +93 -94
- novelwriter/gui/projtree.py +32 -30
- novelwriter/gui/search.py +75 -29
- novelwriter/gui/sidebar.py +24 -28
- novelwriter/gui/statusbar.py +14 -14
- novelwriter/gui/theme.py +61 -39
- novelwriter/guimain.py +37 -33
- novelwriter/shared.py +21 -9
- novelwriter/text/counting.py +1 -0
- novelwriter/tools/dictionaries.py +15 -14
- novelwriter/tools/lipsum.py +20 -17
- novelwriter/tools/manusbuild.py +44 -35
- novelwriter/tools/manuscript.py +112 -112
- novelwriter/tools/manussettings.py +91 -98
- novelwriter/tools/noveldetails.py +20 -18
- novelwriter/tools/welcome.py +51 -48
- novelwriter/tools/writingstats.py +61 -55
- novelwriter/types.py +90 -0
- novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-down.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-right.svg +0 -4
- novelwriter/core/__init__.py +0 -3
- novelwriter/dialogs/__init__.py +0 -3
- novelwriter/extensions/__init__.py +0 -3
- novelwriter/gui/__init__.py +0 -3
- novelwriter/text/__init__.py +0 -3
- novelwriter/tools/__init__.py +0 -3
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/WHEEL +0 -0
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/top_level.txt +0 -0
novelwriter/core/coretools.py
CHANGED
@@ -337,32 +337,32 @@ class DocSearch:
|
|
337
337
|
"""Iteratively search through documents in a project."""
|
338
338
|
self._regEx.setPattern(self._buildPattern(search))
|
339
339
|
logger.debug("Searching with pattern '%s'", self._regEx.pattern())
|
340
|
-
|
341
|
-
num = len(search)
|
342
340
|
storage = project.storage
|
343
341
|
for item in project.tree:
|
344
342
|
if item.isFileType():
|
345
|
-
|
346
|
-
rxItt = self._regEx.globalMatch(text)
|
347
|
-
count = 0
|
348
|
-
capped = False
|
349
|
-
results = []
|
350
|
-
while rxItt.hasNext():
|
351
|
-
rxMatch = rxItt.next()
|
352
|
-
pos = rxMatch.capturedStart()
|
353
|
-
num = rxMatch.capturedLength()
|
354
|
-
context = text[pos:pos+100].partition("\n")[0]
|
355
|
-
if context:
|
356
|
-
results.append((pos, num, context))
|
357
|
-
count += 1
|
358
|
-
if count >= nwConst.MAX_SEARCH_RESULT:
|
359
|
-
capped = True
|
360
|
-
break
|
361
|
-
|
343
|
+
results, capped = self.searchText(storage.getDocumentText(item.itemHandle))
|
362
344
|
yield item, results, capped
|
363
|
-
|
364
345
|
return
|
365
346
|
|
347
|
+
def searchText(self, text: str) -> tuple[list[tuple[int, int, str]], bool]:
|
348
|
+
"""Search a piece of text for RegEx matches."""
|
349
|
+
rxItt = self._regEx.globalMatch(text)
|
350
|
+
count = 0
|
351
|
+
capped = False
|
352
|
+
results = []
|
353
|
+
while rxItt.hasNext():
|
354
|
+
rxMatch = rxItt.next()
|
355
|
+
pos = rxMatch.capturedStart()
|
356
|
+
num = rxMatch.capturedLength()
|
357
|
+
context = text[pos:pos+100].partition("\n")[0]
|
358
|
+
if context:
|
359
|
+
results.append((pos, num, context))
|
360
|
+
count += 1
|
361
|
+
if count >= nwConst.MAX_SEARCH_RESULT:
|
362
|
+
capped = True
|
363
|
+
break
|
364
|
+
return results, capped
|
365
|
+
|
366
366
|
##
|
367
367
|
# Internal Functions
|
368
368
|
##
|
@@ -382,8 +382,7 @@ class DocSearch:
|
|
382
382
|
escaped += f"\\{c}"
|
383
383
|
search = escaped
|
384
384
|
if self._words:
|
385
|
-
search =
|
386
|
-
search = search if search.endswith("\\b") else f"{search}\\b"
|
385
|
+
search = f"(?:^|\\b){search}(?:$|\\b)"
|
387
386
|
return search
|
388
387
|
|
389
388
|
# END Class DocSearch
|
novelwriter/core/docbuild.py
CHANGED
@@ -306,8 +306,8 @@ class NWBuildDocument:
|
|
306
306
|
self._build.getBool("headings.hideScene")
|
307
307
|
)
|
308
308
|
bldObj.setHardSceneFormat(
|
309
|
-
self._build.getStr("headings.
|
310
|
-
self._build.getBool("headings.
|
309
|
+
self._build.getStr("headings.fmtAltScene"),
|
310
|
+
self._build.getBool("headings.hideAltScene")
|
311
311
|
)
|
312
312
|
bldObj.setSectionFormat(
|
313
313
|
self._build.getStr("headings.fmtSection"),
|
novelwriter/core/projectxml.py
CHANGED
@@ -449,7 +449,7 @@ class ProjectXMLReader:
|
|
449
449
|
result[xEntry.attrib["key"]] = checkString(xEntry.text, "")
|
450
450
|
return result
|
451
451
|
|
452
|
-
def _parseDictTagText(self, xItem) -> dict:
|
452
|
+
def _parseDictTagText(self, xItem: ET.Element) -> dict:
|
453
453
|
"""Parse a dictionary stored with key as the tag and the value
|
454
454
|
as the text property.
|
455
455
|
"""
|
novelwriter/core/spellcheck.py
CHANGED
@@ -74,7 +74,7 @@ class NWSpellEnchant:
|
|
74
74
|
# Setters
|
75
75
|
##
|
76
76
|
|
77
|
-
def setLanguage(self, language: str | None):
|
77
|
+
def setLanguage(self, language: str | None) -> None:
|
78
78
|
"""Load a dictionary for the language specified in the config.
|
79
79
|
If that fails, we load a mock dictionary so that lookups don't
|
80
80
|
crash. Note that enchant will allow loading an empty string as
|
@@ -182,10 +182,10 @@ class FakeEnchant:
|
|
182
182
|
def check(self, word: str) -> bool:
|
183
183
|
return True
|
184
184
|
|
185
|
-
def suggest(self, word) -> list[str]:
|
185
|
+
def suggest(self, word: str) -> list[str]:
|
186
186
|
return []
|
187
187
|
|
188
|
-
def add_to_session(self, word: str):
|
188
|
+
def add_to_session(self, word: str) -> None:
|
189
189
|
return
|
190
190
|
|
191
191
|
# END Class FakeEnchant
|
novelwriter/core/status.py
CHANGED
@@ -35,6 +35,7 @@ from PyQt5.QtCore import QRectF
|
|
35
35
|
|
36
36
|
from novelwriter import CONFIG
|
37
37
|
from novelwriter.common import minmax, simplified
|
38
|
+
from novelwriter.types import QtPaintAnitAlias, QtTransparent
|
38
39
|
|
39
40
|
if TYPE_CHECKING: # pragma: no cover
|
40
41
|
from typing import TypeGuard # Requires Python 3.10
|
@@ -248,10 +249,10 @@ class NWStatus:
|
|
248
249
|
def _createIcon(self, red: int, green: int, blue: int) -> QIcon:
|
249
250
|
"""Generate an icon for a status label."""
|
250
251
|
pixmap = QPixmap(self._iPX, self._iPX)
|
251
|
-
pixmap.fill(
|
252
|
+
pixmap.fill(QtTransparent)
|
252
253
|
|
253
254
|
painter = QPainter(pixmap)
|
254
|
-
painter.setRenderHint(
|
255
|
+
painter.setRenderHint(QtPaintAnitAlias)
|
255
256
|
painter.fillPath(self._iconPath, QColor(red, green, blue))
|
256
257
|
painter.end()
|
257
258
|
|
novelwriter/core/tokenizer.py
CHANGED
@@ -49,7 +49,7 @@ ESCAPES = {r"\*": "*", r"\~": "~", r"\_": "_", r"\[": "[", r"\]": "]", r"\ ": ""
|
|
49
49
|
RX_ESC = re.compile("|".join([re.escape(k) for k in ESCAPES.keys()]), flags=re.DOTALL)
|
50
50
|
|
51
51
|
|
52
|
-
def stripEscape(text) -> str:
|
52
|
+
def stripEscape(text: str) -> str:
|
53
53
|
"""Strip escaped Markdown characters from paragraph text."""
|
54
54
|
if "\\" in text:
|
55
55
|
return RX_ESC.sub(lambda x: ESCAPES[x.group(0)], text)
|
@@ -639,8 +639,8 @@ class Tokenizer(ABC):
|
|
639
639
|
tmpMarkdown.append(f"{aLine}\n")
|
640
640
|
|
641
641
|
elif aLine.startswith(("### ", "###! ")):
|
642
|
-
# (
|
643
|
-
#
|
642
|
+
# (Alternative) Scene Headings
|
643
|
+
# ============================
|
644
644
|
# Scene headings in novel documents are treated as centred
|
645
645
|
# separators if the formatting does not change the text. If the
|
646
646
|
# format is empty, the scene can be hidden or a blank paragraph
|