novelWriter 2.3.1__py3-none-any.whl → 2.4rc1__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.
Files changed (107) hide show
  1. {novelWriter-2.3.1.dist-info → novelWriter-2.4rc1.dist-info}/METADATA +5 -6
  2. {novelWriter-2.3.1.dist-info → novelWriter-2.4rc1.dist-info}/RECORD +102 -95
  3. novelwriter/__init__.py +7 -7
  4. novelwriter/assets/icons/none.svg +4 -0
  5. novelwriter/assets/icons/typicons_dark/icons.conf +4 -0
  6. novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +7 -0
  7. novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +1 -1
  8. novelwriter/assets/icons/typicons_dark/typ_refresh.svg +1 -1
  9. novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +4 -0
  10. novelwriter/assets/icons/typicons_dark/typ_times.svg +1 -1
  11. novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +4 -0
  12. novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +4 -0
  13. novelwriter/assets/icons/typicons_light/icons.conf +4 -0
  14. novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +7 -0
  15. novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +1 -1
  16. novelwriter/assets/icons/typicons_light/typ_refresh.svg +1 -1
  17. novelwriter/assets/icons/typicons_light/typ_search-grey.svg +4 -0
  18. novelwriter/assets/icons/typicons_light/typ_times.svg +1 -1
  19. novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +4 -0
  20. novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +4 -0
  21. novelwriter/assets/manual.pdf +0 -0
  22. novelwriter/assets/sample.zip +0 -0
  23. novelwriter/assets/syntax/default_dark.conf +1 -0
  24. novelwriter/assets/syntax/default_light.conf +1 -0
  25. novelwriter/assets/syntax/grey_dark.conf +1 -0
  26. novelwriter/assets/syntax/grey_light.conf +1 -0
  27. novelwriter/assets/syntax/light_owl.conf +1 -0
  28. novelwriter/assets/syntax/night_owl.conf +1 -0
  29. novelwriter/assets/syntax/solarized_dark.conf +1 -0
  30. novelwriter/assets/syntax/solarized_light.conf +1 -0
  31. novelwriter/assets/syntax/tomorrow.conf +1 -0
  32. novelwriter/assets/syntax/tomorrow_night.conf +1 -0
  33. novelwriter/assets/syntax/tomorrow_night_blue.conf +1 -0
  34. novelwriter/assets/syntax/tomorrow_night_bright.conf +1 -0
  35. novelwriter/assets/syntax/tomorrow_night_eighties.conf +1 -0
  36. novelwriter/assets/text/credits_en.htm +25 -23
  37. novelwriter/common.py +7 -2
  38. novelwriter/config.py +43 -16
  39. novelwriter/constants.py +5 -6
  40. novelwriter/core/buildsettings.py +60 -40
  41. novelwriter/core/coretools.py +97 -13
  42. novelwriter/core/docbuild.py +74 -7
  43. novelwriter/core/document.py +24 -3
  44. novelwriter/core/index.py +31 -112
  45. novelwriter/core/project.py +10 -15
  46. novelwriter/core/sessions.py +2 -2
  47. novelwriter/core/status.py +6 -5
  48. novelwriter/core/storage.py +8 -2
  49. novelwriter/core/tohtml.py +22 -25
  50. novelwriter/core/tokenizer.py +416 -232
  51. novelwriter/core/tomd.py +17 -8
  52. novelwriter/core/toodt.py +385 -350
  53. novelwriter/core/tree.py +8 -8
  54. novelwriter/dialogs/about.py +9 -11
  55. novelwriter/dialogs/docmerge.py +17 -14
  56. novelwriter/dialogs/docsplit.py +20 -19
  57. novelwriter/dialogs/editlabel.py +5 -4
  58. novelwriter/dialogs/preferences.py +31 -39
  59. novelwriter/dialogs/projectsettings.py +29 -26
  60. novelwriter/dialogs/quotes.py +10 -9
  61. novelwriter/dialogs/wordlist.py +15 -12
  62. novelwriter/enum.py +17 -14
  63. novelwriter/error.py +13 -11
  64. novelwriter/extensions/circularprogress.py +12 -8
  65. novelwriter/extensions/configlayout.py +1 -3
  66. novelwriter/extensions/modified.py +51 -2
  67. novelwriter/extensions/pagedsidebar.py +16 -14
  68. novelwriter/extensions/simpleprogress.py +3 -1
  69. novelwriter/extensions/statusled.py +3 -1
  70. novelwriter/extensions/switch.py +10 -9
  71. novelwriter/extensions/switchbox.py +14 -13
  72. novelwriter/extensions/versioninfo.py +1 -1
  73. novelwriter/gui/doceditor.py +413 -478
  74. novelwriter/gui/dochighlight.py +33 -29
  75. novelwriter/gui/docviewer.py +162 -175
  76. novelwriter/gui/docviewerpanel.py +20 -37
  77. novelwriter/gui/editordocument.py +15 -4
  78. novelwriter/gui/itemdetails.py +51 -54
  79. novelwriter/gui/mainmenu.py +37 -16
  80. novelwriter/gui/noveltree.py +30 -36
  81. novelwriter/gui/outline.py +114 -92
  82. novelwriter/gui/projtree.py +60 -66
  83. novelwriter/gui/search.py +362 -0
  84. novelwriter/gui/sidebar.py +36 -45
  85. novelwriter/gui/statusbar.py +14 -14
  86. novelwriter/gui/theme.py +93 -28
  87. novelwriter/guimain.py +207 -200
  88. novelwriter/shared.py +31 -6
  89. novelwriter/text/counting.py +137 -0
  90. novelwriter/tools/dictionaries.py +13 -12
  91. novelwriter/tools/lipsum.py +20 -17
  92. novelwriter/tools/manusbuild.py +35 -27
  93. novelwriter/tools/manuscript.py +374 -90
  94. novelwriter/tools/manussettings.py +261 -124
  95. novelwriter/tools/noveldetails.py +20 -18
  96. novelwriter/tools/welcome.py +48 -44
  97. novelwriter/tools/writingstats.py +61 -55
  98. novelwriter/types.py +90 -0
  99. novelwriter/core/__init__.py +0 -3
  100. novelwriter/dialogs/__init__.py +0 -3
  101. novelwriter/extensions/__init__.py +0 -3
  102. novelwriter/gui/__init__.py +0 -3
  103. novelwriter/tools/__init__.py +0 -3
  104. {novelWriter-2.3.1.dist-info → novelWriter-2.4rc1.dist-info}/LICENSE.md +0 -0
  105. {novelWriter-2.3.1.dist-info → novelWriter-2.4rc1.dist-info}/WHEEL +0 -0
  106. {novelWriter-2.3.1.dist-info → novelWriter-2.4rc1.dist-info}/entry_points.txt +0 -0
  107. {novelWriter-2.3.1.dist-info → novelWriter-2.4rc1.dist-info}/top_level.txt +0 -0
