novelWriter 2.3.1__py3-none-any.whl → 2.4b1__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 (81) hide show
  1. {novelWriter-2.3.1.dist-info → novelWriter-2.4b1.dist-info}/METADATA +1 -1
  2. {novelWriter-2.3.1.dist-info → novelWriter-2.4b1.dist-info}/RECORD +81 -70
  3. novelwriter/__init__.py +5 -5
  4. novelwriter/assets/icons/typicons_dark/icons.conf +4 -0
  5. novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +7 -0
  6. novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg +4 -0
  7. novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg +4 -0
  8. novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +1 -1
  9. novelwriter/assets/icons/typicons_dark/typ_refresh.svg +1 -1
  10. novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +4 -0
  11. novelwriter/assets/icons/typicons_dark/typ_times.svg +1 -1
  12. novelwriter/assets/icons/typicons_light/icons.conf +4 -0
  13. novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +7 -0
  14. novelwriter/assets/icons/typicons_light/typ_arrow-down.svg +4 -0
  15. novelwriter/assets/icons/typicons_light/typ_arrow-right.svg +4 -0
  16. novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +1 -1
  17. novelwriter/assets/icons/typicons_light/typ_refresh.svg +1 -1
  18. novelwriter/assets/icons/typicons_light/typ_search-grey.svg +4 -0
  19. novelwriter/assets/icons/typicons_light/typ_times.svg +1 -1
  20. novelwriter/assets/manual.pdf +0 -0
  21. novelwriter/assets/sample.zip +0 -0
  22. novelwriter/assets/syntax/default_dark.conf +1 -0
  23. novelwriter/assets/syntax/default_light.conf +1 -0
  24. novelwriter/assets/syntax/grey_dark.conf +1 -0
  25. novelwriter/assets/syntax/grey_light.conf +1 -0
  26. novelwriter/assets/syntax/light_owl.conf +1 -0
  27. novelwriter/assets/syntax/night_owl.conf +1 -0
  28. novelwriter/assets/syntax/solarized_dark.conf +1 -0
  29. novelwriter/assets/syntax/solarized_light.conf +1 -0
  30. novelwriter/assets/syntax/tomorrow.conf +1 -0
  31. novelwriter/assets/syntax/tomorrow_night.conf +1 -0
  32. novelwriter/assets/syntax/tomorrow_night_blue.conf +1 -0
  33. novelwriter/assets/syntax/tomorrow_night_bright.conf +1 -0
  34. novelwriter/assets/syntax/tomorrow_night_eighties.conf +1 -0
  35. novelwriter/assets/text/credits_en.htm +25 -23
  36. novelwriter/common.py +1 -1
  37. novelwriter/config.py +35 -12
  38. novelwriter/constants.py +5 -6
  39. novelwriter/core/buildsettings.py +60 -40
  40. novelwriter/core/coretools.py +98 -13
  41. novelwriter/core/docbuild.py +74 -7
  42. novelwriter/core/document.py +24 -3
  43. novelwriter/core/index.py +31 -112
  44. novelwriter/core/project.py +10 -15
  45. novelwriter/core/sessions.py +2 -2
  46. novelwriter/core/status.py +4 -4
  47. novelwriter/core/storage.py +8 -2
  48. novelwriter/core/tohtml.py +22 -25
  49. novelwriter/core/tokenizer.py +416 -232
  50. novelwriter/core/tomd.py +17 -8
  51. novelwriter/core/toodt.py +65 -7
  52. novelwriter/core/tree.py +8 -8
  53. novelwriter/dialogs/docsplit.py +7 -8
  54. novelwriter/dialogs/preferences.py +3 -6
  55. novelwriter/enum.py +17 -14
  56. novelwriter/extensions/modified.py +20 -2
  57. novelwriter/extensions/versioninfo.py +1 -1
  58. novelwriter/gui/doceditor.py +257 -279
  59. novelwriter/gui/dochighlight.py +29 -25
  60. novelwriter/gui/docviewer.py +139 -148
  61. novelwriter/gui/docviewerpanel.py +4 -24
  62. novelwriter/gui/editordocument.py +12 -1
  63. novelwriter/gui/itemdetails.py +6 -6
  64. novelwriter/gui/mainmenu.py +37 -16
  65. novelwriter/gui/noveltree.py +11 -19
  66. novelwriter/gui/outline.py +43 -20
  67. novelwriter/gui/projtree.py +35 -43
  68. novelwriter/gui/search.py +316 -0
  69. novelwriter/gui/sidebar.py +25 -30
  70. novelwriter/gui/theme.py +59 -6
  71. novelwriter/guimain.py +176 -173
  72. novelwriter/shared.py +26 -1
  73. novelwriter/text/__init__.py +3 -0
  74. novelwriter/text/counting.py +137 -0
  75. novelwriter/tools/manuscript.py +344 -55
  76. novelwriter/tools/manussettings.py +213 -71
  77. novelwriter/tools/welcome.py +1 -1
  78. {novelWriter-2.3.1.dist-info → novelWriter-2.4b1.dist-info}/LICENSE.md +0 -0
  79. {novelWriter-2.3.1.dist-info → novelWriter-2.4b1.dist-info}/WHEEL +0 -0
  80. {novelWriter-2.3.1.dist-info → novelWriter-2.4b1.dist-info}/entry_points.txt +0 -0
  81. {novelWriter-2.3.1.dist-info → novelWriter-2.4b1.dist-info}/top_level.txt +0 -0