@@ -25,3 +25,4 @@ spellcheckline = 200, 46, 0
25
25
  errorline = 46, 200, 0
26
26
  replacetag = 225, 225, 225
27
27
  modifier = 225, 225, 225
28
+ texthighlight = 255, 255, 255, 64
@@ -25,3 +25,4 @@ spellcheckline = 200, 0, 0
25
25
  errorline = 0, 150, 0
26
26
  replacetag = 0, 0, 0
27
27
  modifier = 0, 0, 0
28
+ texthighlight = 0, 0, 0, 64
@@ -45,3 +45,4 @@ spellcheckline = 222, 61, 58
45
45
  errorline = 8, 145, 106
46
46
  replacetag = 42, 162, 152
47
47
  modifier = 224, 175, 5
48
+ texthighlight = 218, 170, 1, 96
@@ -45,3 +45,4 @@ spellcheckline = 247, 140, 108
45
45
  errorline = 173, 219, 103
46
46
  replacetag = 127, 219, 202
47
47
  modifier = 236, 196, 141
48
+ texthighlight = 255, 235, 149, 96
@@ -25,3 +25,4 @@ spellcheckline = 203, 75, 22
25
25
  errorline = 220, 50, 47
26
26
  replacetag = 133, 153, 0
27
27
  modifier = 181, 137, 0
28
+ texthighlight = 181, 137, 0, 96
@@ -25,3 +25,4 @@ spellcheckline = 203, 75, 22
25
25
  errorline = 220, 50, 47
26
26
  replacetag = 133, 153, 0
27
27
  modifier = 181, 137, 0
28
+ texthighlight = 181, 137, 0, 96
@@ -45,3 +45,4 @@ spellcheckline = 240, 40, 41
45
45
  errorline = 113, 140, 0
46
46
  replacetag = 62, 153, 159
47
47
  modifier = 245, 135, 31
48
+ texthighlight = 234, 183, 0, 96
@@ -45,3 +45,4 @@ spellcheckline = 204, 102, 102
45
45
  errorline = 181, 189, 104
46
46
  replacetag = 138, 190, 183
47
47
  modifier = 222, 147, 95
48
+ texthighlight = 240, 198, 116, 96
@@ -45,3 +45,4 @@ spellcheckline = 255, 157, 164
45
45
  errorline = 209, 241, 169
46
46
  replacetag = 153, 255, 255
47
47
  modifier = 255, 197, 143
48
+ texthighlight = 255, 238, 173, 96
@@ -45,3 +45,4 @@ spellcheckline = 213, 78, 83
45
45
  errorline = 185, 202, 74
46
46
  replacetag = 112, 192, 177
47
47
  modifier = 231, 140, 69
48
+ texthighlight = 231, 197, 71, 128
@@ -45,3 +45,4 @@ spellcheckline = 242, 119, 122
45
45
  errorline = 153, 204, 153
46
46
  replacetag = 102, 204, 204
47
47
  modifier = 249, 145, 57
48
+ texthighlight = 255, 204, 102, 96
@@ -8,9 +8,9 @@
8
8
  <h3>Contributors</h3>
9
9
 
10
10
  <p>
11
- <b>Concept:</b> Marian Lückhof (<a href="https://github.com/Number042">@Number042</a>)<br>
12
- <b>Internationalisation:</b> Bruno Meneguello (<a href="https://github.com/bkmeneguello">@bkmeneguello</a>)<br>
13
- <b>Setup and Packaging:</b> Rachel Powers (<a href="https://github.com/Ryex">@Ryex</a>)
11
+ &nbsp;&bull;&nbsp;<b>Concept:</b> Marian Lückhof (<a href="https://github.com/Number042">@Number042</a>)<br>
12
+ &nbsp;&bull;&nbsp;<b>Internationalisation:</b> Bruno Meneguello (<a href="https://github.com/bkmeneguello">@bkmeneguello</a>)<br>
13
+ &nbsp;&bull;&nbsp;<b>Setup and Packaging:</b> Rachel Powers (<a href="https://github.com/Ryex">@Ryex</a>)
14
14
  </p>
15
15
  <p>For other contributions, see the project's
16
16
  <a href="https://github.com/vkbo/novelWriter/graphs/contributors">Contributors</a> page.</p>
@@ -24,20 +24,20 @@
24
24
  <p>The default language is English (UK) with English (US) as an option. These are the original
25
25
  translators for the languages currently available:</p>
26
26
  <p>
27
- <b>Dutch:</b> Martijn van der Kleijn (<a href="https://github.com/mvdkleijn">@mvdkleijn</a>)<br>
28
- <b>French:</b> Jan Lüdke (<a href="https://github.com/jyhelle">@jyhelle</a>)<br>
29
- <b>German:</b> Myian (<a href="https://github.com/heymyian">@heymyian</a>)<br>
30
- <b>Italian:</b> Riccardo Mangili<br>
31
- <b>Japanese:</b> hebekeg (<a href="https://github.com/hebekeg">@hebekeg</a>)<br>
32
- <b>Latin American Spanish:</b> Tommy Marplatt (<a href="https://github.com/tmarplatt">@tmarplatt</a>)<br>
33
- <b>Norwegian:</b> Veronica Berglyd Olsen (<a href="https://github.com/vkbo">@vkbo</a>)<br>
34
- <b>Portuguese:</b> Bruno Meneguello (<a href="https://github.com/bkmeneguello">@bkmeneguello</a>)<br>
35
- <b>Simplified Chinese:</b> Qianzhi Long (<a href="https://github.com/longqzh">@longqzh</a>)
27
+ &nbsp;&bull;&nbsp;<b>Dutch:</b> Martijn van der Kleijn (<a href="https://github.com/mvdkleijn">@mvdkleijn</a>)<br>
28
+ &nbsp;&bull;&nbsp;<b>French:</b> Jan Lüdke (<a href="https://github.com/jyhelle">@jyhelle</a>)<br>
29
+ &nbsp;&bull;&nbsp;<b>German:</b> Myian (<a href="https://github.com/heymyian">@heymyian</a>)<br>
30
+ &nbsp;&bull;&nbsp;<b>Italian:</b> Riccardo Mangili<br>
31
+ &nbsp;&bull;&nbsp;<b>Japanese:</b> hebekeg (<a href="https://github.com/hebekeg">@hebekeg</a>)<br>
32
+ &nbsp;&bull;&nbsp;<b>Latin American Spanish:</b> Tommy Marplatt (<a href="https://github.com/tmarplatt">@tmarplatt</a>)<br>
33
+ &nbsp;&bull;&nbsp;<b>Norwegian:</b> Veronica Berglyd Olsen (<a href="https://github.com/vkbo">@vkbo</a>)<br>
34
+ &nbsp;&bull;&nbsp;<b>Portuguese:</b> Bruno Meneguello (<a href="https://github.com/bkmeneguello">@bkmeneguello</a>)<br>
35
+ &nbsp;&bull;&nbsp;<b>Simplified Chinese:</b> Qianzhi Long (<a href="https://github.com/longqzh">@longqzh</a>)
36
36
  </p>
37
37
 
38
38
  <p>Additional larger translation contributions:</p>
39
39
  <p>
40
- <b>French:</b> Albert Aribaud (<a href="https://github.com/aaribaud">@aaribaud</a>)
40
+ &nbsp;&bull;&nbsp;<b>French:</b> Albert Aribaud (<a href="https://github.com/aaribaud">@aaribaud</a>)
41
41
  </p>
42
42
 