@@ -74,15 +74,9 @@ class ToHtml(Tokenizer):
74
74
  # Setters
75
75
  ##
76
76
 
77
- def setPreview(self, doComments: bool, doSynopsis: bool) -> None:
78
- """If we're using this class to generate markdown preview, we
79
- need to make a few changes to formatting, which is managed by
80
- these flags.
81
- """
82
- self._genMode = self.M_PREVIEW
83
- self._doKeywords = True
84
- self._doComments = doComments
85
- self._doSynopsis = doSynopsis
77
+ def setPreview(self, state: bool) -> None:
78
+ """Set to preview generator mode."""
79
+ self._genMode = self.M_PREVIEW if state else self.M_EXPORT
86
80
  return
87
81
 
88
82
  def setStyles(self, cssStyles: bool) -> None:
@@ -133,6 +127,8 @@ class ToHtml(Tokenizer):
133
127
  self.FMT_D_E: "</span>",
134
128
  self.FMT_U_B: "<u>",
135
129
  self.FMT_U_E: "</u>",
130
+ self.FMT_M_B: "<mark>",
131
+ self.FMT_M_E: "</mark>",
136
132
  }
137
133
  else:
138
134
  htmlTags = { # HTML5 (for export)
@@ -144,6 +140,8 @@ class ToHtml(Tokenizer):
144
140
  self.FMT_D_E: "</del>",
145
141
  self.FMT_U_B: "<span style='text-decoration: underline;'>",
146
142
  self.FMT_U_E: "</span>",
143
+ self.FMT_M_B: "<mark>",
144
+ self.FMT_M_E: "</mark>",
147
145
  }
148
146
 
149
147
  htmlTags[self.FMT_SUP_B] = "<sup>"
@@ -171,6 +169,8 @@ class ToHtml(Tokenizer):
171
169
  pStyle = None
172
170
  lines = []
173
171
 
172
+ tHandle = self._handle
173
+
174
174
  for tType, nHead, tText, tFormat, tStyle in self._tokens:
175
175
 
176
176
  # Replace < and > with HTML entities
@@ -229,8 +229,8 @@ class ToHtml(Tokenizer):
229
229
  else:
230
230
  hStyle = ""
231
231
 
232
- if self._linkHeaders:
233
- aNm = f"<a name='T{nHead:04d}'></a>"
232
+ if self._linkHeadings and tHandle:
233
+ aNm = f"<a name='{tHandle}:T{nHead:04d}'></a>"
234
234
  else:
235
235
  aNm = ""
236
236
 
@@ -252,10 +252,6 @@ class ToHtml(Tokenizer):
252
252
  tHead = tText.replace(nwHeadFmt.BR, "<br/>")
253
253
  lines.append(f"<h1 class='title'{hStyle}>{aNm}{tHead}</h1>\n")