43
43
  <p>Translations are managed on <a href="https://crowdin.com/project/novelwriter">Crowdin</a>, and
@@ -47,27 +47,29 @@ more contributions are listed on the project's <a href="https://crowdin.com/proj
47
47
 
48
48
  <p>The following libraries are dependencies of novelWriter:</p>
49
49
  <p>
50
- <a href="https://www.qt.io">Qt5</a> by Qt Company<br>
51
- <a href="https://www.riverbankcomputing.com/software/pyqt">PyQt5</a> by Riverbank Computing<br>
52
- <a href="https://abiword.github.io/enchant">Enchant</a> by Dom Lachowicz<br>
53
- <a href="https://pyenchant.github.io/pyenchant">PyEnchant</a> by Dimitri Merejkowsky
50
+ &nbsp;&bull;&nbsp;<a href="https://www.qt.io">Qt5</a> by Qt Company<br>
51
+ &nbsp;&bull;&nbsp;<a href="https://www.riverbankcomputing.com/software/pyqt">PyQt5</a> by Riverbank Computing<br>
52
+ &nbsp;&bull;&nbsp;<a href="https://abiword.github.io/enchant">Enchant</a> by Dom Lachowicz<br>
53
+ &nbsp;&bull;&nbsp;<a href="https://pyenchant.github.io/pyenchant">PyEnchant</a> by Dimitri Merejkowsky
54
54
  </p>
55
55
 
56
56
  <h3>Assets</h3>
57
57
 
58
58
  <p>Some of the assets bundled with novelWriter were adapted from the following sources:</p>
59
59
  <p>
60
- <a href="https://github.com/stephenhutchings/typicons.font">Typicons</a> icons by Stephen Hutchings (CC BY-SA 4.0)<br>
61
- <a href="https://github.com/chriskempson/base16">Tomorrow</a> syntax themes by Chris Kempson (MIT License)<br>
62
- <a href="https://github.com/sdras/night-owl-vscode-theme">Owl</a> syntax themes by Sarah Drasner (MIT License)<br>
63
- <a href="https://github.com/altercation/solarized">Solarized</a> themes by Ethan Schoonover (MIT License)
60
+ &nbsp;&bull;&nbsp;<a href="https://github.com/stephenhutchings/typicons.font">Typicons</a> icons by Stephen Hutchings (CC BY-SA 4.0)<br>
61
+ &nbsp;&bull;&nbsp;<a href="https://github.com/chriskempson/base16">Tomorrow</a> syntax themes by Chris Kempson (MIT License)<br>
62
+ &nbsp;&bull;&nbsp;<a href="https://github.com/sdras/night-owl-vscode-theme">Owl</a> syntax themes by Sarah Drasner (MIT License)<br>
63
+ &nbsp;&bull;&nbsp;<a href="https://github.com/altercation/solarized">Solarized</a> themes by Ethan Schoonover (MIT License)
64
64
  </p>
65
65
 
66
66
  <h3>Fonts</h3>
67
67
 
68
- <p>The font used for the main novelWriter logo, mimetype and text banners is:</p>
68
+ <p>The font used for the main novelWriter logo, mimetype and text banners is Pridi. Other fonts are
69
+ used on buttons and icons.</p>
69
70
  <p>
70
- Pridi by Cadson Demak (Open Font License, Version 1.1)
71
+ &nbsp;&bull;&nbsp;Pridi by Cadson Demak (Open Font License, Version 1.1)<br>
72
+ &nbsp;&bull;&nbsp;Source Sans Pro by Paul D. Hunt (SIL Open Font License)
71
73
  </p>
72
74
 
73
75
  <h3>Special Mentions</h3>
novelwriter/common.py CHANGED
@@ -36,7 +36,7 @@ from configparser import ConfigParser
36
36
  from urllib.parse import urljoin
37
37
  from urllib.request import pathname2url
38
38
 
39
- from PyQt5.QtGui import QDesktopServices
39
+ from PyQt5.QtGui import QColor, QDesktopServices
40
40
  from PyQt5.QtCore import QCoreApplication, QUrl
41
41
 
42
42
  from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
@@ -255,7 +255,7 @@ def formatFileFilter(extensions: list[str | tuple[str, str]]) -> str:
255
255
  result = []
256
256
  for ext in extensions:
257
257
  if isinstance(ext, str):
258
- result.append(f"{trConst(nwLabels.FILE_FILTERS.get(ext))} ({ext})")
258
+ result.append(f"{trConst(nwLabels.FILE_FILTERS.get(ext, 'ERR'))} ({ext})")
259
259
  elif isinstance(ext, tuple) and len(ext) == 2:
260
260
  result.append(f"{ext[0]} ({ext[1]})")
261
261
  return ";;".join(result)
@@ -382,6 +382,11 @@ def numberToRoman(value: int, toLower: bool = False) -> str:
382
382
  return roman.lower() if toLower else roman
383
383
 
384
384
 
385
+ def cssCol(col: QColor, alpha: int | None = None) -> str:
386
+ """Convert a QColor object to an rgba entry to use in CSS."""
387
+ return f"rgba({col.red()}, {col.green()}, {col.blue()}, {alpha or col.alpha()})"
388
+
389
+
385
390
  ##
386
391
  # Encoder Functions
387
392
  ##
novelwriter/config.py CHANGED
@@ -30,6 +30,7 @@ import logging
30
30
 
31
31
  from time import time
32
32
  from pathlib import Path
33
+ from datetime import datetime
33
34
 
34
35
  from PyQt5.QtGui import QFontDatabase
35
36
  from PyQt5.QtCore import (
@@ -60,8 +61,12 @@ class Config:
60
61
  self.appHandle = "novelwriter"
61
62
 
62
63
  # Set Paths
63
- confRoot = Path(QStandardPaths.writableLocation(QStandardPaths.ConfigLocation))
64
- dataRoot = Path(QStandardPaths.writableLocation(QStandardPaths.AppDataLocation))
64
+ confRoot = Path(QStandardPaths.writableLocation(
65
+ QStandardPaths.StandardLocation.ConfigLocation)
66
+ )
67
+ dataRoot = Path(QStandardPaths.writableLocation(
68
+ QStandardPaths.StandardLocation.AppDataLocation)
69
+ )
65
70
 
66
71
  self._confPath = confRoot.absolute() / self.appHandle # The user config location
67
72
  self._dataPath = dataRoot.absolute() / self.appHandle # The user data location
@@ -82,10 +87,13 @@ class Config:
82
87
  # Localisation
83
88
  # Note that these paths must be strings
84
89
  self._nwLangPath = self._appPath / "assets" / "i18n"
85
- self._qtLangPath = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
90
+ self._qtLangPath = QLibraryInfo.location(QLibraryInfo.LibraryLocation.TranslationsPath)
86
91
 
87
- wantedLocale = self._nwLangPath / f"nw_{QLocale.system().name()}.qm"
88
- self._qLocale = QLocale.system() if wantedLocale.exists() else QLocale("en_GB")
92
+ hasLocale = (self._nwLangPath / f"nw_{QLocale.system().name()}.qm").exists()
93
+ self._qLocale = QLocale.system() if hasLocale else QLocale("en_GB")
94
+ self._dLocale = QLocale.system()
95
+ self._dShortDate = self._dLocale.dateFormat(QLocale.FormatType.ShortFormat)
96
+ self._dShortDateTime = self._dLocale.dateTimeFormat(QLocale.FormatType.ShortFormat)
89
97
  self._qtTrans = {}
90
98
 
91
99
  # PDF Manual
@@ -179,17 +187,19 @@ class Config:
179
187
  # State
180
188
  self.showViewerPanel = True # The panel for the viewer is visible
181
189
  self.showEditToolBar = False # The document editor toolbar visibility
182
- self.useShortcodes = False # Use shortcodes for basic formatting
183
190
  self.viewComments = True # Comments are shown in the viewer
184
191
  self.viewSynopsis = True # Synopsis is shown in the viewer
185
192
 
186
- # Search Bar Switches
187
- self.searchCase = False
188
- self.searchWord = False
189
- self.searchRegEx = False
190
- self.searchLoop = False
191
- self.searchNextFile = False
192
- self.searchMatchCap = False
193
+ # Search Box States
194
+ self.searchCase = False
195
+ self.searchWord = False
196
+ self.searchRegEx = False
197
+ self.searchLoop = False
198
+ self.searchNextFile = False
199
+ self.searchMatchCap = False
200
+ self.searchProjCase = False
201
+ self.searchProjWord = False
202
+ self.searchProjRegEx = False
193
203
 
194
204
  # System and App Information
195
205
  # ==========================
@@ -363,7 +373,7 @@ class Config:
363
373
  elif self.osDarwin and "Helvetica" in fontFam:
364
374
  self.textFont = "Helvetica"
365
375
  else:
366
- self.textFont = fontDB.systemFont(QFontDatabase.GeneralFont).family()
376
+ self.textFont = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont).family()
367
377
  else:
368
378
  self.textFont = family
369
379
  return
@@ -414,6 +424,14 @@ class Config:
414
424
  self._errData = []
415
425
  return message
416
426
 
427
+ def localDate(self, value: datetime) -> str:
428
+ """Return a localised date format."""
429
+ return self._dLocale.toString(value, self._dShortDate)
430
+
431
+ def localDateTime(self, value: datetime) -> str:
432
+ """Return a localised datetime format."""
433
+ return self._dLocale.toString(value, self._dShortDateTime)
434
+
417
435
  def listLanguages(self, lngSet: int) -> list[tuple[str, str]]:
418
436
  """List localisation files in the i18n folder. The default GUI
419
437
  language is British English (en_GB).
@@ -496,6 +514,11 @@ class Config:
496
514
  QLocale.setDefault(self._qLocale)
497
515
  self._qtTrans = {}
498
516
 
517
+ hasLocale = (self._nwLangPath / f"nw_{self._qLocale.name()}.qm").exists()
518
+ self._dLocale = self._qLocale if hasLocale else QLocale.system()
519
+ self._dShortDate = self._dLocale.dateFormat(QLocale.FormatType.ShortFormat)
520
+ self._dShortDateTime = self._dLocale.dateTimeFormat(QLocale.FormatType.ShortFormat)
521
+
499
522
  langList = [
500
523
  (self._qtLangPath, "qtbase"), # Qt 5.x
501
524
  (str(self._nwLangPath), "nw"), # novelWriter
@@ -602,7 +625,6 @@ class Config:
602
625
  sec = "State"
603
626
  self.showViewerPanel = conf.rdBool(sec, "showviewerpanel", self.showViewerPanel)
604
627
  self.showEditToolBar = conf.rdBool(sec, "showedittoolbar", self.showEditToolBar)
605
- self.useShortcodes = conf.rdBool(sec, "useshortcodes", self.useShortcodes)
606
628
  self.viewComments = conf.rdBool(sec, "viewcomments", self.viewComments)
607
629
  self.viewSynopsis = conf.rdBool(sec, "viewsynopsis", self.viewSynopsis)
608
630
  self.searchCase = conf.rdBool(sec, "searchcase", self.searchCase)
@@ -611,6 +633,9 @@ class Config:
611
633
  self.searchLoop = conf.rdBool(sec, "searchloop", self.searchLoop)
612
634
  self.searchNextFile = conf.rdBool(sec, "searchnextfile", self.searchNextFile)
613
635
  self.searchMatchCap = conf.rdBool(sec, "searchmatchcap", self.searchMatchCap)
636
+ self.searchProjCase = conf.rdBool(sec, "searchprojcase", self.searchProjCase)
637
+ self.searchProjWord = conf.rdBool(sec, "searchprojword", self.searchProjWord)
638
+ self.searchProjRegEx = conf.rdBool(sec, "searchprojregex", self.searchProjRegEx)
614
639
 
615
640
  # Check Values
616
641
  # ============
@@ -708,7 +733,6 @@ class Config:
708
733
  conf["State"] = {
709
734
  "showviewerpanel": str(self.showViewerPanel),
710
735
  "showedittoolbar": str(self.showEditToolBar),
711
- "useshortcodes": str(self.useShortcodes),
712
736
  "viewcomments": str(self.viewComments),
713
737
  "viewsynopsis": str(self.viewSynopsis),
714
738
  "searchcase": str(self.searchCase),
@@ -717,6 +741,9 @@ class Config:
717
741
  "searchloop": str(self.searchLoop),
718
742
  "searchnextfile": str(self.searchNextFile),
719
743
  "searchmatchcap": str(self.searchMatchCap),
744
+ "searchprojcase": str(self.searchProjCase),
745
+ "searchprojword": str(self.searchProjWord),
746
+ "searchprojregex": str(self.searchProjRegEx),
720
747
  }
721
748
 
722
749
  # Write config file
novelwriter/constants.py CHANGED
@@ -23,8 +23,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- import re
27
-
28
26
  from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP
29
27
 
30
28
  from novelwriter.enum import nwBuildFmt, nwItemClass, nwItemLayout, nwOutline
@@ -55,6 +53,7 @@ class nwConst:
55
53
 
56
54
  # Gui Settings
57
55
  STATUS_MSG_TIMEOUT = 15000 # milliseconds
56
+ MAX_SEARCH_RESULT = 1000
58
57
 
59
58
  # Dialogs
60
59
  DLG_FINISHED = 2
@@ -67,12 +66,9 @@ class nwRegEx:
67
66
  FMT_EI = r"(?<![\w\\])(_)(?![\s_])(.+?)(?<![\s\\])(\1)(?!\w)"
68
67
  FMT_EB = r"(?<![\w\\])([\*]{2})(?![\s\*])(.+?)(?<![\s\\])(\1)(?!\w)"
69
68
  FMT_ST = r"(?<![\w\\])([~]{2})(?![\s~])(.+?)(?<![\s\\])(\1)(?!\w)"
70
- FMT_SC = r"(?i)(?<!\\)(\[[\/\!]?(?:i|b|s|u|sup|sub)\])"
69
+ FMT_SC = r"(?i)(?<!\\)(\[[\/\!]?(?:i|b|s|u|m|sup|sub)\])"
71
70
  FMT_SV = r"(?<!\\)(\[(?i)(?:fn|footnote):)(.+?)(?<!\\)(\])"
72
71
 
73
- # Pre-Compiled RegEx
74
- RX_SC = re.compile(FMT_SC)
75
-
76
72
  # END Class nwRegEx
77
73
 
78
74
 
@@ -86,6 +82,8 @@ class nwShortcode:
86
82
  STRIKE_C = "[/s]"
87
83
  ULINE_O = "[u]"
88
84
  ULINE_C = "[/u]"
85
+ MARK_O = "[m]"
86
+ MARK_C = "[/m]"
89
87
  SUP_O = "[sup]"
90
88
  SUP_C = "[/sup]"
91
89
  SUB_O = "[sub]"
@@ -408,6 +406,7 @@ class nwUnicode:
408
406
  U_THNBSP = "\u202f" # Thin non-breaking space
409
407
  U_ENSP = "\u2002" # Short (en) space
410
408
  U_EMSP = "\u2003" # Long (em) space
409
+ U_MMSP = "\u205f" # Medium mathematical space
411
410
  U_LSEP = "\u2028" # Line separator
412
411
  U_PSEP = "\u2029" # Paragraph separator
413
412
 
@@ -49,39 +49,54 @@ logger = logging.getLogger(__name__)
49
49
  # (type, default, [min value, max value])
50
50
 
51
51
  SETTINGS_TEMPLATE = {
52
- "filter.includeNovel": (bool, True),
53
- "filter.includeNotes": (bool, False),
54
- "filter.includeInactive": (bool, False),
55
- "headings.fmtTitle": (str, nwHeadFmt.TITLE),
56
- "headings.fmtChapter": (str, nwHeadFmt.TITLE),
57
- "headings.fmtUnnumbered": (str, nwHeadFmt.TITLE),
58
- "headings.fmtScene": (str, "* * *"),
59
- "headings.fmtSection": (str, ""),
60
- "headings.hideScene": (bool, False),
61
- "headings.hideSection": (bool, True),
62
- "text.includeSynopsis": (bool, False),
63
- "text.includeComments": (bool, False),
64
- "text.includeKeywords": (bool, False),
65
- "text.includeBodyText": (bool, True),
66
- "text.addNoteHeadings": (bool, True),
67
- "format.textFont": (str, CONFIG.textFont),
68
- "format.textSize": (int, 12),
69
- "format.lineHeight": (float, 1.15, 0.75, 3.0),
70
- "format.justifyText": (bool, False),
71
- "format.stripUnicode": (bool, False),
72
- "format.replaceTabs": (bool, False),
73
- "format.pageUnit": (str, "cm"),
74
- "format.pageSize": (str, "A4"),
75
- "format.pageWidth": (float, 21.0),
76
- "format.pageHeight": (float, 29.7),
77
- "format.topMargin": (float, 2.0),
78
- "format.bottomMargin": (float, 2.0),
79
- "format.leftMargin": (float, 2.0),
80
- "format.rightMargin": (float, 2.0),
81
- "odt.addColours": (bool, True),
82
- "odt.pageHeader": (str, nwHeadFmt.ODT_AUTO),
83
- "odt.pageCountOffset": (int, 0),
84
- "html.addStyles": (bool, True),
52
+ "filter.includeNovel": (bool, True),
53
+ "filter.includeNotes": (bool, False),
54
+ "filter.includeInactive": (bool, False),
55
+ "headings.fmtTitle": (str, nwHeadFmt.TITLE),
56
+ "headings.fmtChapter": (str, nwHeadFmt.TITLE),
57
+ "headings.fmtUnnumbered": (str, nwHeadFmt.TITLE),
58
+ "headings.fmtScene": (str, "* * *"),
59
+ "headings.fmtHardScene": (str, ""),
60
+ "headings.fmtSection": (str, ""),
61
+ "headings.hideTitle": (bool, False),
62
+ "headings.hideChapter": (bool, False),
63
+ "headings.hideUnnumbered": (bool, False),
64
+ "headings.hideScene": (bool, False),
65
+ "headings.hideHardScene": (bool, False),
66
+ "headings.hideSection": (bool, True),
67
+ "headings.centerTitle": (bool, True),
68
+ "headings.centerChapter": (bool, False),
69
+ "headings.centerScene": (bool, False),
70
+ "headings.breakTitle": (bool, True),
71
+ "headings.breakChapter": (bool, True),
72
+ "headings.breakScene": (bool, False),
73
+ "text.includeSynopsis": (bool, False),
74
+ "text.includeComments": (bool, False),
75
+ "text.includeKeywords": (bool, False),
76
+ "text.includeBodyText": (bool, True),
77
+ "text.ignoredKeywords": (str, ""),
78
+ "text.addNoteHeadings": (bool, True),
79
+ "format.textFont": (str, CONFIG.textFont),
80
+ "format.textSize": (int, 12),
81
+ "format.lineHeight": (float, 1.15, 0.75, 3.0),
82
+ "format.justifyText": (bool, False),
83
+ "format.stripUnicode": (bool, False),
84
+ "format.replaceTabs": (bool, False),
85
+ "format.pageUnit": (str, "cm"),
86
+ "format.pageSize": (str, "A4"),
87
+ "format.pageWidth": (float, 21.0),
88
+ "format.pageHeight": (float, 29.7),
89
+ "format.topMargin": (float, 2.0),
90
+ "format.bottomMargin": (float, 2.0),
91
+ "format.leftMargin": (float, 2.0),
92
+ "format.rightMargin": (float, 2.0),
93
+ "odt.addColours": (bool, True),
94
+ "odt.pageHeader": (str, nwHeadFmt.ODT_AUTO),
95
+ "odt.pageCountOffset": (int, 0),
96
+ "odt.firstLineIndent": (bool, False),
97
+ "md.preserveBreaks": (bool, True),
98
+ "html.addStyles": (bool, True),
99
+ "html.preserveTabs": (bool, False),
85
100
  }
86
101
 
87
102
  SETTINGS_LABELS = {
@@ -91,19 +106,19 @@ SETTINGS_LABELS = {
91
106
  "filter.includeInactive": QT_TRANSLATE_NOOP("Builds", "Inactive Documents"),
92
107
 
93
108
  "headings": QT_TRANSLATE_NOOP("Builds", "Headings"),
94
- "headings.fmtTitle": QT_TRANSLATE_NOOP("Builds", "Title Headings"),
95
- "headings.fmtChapter": QT_TRANSLATE_NOOP("Builds", "Chapter Headings"),
96
- "headings.fmtUnnumbered": QT_TRANSLATE_NOOP("Builds", "Unnumbered Headings"),
97
- "headings.fmtScene": QT_TRANSLATE_NOOP("Builds", "Scene Headings"),
98
- "headings.fmtSection": QT_TRANSLATE_NOOP("Builds", "Section Headings"),
99
- "headings.hideScene": QT_TRANSLATE_NOOP("Builds", "Hide Scene Headings"),
100
- "headings.hideSection": QT_TRANSLATE_NOOP("Builds", "Hide Section Headings"),
109
+ "headings.fmtTitle": QT_TRANSLATE_NOOP("Builds", "Partition Format"),
110
+ "headings.fmtChapter": QT_TRANSLATE_NOOP("Builds", "Chapter Format"),
111
+ "headings.fmtUnnumbered": QT_TRANSLATE_NOOP("Builds", "Unnumbered Format"),
112
+ "headings.fmtScene": QT_TRANSLATE_NOOP("Builds", "Scene Format"),
113
+ "headings.fmtHardScene": QT_TRANSLATE_NOOP("Builds", "Hard Scene Format"),
114
+ "headings.fmtSection": QT_TRANSLATE_NOOP("Builds", "Section Format"),
101
115
 
102
116
  "text.grpContent": QT_TRANSLATE_NOOP("Builds", "Text Content"),
103
117
  "text.includeSynopsis": QT_TRANSLATE_NOOP("Builds", "Include Synopsis"),
104
118
  "text.includeComments": QT_TRANSLATE_NOOP("Builds", "Include Comments"),
105
119
  "text.includeKeywords": QT_TRANSLATE_NOOP("Builds", "Include Keywords"),
106
120
  "text.includeBodyText": QT_TRANSLATE_NOOP("Builds", "Include Body Text"),
121
+ "text.ignoredKeywords": QT_TRANSLATE_NOOP("Builds", "Ignore These Keywords"),
107
122
  "text.grpInsert": QT_TRANSLATE_NOOP("Builds", "Insert Content"),
108
123
  "text.addNoteHeadings": QT_TRANSLATE_NOOP("Builds", "Add Titles for Notes"),
109
124
 
@@ -129,9 +144,14 @@ SETTINGS_LABELS = {
129
144
  "odt.addColours": QT_TRANSLATE_NOOP("Builds", "Add Highlight Colours"),
130
145
  "odt.pageHeader": QT_TRANSLATE_NOOP("Builds", "Page Header"),
131
146
  "odt.pageCountOffset": QT_TRANSLATE_NOOP("Builds", "Page Counter Offset"),
147
+ "odt.firstLineIndent": QT_TRANSLATE_NOOP("Builds", "First Line Indent"),
148
+
149
+ "md": QT_TRANSLATE_NOOP("Builds", "Markdown (.md)"),
150
+ "md.preserveBreaks": QT_TRANSLATE_NOOP("Builds", "Preserve Hard Line Breaks"),
132
151
 
133
152
  "html": QT_TRANSLATE_NOOP("Builds", "HTML (.html)"),
134
153
  "html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"),
154
+ "html.preserveTabs": QT_TRANSLATE_NOOP("Builds", "Preserve Tab Characters"),
135
155
  }
136
156
 
137
157