254
254
 
255
- elif tType == self.T_UNNUM:
256
- tHead = tText.replace(nwHeadFmt.BR, "<br/>")
257
- lines.append(f"<{h2}{hStyle}>{aNm}{tHead}</{h2}>\n")
258
-
259
255
  elif tType == self.T_HEAD1:
260
256
  tHead = tText.replace(nwHeadFmt.BR, "<br/>")
261
257
  lines.append(f"<{h1}{h1Cl}{hStyle}>{aNm}{tHead}</{h1}>\n")
@@ -296,12 +292,13 @@ class ToHtml(Tokenizer):
296
292
  lines.append(self._formatComments(tText))
297
293
 
298
294
  elif tType == self.T_KEYWORD and self._doKeywords:
299
- tTemp = f"<p{hStyle}>{self._formatKeywords(tText)}</p>\n"
295
+ tag, text = self._formatKeywords(tText)
296
+ kClass = f" class='meta meta-{tag}'" if tag else ""
297
+ tTemp = f"<p{kClass}{hStyle}>{text}</p>\n"
300
298
  lines.append(tTemp)
301
299
 
302
300
  self._result = "".join(lines)
303
- if self._genMode != self.M_PREVIEW:
304
- self._fullHTML.append(self._result)
301
+ self._fullHTML.append(self._result)
305
302
 
306
303
  return
307
304
 
@@ -364,13 +361,12 @@ class ToHtml(Tokenizer):
364
361
 
365
362
  def getStyleSheet(self) -> list[str]:
366
363
  """Generate a stylesheet for the current settings."""
367
- styles = []
368
364
  if not self._cssStyles:
369
- return styles
365
+ return []
370
366
 
371
367
  mScale = self._lineHeight/1.15
372
- textAlign = "justify" if self._doJustify else "left"
373
368
 
369
+ styles = []
374
370
  styles.append("body {{font-family: '{0:s}'; font-size: {1:d}pt;}}".format(
375
371
  self._textFont, self._textSize
376
372
  ))
@@ -380,7 +376,7 @@ class ToHtml(Tokenizer):
380
376
  "margin-top: {2:.2f}em; margin-bottom: {3:.2f}em;"
381
377
  "}}"
382
378
  ).format(
383
- textAlign,
379
+ "justify" if self._doJustify else "left",
384
380
  round(100 * self._lineHeight),
385
381
  mScale * self._marginText[0],
386
382
  mScale * self._marginText[1],
@@ -445,6 +441,7 @@ class ToHtml(Tokenizer):
445
441
  ))
446
442
 
447
443
  styles.append("a {color: rgb(66, 113, 174);}")
444
+ styles.append("mark {background: rgb(255, 255, 166);}")
448
445
  styles.append(".tags {color: rgb(245, 135, 31); font-weight: bold;}")
449
446
  styles.append(".break {text-align: left;}")
450
447
  styles.append(".synopsis {font-style: italic;}")
@@ -475,11 +472,11 @@ class ToHtml(Tokenizer):
475
472
  sComm = self._localLookup("Comment")
476
473
  return f"<p class='comment'><strong>{sComm}:</strong> {text}</p>\n"
477
474
 
478
- def _formatKeywords(self, text: str) -> str:
475
+ def _formatKeywords(self, text: str) -> tuple[str, str]:
479
476
  """Apply HTML formatting to keywords."""
480
477
  valid, bits, _ = self._project.index.scanThis("@"+text)
481
478
  if not valid or not bits or bits[0] not in nwLabels.KEY_NAME:
482
- return ""
479
+ return "", ""
483
480
 
484
481
  result = f"<span class='tags'>{self._localLookup(nwLabels.KEY_NAME[bits[0]])}:</span> "
485
482
  if len(bits) > 1:
@@ -494,6 +491,6 @@ class ToHtml(Tokenizer):
494
491
  else:
495
492
  result += ", ".join(f"<a href='#tag_{t}'>{t}</a>" for t in bits[1:])
496
493
 
497
- return result
494
+ return bits[0][1:], result
498
495
 
499
496
  # END Class ToHtml