novelWriter 2.7.4__py3-none-any.whl → 2.8b1__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/__init__.py +8 -7
 - novelwriter/assets/icons/font_awesome.icons +22 -4
 - novelwriter/assets/icons/material_filled_normal.icons +20 -2
 - novelwriter/assets/icons/material_filled_thin.icons +20 -2
 - novelwriter/assets/icons/material_rounded_normal.icons +20 -2
 - novelwriter/assets/icons/material_rounded_thin.icons +20 -2
 - novelwriter/assets/icons/material_sharp_normal.icons +20 -2
 - novelwriter/assets/icons/material_sharp_thin.icons +20 -2
 - novelwriter/assets/icons/remix_filled.icons +20 -2
 - novelwriter/assets/icons/remix_outline.icons +20 -2
 - novelwriter/assets/images/welcome.webp +0 -0
 - novelwriter/assets/manual.pdf +0 -0
 - novelwriter/assets/manual_fr.pdf +0 -0
 - novelwriter/assets/sample.zip +0 -0
 - novelwriter/assets/text/credits_en.htm +61 -11
 - novelwriter/assets/themes/aura.conf +97 -0
 - novelwriter/assets/themes/aura_bright.conf +95 -0
 - novelwriter/assets/themes/aura_soft.conf +97 -0
 - novelwriter/assets/themes/b2t_garden_dark.conf +97 -0
 - novelwriter/assets/themes/b2t_garden_light.conf +97 -0
 - novelwriter/assets/themes/b2t_suburb_dark.conf +97 -0
 - novelwriter/assets/themes/b2t_suburb_light.conf +97 -0
 - novelwriter/assets/themes/b4t_classic_o_dark.conf +97 -0
 - novelwriter/assets/themes/b4t_classic_o_light.conf +97 -0
 - novelwriter/assets/themes/b4t_modern_c_dark.conf +97 -0
 - novelwriter/assets/themes/b4t_modern_c_light.conf +97 -0
 - novelwriter/assets/themes/blue_streak_dark.conf +97 -0
 - novelwriter/assets/themes/blue_streak_light.conf +97 -0
 - novelwriter/assets/themes/castle_day.conf +95 -0
 - novelwriter/assets/themes/castle_night.conf +95 -0
 - novelwriter/assets/themes/catppuccin_latte.conf +97 -0
 - novelwriter/assets/themes/catppuccin_mocha.conf +97 -0
 - novelwriter/assets/themes/chalky_soil.conf +95 -0
 - novelwriter/assets/themes/chernozem.conf +95 -0
 - novelwriter/assets/themes/cyberpunk_night.conf +88 -40
 - novelwriter/assets/themes/default_dark.conf +89 -41
 - novelwriter/assets/themes/default_light.conf +89 -41
 - novelwriter/assets/themes/dracula.conf +91 -42
 - novelwriter/assets/themes/espresso.conf +97 -0
 - novelwriter/assets/themes/everforest_dark.conf +97 -0
 - novelwriter/assets/themes/everforest_light.conf +97 -0
 - novelwriter/assets/themes/floral_daydream.conf +95 -0
 - novelwriter/assets/themes/floral_midnight.conf +95 -0
 - novelwriter/assets/themes/full_moon.conf +95 -0
 - novelwriter/assets/themes/grey_dark.conf +97 -0
 - novelwriter/assets/themes/grey_light.conf +97 -0
 - novelwriter/assets/themes/horizon_dark.conf +97 -0
 - novelwriter/assets/themes/horizon_light.conf +97 -0
 - novelwriter/assets/themes/jewel_case_dark.conf +95 -0
 - novelwriter/assets/themes/jewel_case_light.conf +95 -0
 - novelwriter/assets/themes/lcars.conf +97 -0
 - novelwriter/assets/themes/light_owl.conf +117 -0
 - novelwriter/assets/themes/new_moon.conf +97 -0
 - novelwriter/assets/themes/night_owl.conf +117 -0
 - novelwriter/assets/themes/noctis.conf +129 -0
 - novelwriter/assets/themes/noctis_lux.conf +129 -0
 - novelwriter/assets/themes/nord.conf +97 -0
 - novelwriter/assets/themes/nordlicht.conf +95 -0
 - novelwriter/assets/themes/otium_dark.conf +95 -0
 - novelwriter/assets/themes/otium_light.conf +95 -0
 - novelwriter/assets/themes/paragon.conf +96 -0
 - novelwriter/assets/themes/primer_light.conf +97 -0
 - novelwriter/assets/themes/primer_night.conf +97 -0
 - novelwriter/assets/themes/rose_pine.conf +97 -0
 - novelwriter/assets/themes/rose_pine_dawn.conf +97 -0
 - novelwriter/assets/themes/ruby_day.conf +95 -0
 - novelwriter/assets/themes/ruby_night.conf +95 -0
 - novelwriter/assets/themes/selenium_dark.conf +95 -0
 - novelwriter/assets/themes/selenium_light.conf +95 -0
 - novelwriter/assets/themes/sepia_dark.conf +95 -0
 - novelwriter/assets/themes/sepia_light.conf +95 -0
 - novelwriter/assets/themes/snazzy.conf +102 -40
 - novelwriter/assets/themes/solarized_dark.conf +108 -40
 - novelwriter/assets/themes/solarized_light.conf +108 -40
 - novelwriter/assets/themes/sultana_light.conf +95 -0
 - novelwriter/assets/themes/sultana_night.conf +95 -0
 - novelwriter/assets/themes/tango_dark.conf +111 -0
 - novelwriter/assets/themes/tango_light.conf +111 -0
 - novelwriter/assets/themes/tomorrow.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_blue.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_bright.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_eighties.conf +117 -0
 - novelwriter/assets/themes/vivid_black_green.conf +97 -0
 - novelwriter/assets/themes/vivid_black_red.conf +97 -0
 - novelwriter/assets/themes/vivid_white_green.conf +97 -0
 - novelwriter/assets/themes/vivid_white_red.conf +97 -0
 - novelwriter/assets/themes/warpgate.conf +96 -0
 - novelwriter/assets/themes/waterlily_dark.conf +95 -0
 - novelwriter/assets/themes/waterlily_light.conf +95 -0
 - novelwriter/common.py +47 -17
 - novelwriter/config.py +57 -62
 - novelwriter/constants.py +32 -6
 - novelwriter/core/buildsettings.py +3 -23
 - novelwriter/core/coretools.py +21 -25
 - novelwriter/core/docbuild.py +4 -9
 - novelwriter/core/document.py +2 -6
 - novelwriter/core/index.py +33 -53
 - novelwriter/core/indexdata.py +17 -22
 - novelwriter/core/item.py +11 -35
 - novelwriter/core/itemmodel.py +5 -21
 - novelwriter/core/novelmodel.py +3 -7
 - novelwriter/core/options.py +3 -4
 - novelwriter/core/project.py +31 -21
 - novelwriter/core/projectdata.py +2 -21
 - novelwriter/core/projectxml.py +13 -21
 - novelwriter/core/sessions.py +2 -4
 - novelwriter/core/spellcheck.py +12 -13
 - novelwriter/core/status.py +27 -20
 - novelwriter/core/storage.py +5 -10
 - novelwriter/core/tree.py +6 -15
 - novelwriter/dialogs/about.py +9 -10
 - novelwriter/dialogs/docmerge.py +17 -14
 - novelwriter/dialogs/docsplit.py +18 -14
 - novelwriter/dialogs/editlabel.py +15 -9
 - novelwriter/dialogs/preferences.py +69 -68
 - novelwriter/dialogs/projectsettings.py +88 -67
 - novelwriter/dialogs/quotes.py +15 -10
 - novelwriter/dialogs/wordlist.py +18 -21
 - novelwriter/enum.py +75 -30
 - novelwriter/error.py +6 -11
 - novelwriter/extensions/configlayout.py +8 -34
 - novelwriter/extensions/eventfilters.py +3 -3
 - novelwriter/extensions/modified.py +87 -32
 - novelwriter/extensions/novelselector.py +13 -12
 - novelwriter/extensions/pagedsidebar.py +10 -18
 - novelwriter/extensions/progressbars.py +5 -11
 - novelwriter/extensions/statusled.py +3 -6
 - novelwriter/extensions/switch.py +8 -11
 - novelwriter/extensions/switchbox.py +2 -11
 - novelwriter/extensions/versioninfo.py +6 -7
 - novelwriter/formats/shared.py +10 -2
 - novelwriter/formats/todocx.py +15 -37
 - novelwriter/formats/tohtml.py +52 -61
 - novelwriter/formats/tokenizer.py +33 -64
 - novelwriter/formats/tomarkdown.py +4 -11
 - novelwriter/formats/toodt.py +12 -71
 - novelwriter/formats/toqdoc.py +11 -21
 - novelwriter/formats/toraw.py +2 -6
 - novelwriter/gui/doceditor.py +207 -245
 - novelwriter/gui/dochighlight.py +142 -101
 - novelwriter/gui/docviewer.py +53 -84
 - novelwriter/gui/docviewerpanel.py +18 -41
 - novelwriter/gui/editordocument.py +12 -17
 - novelwriter/gui/itemdetails.py +5 -14
 - novelwriter/gui/mainmenu.py +24 -32
 - novelwriter/gui/noveltree.py +13 -51
 - novelwriter/gui/outline.py +20 -61
 - novelwriter/gui/projtree.py +40 -96
 - novelwriter/gui/search.py +9 -24
 - novelwriter/gui/sidebar.py +54 -22
 - novelwriter/gui/statusbar.py +7 -22
 - novelwriter/gui/theme.py +482 -368
 - novelwriter/guimain.py +87 -101
 - novelwriter/shared.py +79 -48
 - novelwriter/splash.py +9 -5
 - novelwriter/text/comments.py +1 -1
 - novelwriter/text/counting.py +9 -5
 - novelwriter/text/patterns.py +20 -15
 - novelwriter/tools/dictionaries.py +18 -16
 - novelwriter/tools/lipsum.py +15 -17
 - novelwriter/tools/manusbuild.py +25 -45
 - novelwriter/tools/manuscript.py +94 -95
 - novelwriter/tools/manussettings.py +149 -104
 - novelwriter/tools/noveldetails.py +10 -24
 - novelwriter/tools/welcome.py +24 -72
 - novelwriter/tools/writingstats.py +17 -26
 - novelwriter/types.py +25 -13
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/METADATA +7 -7
 - novelwriter-2.8b1.dist-info/RECORD +212 -0
 - novelwriter/assets/images/welcome-dark.jpg +0 -0
 - novelwriter/assets/images/welcome-light.jpg +0 -0
 - novelwriter/assets/syntax/cyberpunk_night.conf +0 -28
 - novelwriter/assets/syntax/default_dark.conf +0 -42
 - novelwriter/assets/syntax/default_light.conf +0 -42
 - novelwriter/assets/syntax/dracula.conf +0 -44
 - novelwriter/assets/syntax/grey_dark.conf +0 -29
 - novelwriter/assets/syntax/grey_light.conf +0 -29
 - novelwriter/assets/syntax/light_owl.conf +0 -49
 - novelwriter/assets/syntax/night_owl.conf +0 -49
 - novelwriter/assets/syntax/snazzy.conf +0 -42
 - novelwriter/assets/syntax/solarized_dark.conf +0 -29
 - novelwriter/assets/syntax/solarized_light.conf +0 -29
 - novelwriter/assets/syntax/tango.conf +0 -39
 - novelwriter/assets/syntax/tomorrow.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_blue.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_bright.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_eighties.conf +0 -49
 - novelwriter/assets/themes/default.conf +0 -3
 - novelwriter-2.7.4.dist-info/RECORD +0 -163
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/WHEEL +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/entry_points.txt +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/licenses/LICENSE.md +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/licenses/setup/LICENSE-Apache-2.0.txt +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/top_level.txt +0 -0
 
| 
         @@ -21,7 +21,7 @@ General Public License for more details. 
     | 
|
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       23 
23 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       24 
     | 
    
         
            -
            """
         
     | 
| 
      
 24 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       25 
25 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
            import json
         
     | 
| 
         @@ -211,7 +211,7 @@ class FilterMode(Enum): 
     | 
|
| 
       211 
211 
     | 
    
         | 
| 
       212 
212 
     | 
    
         | 
| 
       213 
213 
     | 
    
         
             
            class BuildSettings:
         
     | 
| 
       214 
     | 
    
         
            -
                """Core: Build Settings Class
         
     | 
| 
      
 214 
     | 
    
         
            +
                """Core: Build Settings Class.
         
     | 
| 
       215 
215 
     | 
    
         | 
| 
       216 
216 
     | 
    
         
             
                This class manages the build settings for a Manuscript build job.
         
     | 
| 
       217 
217 
     | 
    
         
             
                The settings can be packed/unpacked to/from a dictionary for JSON.
         
     | 
| 
         @@ -229,7 +229,6 @@ class BuildSettings: 
     | 
|
| 
       229 
229 
     | 
    
         
             
                    self._included = set()
         
     | 
| 
       230 
230 
     | 
    
         
             
                    self._settings = {k: v[1] for k, v in SETTINGS_TEMPLATE.items()}
         
     | 
| 
       231 
231 
     | 
    
         
             
                    self._changed = False
         
     | 
| 
       232 
     | 
    
         
            -
                    return
         
     | 
| 
       233 
232 
     | 
    
         | 
| 
       234 
233 
     | 
    
         
             
                @classmethod
         
     | 
| 
       235 
234 
     | 
    
         
             
                def fromDict(cls, data: dict) -> BuildSettings:
         
     | 
| 
         @@ -315,7 +314,6 @@ class BuildSettings: 
     | 
|
| 
       315 
314 
     | 
    
         
             
                def setName(self, name: str) -> None:
         
     | 
| 
       316 
315 
     | 
    
         
             
                    """Set the build setting display name."""
         
     | 
| 
       317 
316 
     | 
    
         
             
                    self._name = str(name)
         
     | 
| 
       318 
     | 
    
         
            -
                    return
         
     | 
| 
       319 
317 
     | 
    
         | 
| 
       320 
318 
     | 
    
         
             
                def setBuildID(self, value: str | uuid.UUID) -> None:
         
     | 
| 
       321 
319 
     | 
    
         
             
                    """Set a UUID build ID."""
         
     | 
| 
         @@ -324,13 +322,11 @@ class BuildSettings: 
     | 
|
| 
       324 
322 
     | 
    
         
             
                        self._uuid = str(uuid.uuid4())
         
     | 
| 
       325 
323 
     | 
    
         
             
                    elif value != self._uuid:
         
     | 
| 
       326 
324 
     | 
    
         
             
                        self._uuid = value
         
     | 
| 
       327 
     | 
    
         
            -
                    return
         
     | 
| 
       328 
325 
     | 
    
         | 
| 
       329 
326 
     | 
    
         
             
                def setOrder(self, value: int) -> None:
         
     | 
| 
       330 
327 
     | 
    
         
             
                    """Set the build order."""
         
     | 
| 
       331 
328 
     | 
    
         
             
                    if isinstance(value, int):
         
     | 
| 
       332 
329 
     | 
    
         
             
                        self._order = value
         
     | 
| 
       333 
     | 
    
         
            -
                    return
         
     | 
| 
       334 
330 
     | 
    
         | 
| 
       335 
331 
     | 
    
         
             
                def setLastBuildPath(self, path: Path | str | None) -> None:
         
     | 
| 
       336 
332 
     | 
    
         
             
                    """Set the last used build path."""
         
     | 
| 
         @@ -341,41 +337,35 @@ class BuildSettings: 
     | 
|
| 
       341 
337 
     | 
    
         
             
                    else:
         
     | 
| 
       342 
338 
     | 
    
         
             
                        self._path = CONFIG.homePath()
         
     | 
| 
       343 
339 
     | 
    
         
             
                    self._changed = True
         
     | 
| 
       344 
     | 
    
         
            -
                    return
         
     | 
| 
       345 
340 
     | 
    
         | 
| 
       346 
341 
     | 
    
         
             
                def setLastBuildName(self, name: str) -> None:
         
     | 
| 
       347 
342 
     | 
    
         
             
                    """Set the last used build name."""
         
     | 
| 
       348 
343 
     | 
    
         
             
                    self._build = str(name).strip()
         
     | 
| 
       349 
344 
     | 
    
         
             
                    self._changed = True
         
     | 
| 
       350 
     | 
    
         
            -
                    return
         
     | 
| 
       351 
345 
     | 
    
         | 
| 
       352 
346 
     | 
    
         
             
                def setLastFormat(self, value: nwBuildFmt) -> None:
         
     | 
| 
       353 
347 
     | 
    
         
             
                    """Set the last used build format."""
         
     | 
| 
       354 
348 
     | 
    
         
             
                    if isinstance(value, nwBuildFmt):
         
     | 
| 
       355 
349 
     | 
    
         
             
                        self._format = value
         
     | 
| 
       356 
350 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       357 
     | 
    
         
            -
                    return
         
     | 
| 
       358 
351 
     | 
    
         | 
| 
       359 
352 
     | 
    
         
             
                def setFiltered(self, tHandle: str) -> None:
         
     | 
| 
       360 
353 
     | 
    
         
             
                    """Set an item as filtered."""
         
     | 
| 
       361 
354 
     | 
    
         
             
                    self._excluded.discard(tHandle)
         
     | 
| 
       362 
355 
     | 
    
         
             
                    self._included.discard(tHandle)
         
     | 
| 
       363 
356 
     | 
    
         
             
                    self._changed = True
         
     | 
| 
       364 
     | 
    
         
            -
                    return
         
     | 
| 
       365 
357 
     | 
    
         | 
| 
       366 
358 
     | 
    
         
             
                def setIncluded(self, tHandle: str) -> None:
         
     | 
| 
       367 
359 
     | 
    
         
             
                    """Set an item as explicitly included."""
         
     | 
| 
       368 
360 
     | 
    
         
             
                    self._excluded.discard(tHandle)
         
     | 
| 
       369 
361 
     | 
    
         
             
                    self._included.add(tHandle)
         
     | 
| 
       370 
362 
     | 
    
         
             
                    self._changed = True
         
     | 
| 
       371 
     | 
    
         
            -
                    return
         
     | 
| 
       372 
363 
     | 
    
         | 
| 
       373 
364 
     | 
    
         
             
                def setExcluded(self, tHandle: str) -> None:
         
     | 
| 
       374 
365 
     | 
    
         
             
                    """Set an item as explicitly excluded."""
         
     | 
| 
       375 
366 
     | 
    
         
             
                    self._excluded.add(tHandle)
         
     | 
| 
       376 
367 
     | 
    
         
             
                    self._included.discard(tHandle)
         
     | 
| 
       377 
368 
     | 
    
         
             
                    self._changed = True
         
     | 
| 
       378 
     | 
    
         
            -
                    return
         
     | 
| 
       379 
369 
     | 
    
         | 
| 
       380 
370 
     | 
    
         
             
                def setAllowRoot(self, tHandle: str, state: bool) -> None:
         
     | 
| 
       381 
371 
     | 
    
         
             
                    """Set a specific root folder as allowed or not."""
         
     | 
| 
         @@ -385,14 +375,12 @@ class BuildSettings: 
     | 
|
| 
       385 
375 
     | 
    
         
             
                    elif state is False:
         
     | 
| 
       386 
376 
     | 
    
         
             
                        self._skipRoot.add(tHandle)
         
     | 
| 
       387 
377 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       388 
     | 
    
         
            -
                    return
         
     | 
| 
       389 
378 
     | 
    
         | 
| 
       390 
379 
     | 
    
         
             
                def setValue(self, key: str, value: T_BuildValue) -> None:
         
     | 
| 
       391 
380 
     | 
    
         
             
                    """Set a specific value for a build setting."""
         
     | 
| 
       392 
381 
     | 
    
         
             
                    if (d := SETTINGS_TEMPLATE.get(key)) and len(d) == 2 and isinstance(value, d[0]):
         
     | 
| 
       393 
382 
     | 
    
         
             
                        self._changed |= (value != self._settings[key])
         
     | 
| 
       394 
383 
     | 
    
         
             
                        self._settings[key] = value
         
     | 
| 
       395 
     | 
    
         
            -
                    return
         
     | 
| 
       396 
384 
     | 
    
         | 
| 
       397 
385 
     | 
    
         
             
                ##
         
     | 
| 
       398 
386 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -463,7 +451,6 @@ class BuildSettings: 
     | 
|
| 
       463 
451 
     | 
    
         
             
                    called when the changes have been safely saved or passed on.
         
     | 
| 
       464 
452 
     | 
    
         
             
                    """
         
     | 
| 
       465 
453 
     | 
    
         
             
                    self._changed = False
         
     | 
| 
       466 
     | 
    
         
            -
                    return
         
     | 
| 
       467 
454 
     | 
    
         | 
| 
       468 
455 
     | 
    
         
             
                def pack(self) -> dict:
         
     | 
| 
       469 
456 
     | 
    
         
             
                    """Pack all content into a JSON compatible dictionary."""
         
     | 
| 
         @@ -516,8 +503,6 @@ class BuildSettings: 
     | 
|
| 
       516 
503 
     | 
    
         | 
| 
       517 
504 
     | 
    
         
             
                    self._changed = False
         
     | 
| 
       518 
505 
     | 
    
         | 
| 
       519 
     | 
    
         
            -
                    return
         
     | 
| 
       520 
     | 
    
         
            -
             
     | 
| 
       521 
506 
     | 
    
         
             
                @classmethod
         
     | 
| 
       522 
507 
     | 
    
         
             
                def duplicate(cls, source: BuildSettings) -> BuildSettings:
         
     | 
| 
       523 
508 
     | 
    
         
             
                    """Make a copy of another build."""
         
     | 
| 
         @@ -529,7 +514,7 @@ class BuildSettings: 
     | 
|
| 
       529 
514 
     | 
    
         | 
| 
       530 
515 
     | 
    
         | 
| 
       531 
516 
     | 
    
         
             
            class BuildCollection:
         
     | 
| 
       532 
     | 
    
         
            -
                """Core: Build Collection Class
         
     | 
| 
      
 517 
     | 
    
         
            +
                """Core: Build Collection Class.
         
     | 
| 
       533 
518 
     | 
    
         | 
| 
       534 
519 
     | 
    
         
             
                This object holds all the build setting objects defined by the given
         
     | 
| 
       535 
520 
     | 
    
         
             
                project. The build settings are saved as a single JSON file in the
         
     | 
| 
         @@ -542,7 +527,6 @@ class BuildCollection: 
     | 
|
| 
       542 
527 
     | 
    
         
             
                    self._defaultBuild = ""
         
     | 
| 
       543 
528 
     | 
    
         
             
                    self._builds: dict[str, BuildSettings] = {}
         
     | 
| 
       544 
529 
     | 
    
         
             
                    self._loadCollection()
         
     | 
| 
       545 
     | 
    
         
            -
                    return
         
     | 
| 
       546 
530 
     | 
    
         | 
| 
       547 
531 
     | 
    
         
             
                def __len__(self) -> int:
         
     | 
| 
       548 
532 
     | 
    
         
             
                    """Return the number of builds."""
         
     | 
| 
         @@ -581,21 +565,18 @@ class BuildCollection: 
     | 
|
| 
       581 
565 
     | 
    
         
             
                            build.setOrder(i)
         
     | 
| 
       582 
566 
     | 
    
         
             
                    self._lastBuild = lastBuild
         
     | 
| 
       583 
567 
     | 
    
         
             
                    self._saveCollection()
         
     | 
| 
       584 
     | 
    
         
            -
                    return
         
     | 
| 
       585 
568 
     | 
    
         | 
| 
       586 
569 
     | 
    
         
             
                def setDefaultBuild(self, buildID: str) -> None:
         
     | 
| 
       587 
570 
     | 
    
         
             
                    """Set the default build id."""
         
     | 
| 
       588 
571 
     | 
    
         
             
                    if buildID != self._defaultBuild:
         
     | 
| 
       589 
572 
     | 
    
         
             
                        self._defaultBuild = buildID
         
     | 
| 
       590 
573 
     | 
    
         
             
                        self._saveCollection()
         
     | 
| 
       591 
     | 
    
         
            -
                    return
         
     | 
| 
       592 
574 
     | 
    
         | 
| 
       593 
575 
     | 
    
         
             
                def setBuild(self, build: BuildSettings) -> None:
         
     | 
| 
       594 
576 
     | 
    
         
             
                    """Set build settings data in the collection."""
         
     | 
| 
       595 
577 
     | 
    
         
             
                    if isinstance(build, BuildSettings):
         
     | 
| 
       596 
578 
     | 
    
         
             
                        self._builds[build.buildID] = build
         
     | 
| 
       597 
579 
     | 
    
         
             
                        self._saveCollection()
         
     | 
| 
       598 
     | 
    
         
            -
                    return
         
     | 
| 
       599 
580 
     | 
    
         | 
| 
       600 
581 
     | 
    
         
             
                ##
         
     | 
| 
       601 
582 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -605,7 +586,6 @@ class BuildCollection: 
     | 
|
| 
       605 
586 
     | 
    
         
             
                    """Remove a build from the collection."""
         
     | 
| 
       606 
587 
     | 
    
         
             
                    self._builds.pop(buildID, None)
         
     | 
| 
       607 
588 
     | 
    
         
             
                    self._saveCollection()
         
     | 
| 
       608 
     | 
    
         
            -
                    return
         
     | 
| 
       609 
589 
     | 
    
         | 
| 
       610 
590 
     | 
    
         
             
                def builds(self) -> Iterable[tuple[str, str]]:
         
     | 
| 
       611 
591 
     | 
    
         
             
                    """Iterate over all available builds."""
         
     | 
    
        novelwriter/core/coretools.py
    CHANGED
    
    | 
         @@ -23,7 +23,7 @@ General Public License for more details. 
     | 
|
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       25 
25 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       26 
     | 
    
         
            -
            """
         
     | 
| 
      
 26 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       27 
27 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            import logging
         
     | 
| 
         @@ -52,7 +52,9 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         
             
            class DocMerger:
         
     | 
| 
       55 
     | 
    
         
            -
                """ 
     | 
| 
      
 55 
     | 
    
         
            +
                """Tool: Merge Documents.
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                Document tool for merging a set of documents into a single new
         
     | 
| 
       56 
58 
     | 
    
         
             
                document. The parameters are defined by the user using the
         
     | 
| 
       57 
59 
     | 
    
         
             
                GuiDocMerge dialog.
         
     | 
| 
       58 
60 
     | 
    
         
             
                """
         
     | 
| 
         @@ -62,7 +64,6 @@ class DocMerger: 
     | 
|
| 
       62 
64 
     | 
    
         
             
                    self._error = ""
         
     | 
| 
       63 
65 
     | 
    
         
             
                    self._target = None
         
     | 
| 
       64 
66 
     | 
    
         
             
                    self._text = []
         
     | 
| 
       65 
     | 
    
         
            -
                    return
         
     | 
| 
       66 
67 
     | 
    
         | 
| 
       67 
68 
     | 
    
         
             
                @property
         
     | 
| 
       68 
69 
     | 
    
         
             
                def targetHandle(self) -> str | None:
         
     | 
| 
         @@ -85,7 +86,6 @@ class DocMerger: 
     | 
|
| 
       85 
86 
     | 
    
         
             
                    """
         
     | 
| 
       86 
87 
     | 
    
         
             
                    self._target = self._project.tree[tHandle]
         
     | 
| 
       87 
88 
     | 
    
         
             
                    self._text = []
         
     | 
| 
       88 
     | 
    
         
            -
                    return
         
     | 
| 
       89 
89 
     | 
    
         | 
| 
       90 
90 
     | 
    
         
             
                def newTargetDoc(self, sHandle: str, label: str) -> None:
         
     | 
| 
       91 
91 
     | 
    
         
             
                    """Create a brand new target document based on a source handle
         
     | 
| 
         @@ -101,7 +101,6 @@ class DocMerger: 
     | 
|
| 
       101 
101 
     | 
    
         
             
                            nwItem.notifyToRefresh()
         
     | 
| 
       102 
102 
     | 
    
         
             
                            self._target = nwItem
         
     | 
| 
       103 
103 
     | 
    
         
             
                            self._text = []
         
     | 
| 
       104 
     | 
    
         
            -
                    return
         
     | 
| 
       105 
104 
     | 
    
         | 
| 
       106 
105 
     | 
    
         
             
                def appendText(self, sHandle: str, addComment: bool, cmtPrefix: str) -> None:
         
     | 
| 
       107 
106 
     | 
    
         
             
                    """Append text from an existing document to the text buffer."""
         
     | 
| 
         @@ -112,7 +111,6 @@ class DocMerger: 
     | 
|
| 
       112 
111 
     | 
    
         
             
                            status, _ = item.getImportStatus()
         
     | 
| 
       113 
112 
     | 
    
         
             
                            text = f"% {cmtPrefix} {info}: {item.itemName} [{status}]\n\n{text}"
         
     | 
| 
       114 
113 
     | 
    
         
             
                        self._text.append(text)
         
     | 
| 
       115 
     | 
    
         
            -
                    return
         
     | 
| 
       116 
114 
     | 
    
         | 
| 
       117 
115 
     | 
    
         
             
                def writeTargetDoc(self) -> bool:
         
     | 
| 
       118 
116 
     | 
    
         
             
                    """Write the accumulated text into the designated target
         
     | 
| 
         @@ -158,7 +156,8 @@ class DocSplitter: 
     | 
|
| 
       158 
156 
     | 
    
         
             
                        self._srcHandle = sHandle
         
     | 
| 
       159 
157 
     | 
    
         
             
                        self._srcItem = srcItem
         
     | 
| 
       160 
158 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
      
 159 
     | 
    
         
            +
                def __len__(self) -> int:
         
     | 
| 
      
 160 
     | 
    
         
            +
                    return len(self._rawData)
         
     | 
| 
       162 
161 
     | 
    
         | 
| 
       163 
162 
     | 
    
         
             
                ##
         
     | 
| 
       164 
163 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -174,7 +173,6 @@ class DocSplitter: 
     | 
|
| 
       174 
173 
     | 
    
         
             
                    """
         
     | 
| 
       175 
174 
     | 
    
         
             
                    self._parHandle = pHandle
         
     | 
| 
       176 
175 
     | 
    
         
             
                    self._inFolder = False
         
     | 
| 
       177 
     | 
    
         
            -
                    return
         
     | 
| 
       178 
176 
     | 
    
         | 
| 
       179 
177 
     | 
    
         
             
                def newParentFolder(self, pHandle: str, folderLabel: str) -> None:
         
     | 
| 
       180 
178 
     | 
    
         
             
                    """Create a new folder that will be the top level parent item
         
     | 
| 
         @@ -188,7 +186,6 @@ class DocSplitter: 
     | 
|
| 
       188 
186 
     | 
    
         
             
                            nwItem.notifyToRefresh()
         
     | 
| 
       189 
187 
     | 
    
         
             
                        self._parHandle = nHandle
         
     | 
| 
       190 
188 
     | 
    
         
             
                        self._inFolder = True
         
     | 
| 
       191 
     | 
    
         
            -
                    return
         
     | 
| 
       192 
189 
     | 
    
         | 
| 
       193 
190 
     | 
    
         
             
                def splitDocument(self, splitData: list, splitText: list[str]) -> None:
         
     | 
| 
       194 
191 
     | 
    
         
             
                    """Loop through the split data record and perform the split job
         
     | 
| 
         @@ -200,12 +197,9 @@ class DocSplitter: 
     | 
|
| 
       200 
197 
     | 
    
         
             
                        chunk = buffer[lineNo:]
         
     | 
| 
       201 
198 
     | 
    
         
             
                        buffer = buffer[:lineNo]
         
     | 
| 
       202 
199 
     | 
    
         
             
                        self._rawData.insert(0, (chunk, hLevel, hLabel))
         
     | 
| 
       203 
     | 
    
         
            -
                    return
         
     | 
| 
       204 
200 
     | 
    
         | 
| 
       205 
201 
     | 
    
         
             
                def writeDocuments(self, docHierarchy: bool) -> Iterable[bool]:
         
     | 
| 
       206 
     | 
    
         
            -
                    """ 
     | 
| 
       207 
     | 
    
         
            -
                    return its new handle, parent handle, and sibling handle.
         
     | 
| 
       208 
     | 
    
         
            -
                    """
         
     | 
| 
      
 202 
     | 
    
         
            +
                    """Write each document in the buffer and yield if successful."""
         
     | 
| 
       209 
203 
     | 
    
         
             
                    if self._srcHandle and self._srcItem and self._parHandle:
         
     | 
| 
       210 
204 
     | 
    
         
             
                        pHandle = self._parHandle
         
     | 
| 
       211 
205 
     | 
    
         
             
                        hHandle = [self._parHandle, None, None, None, None]
         
     | 
| 
         @@ -256,7 +250,6 @@ class DocDuplicator: 
     | 
|
| 
       256 
250 
     | 
    
         | 
| 
       257 
251 
     | 
    
         
             
                def __init__(self, project: NWProject) -> None:
         
     | 
| 
       258 
252 
     | 
    
         
             
                    self._project = project
         
     | 
| 
       259 
     | 
    
         
            -
                    return
         
     | 
| 
       260 
253 
     | 
    
         | 
| 
       261 
254 
     | 
    
         
             
                ##
         
     | 
| 
       262 
255 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -270,7 +263,9 @@ class DocDuplicator: 
     | 
|
| 
       270 
263 
     | 
    
         
             
                    after = True
         
     | 
| 
       271 
264 
     | 
    
         
             
                    if items:
         
     | 
| 
       272 
265 
     | 
    
         
             
                        hMap: dict[str, str | None] = {t: None for t in items}
         
     | 
| 
      
 266 
     | 
    
         
            +
                        SHARED.initMainProgress(len(items))
         
     | 
| 
       273 
267 
     | 
    
         
             
                        for tHandle in items:
         
     | 
| 
      
 268 
     | 
    
         
            +
                            SHARED.incMainProgress()
         
     | 
| 
       274 
269 
     | 
    
         
             
                            if oldItem := self._project.tree[tHandle]:
         
     | 
| 
       275 
270 
     | 
    
         
             
                                pHandle = hMap.get(oldItem.itemParent or "") or oldItem.itemParent
         
     | 
| 
       276 
271 
     | 
    
         
             
                                if newItem := self._project.tree.duplicate(tHandle, pHandle, after):
         
     | 
| 
         @@ -282,17 +277,21 @@ class DocDuplicator: 
     | 
|
| 
       282 
277 
     | 
    
         
             
                                after = False
         
     | 
| 
       283 
278 
     | 
    
         
             
                            else:
         
     | 
| 
       284 
279 
     | 
    
         
             
                                break
         
     | 
| 
      
 280 
     | 
    
         
            +
                        SHARED.clearMainProgress()
         
     | 
| 
       285 
281 
     | 
    
         
             
                    return result
         
     | 
| 
       286 
282 
     | 
    
         | 
| 
       287 
283 
     | 
    
         | 
| 
       288 
284 
     | 
    
         
             
            class DocSearch:
         
     | 
| 
      
 285 
     | 
    
         
            +
                """Tool: Search Documents.
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
                A global document search class.
         
     | 
| 
      
 288 
     | 
    
         
            +
                """
         
     | 
| 
       289 
289 
     | 
    
         | 
| 
       290 
290 
     | 
    
         
             
                def __init__(self) -> None:
         
     | 
| 
       291 
291 
     | 
    
         
             
                    self._regEx = re.compile(r"")
         
     | 
| 
       292 
     | 
    
         
            -
                    self._opts = re. 
     | 
| 
      
 292 
     | 
    
         
            +
                    self._opts = re.IGNORECASE
         
     | 
| 
       293 
293 
     | 
    
         
             
                    self._words = False
         
     | 
| 
       294 
294 
     | 
    
         
             
                    self._escape = True
         
     | 
| 
       295 
     | 
    
         
            -
                    return
         
     | 
| 
       296 
295 
     | 
    
         | 
| 
       297 
296 
     | 
    
         
             
                ##
         
     | 
| 
       298 
297 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -300,32 +299,30 @@ class DocSearch: 
     | 
|
| 
       300 
299 
     | 
    
         | 
| 
       301 
300 
     | 
    
         
             
                def setCaseSensitive(self, state: bool) -> None:
         
     | 
| 
       302 
301 
     | 
    
         
             
                    """Set the case sensitive search flag."""
         
     | 
| 
       303 
     | 
    
         
            -
                    self._opts = re. 
     | 
| 
       304 
     | 
    
         
            -
                    if not state:
         
     | 
| 
       305 
     | 
    
         
            -
                        self._opts |= re.IGNORECASE
         
     | 
| 
       306 
     | 
    
         
            -
                    return
         
     | 
| 
      
 302 
     | 
    
         
            +
                    self._opts = 0 if state else re.IGNORECASE
         
     | 
| 
       307 
303 
     | 
    
         | 
| 
       308 
304 
     | 
    
         
             
                def setWholeWords(self, state: bool) -> None:
         
     | 
| 
       309 
305 
     | 
    
         
             
                    """Set the whole words search flag."""
         
     | 
| 
       310 
306 
     | 
    
         
             
                    self._words = state
         
     | 
| 
       311 
     | 
    
         
            -
                    return
         
     | 
| 
       312 
307 
     | 
    
         | 
| 
       313 
308 
     | 
    
         
             
                def setUserRegEx(self, state: bool) -> None:
         
     | 
| 
       314 
309 
     | 
    
         
             
                    """Set the escape flag to the opposite state."""
         
     | 
| 
       315 
310 
     | 
    
         
             
                    self._escape = not state
         
     | 
| 
       316 
     | 
    
         
            -
                    return
         
     | 
| 
       317 
311 
     | 
    
         | 
| 
       318 
312 
     | 
    
         
             
                def iterSearch(
         
     | 
| 
       319 
313 
     | 
    
         
             
                    self, project: NWProject, search: str
         
     | 
| 
       320 
314 
     | 
    
         
             
                ) -> Iterable[tuple[NWItem, list[tuple[int, int, str]], bool]]:
         
     | 
| 
       321 
     | 
    
         
            -
                    """ 
     | 
| 
      
 315 
     | 
    
         
            +
                    """Iterate through documents in a project and apply search."""
         
     | 
| 
       322 
316 
     | 
    
         
             
                    self._regEx = re.compile(self._buildPattern(search), self._opts)
         
     | 
| 
       323 
317 
     | 
    
         
             
                    logger.debug("Searching with pattern '%s'", self._regEx.pattern)
         
     | 
| 
       324 
318 
     | 
    
         
             
                    storage = project.storage
         
     | 
| 
      
 319 
     | 
    
         
            +
                    SHARED.initMainProgress(len(project.tree))
         
     | 
| 
       325 
320 
     | 
    
         
             
                    for item in project.tree:
         
     | 
| 
      
 321 
     | 
    
         
            +
                        SHARED.incMainProgress()
         
     | 
| 
       326 
322 
     | 
    
         
             
                        if item.isFileType():
         
     | 
| 
       327 
323 
     | 
    
         
             
                            results, capped = self.searchText(storage.getDocumentText(item.itemHandle))
         
     | 
| 
       328 
324 
     | 
    
         
             
                            yield item, results, capped
         
     | 
| 
      
 325 
     | 
    
         
            +
                    SHARED.clearMainProgress()
         
     | 
| 
       329 
326 
     | 
    
         
             
                    return
         
     | 
| 
       330 
327 
     | 
    
         | 
| 
       331 
328 
     | 
    
         
             
                def searchText(self, text: str) -> tuple[list[tuple[int, int, str]], bool]:
         
     | 
| 
         @@ -368,7 +365,6 @@ class ProjectBuilder: 
     | 
|
| 
       368 
365 
     | 
    
         
             
                def __init__(self) -> None:
         
     | 
| 
       369 
366 
     | 
    
         
             
                    self._path = None
         
     | 
| 
       370 
367 
     | 
    
         
             
                    self.tr = partial(QCoreApplication.translate, "ProjectBuilder")
         
     | 
| 
       371 
     | 
    
         
            -
                    return
         
     | 
| 
       372 
368 
     | 
    
         | 
| 
       373 
369 
     | 
    
         
             
                @property
         
     | 
| 
       374 
370 
     | 
    
         
             
                def projPath(self) -> Path | None:
         
     | 
| 
         @@ -609,6 +605,6 @@ class ProjectBuilder: 
     | 
|
| 
       609 
605 
     | 
    
         
             
                    project.data.setSaveCount(0)
         
     | 
| 
       610 
606 
     | 
    
         
             
                    project.data.setAutoCount(0)
         
     | 
| 
       611 
607 
     | 
    
         
             
                    project.data.setEditTime(0)
         
     | 
| 
      
 608 
     | 
    
         
            +
                    project.index.rebuild()
         
     | 
| 
       612 
609 
     | 
    
         
             
                    project.saveProject()
         
     | 
| 
       613 
610 
     | 
    
         
             
                    project.closeProject()
         
     | 
| 
       614 
     | 
    
         
            -
                    return
         
     | 
    
        novelwriter/core/docbuild.py
    CHANGED
    
    | 
         @@ -20,7 +20,7 @@ General Public License for more details. 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
22 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
      
 23 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       24 
24 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            import logging
         
     | 
| 
         @@ -53,7 +53,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
            class NWBuildDocument:
         
     | 
| 
       56 
     | 
    
         
            -
                """Core: Manuscript Document Build Class
         
     | 
| 
      
 56 
     | 
    
         
            +
                """Core: Manuscript Document Build Class.
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
       58 
58 
     | 
    
         
             
                This is the core tool that assembles a project and outputs a
         
     | 
| 
       59 
59 
     | 
    
         
             
                manuscript, based on a build definition object (BuildSettings).
         
     | 
| 
         @@ -72,7 +72,6 @@ class NWBuildDocument: 
     | 
|
| 
       72 
72 
     | 
    
         
             
                    self._cache = None
         
     | 
| 
       73 
73 
     | 
    
         
             
                    self._count = False
         
     | 
| 
       74 
74 
     | 
    
         
             
                    self._outline = False
         
     | 
| 
       75 
     | 
    
         
            -
                    return
         
     | 
| 
       76 
75 
     | 
    
         | 
| 
       77 
76 
     | 
    
         
             
                ##
         
     | 
| 
       78 
77 
     | 
    
         
             
                #  Properties
         
     | 
| 
         @@ -106,7 +105,6 @@ class NWBuildDocument: 
     | 
|
| 
       106 
105 
     | 
    
         
             
                def addDocument(self, tHandle: str) -> None:
         
     | 
| 
       107 
106 
     | 
    
         
             
                    """Add a document to the build queue manually."""
         
     | 
| 
       108 
107 
     | 
    
         
             
                    self._queue.append(tHandle)
         
     | 
| 
       109 
     | 
    
         
            -
                    return
         
     | 
| 
       110 
108 
     | 
    
         | 
| 
       111 
109 
     | 
    
         
             
                def queueAll(self) -> None:
         
     | 
| 
       112 
110 
     | 
    
         
             
                    """Queue all document as defined by the build settings."""
         
     | 
| 
         @@ -115,7 +113,6 @@ class NWBuildDocument: 
     | 
|
| 
       115 
113 
     | 
    
         
             
                    for item in self._project.tree:
         
     | 
| 
       116 
114 
     | 
    
         
             
                        if filtered.get(item.itemHandle, False):
         
     | 
| 
       117 
115 
     | 
    
         
             
                            self._queue.append(item.itemHandle)
         
     | 
| 
       118 
     | 
    
         
            -
                    return
         
     | 
| 
       119 
116 
     | 
    
         | 
| 
       120 
117 
     | 
    
         
             
                def iterBuildPreview(self, newPage: bool) -> Iterable[tuple[int, bool]]:
         
     | 
| 
       121 
118 
     | 
    
         
             
                    """Build a preview QTextDocument."""
         
     | 
| 
         @@ -131,7 +128,7 @@ class NWBuildDocument: 
     | 
|
| 
       131 
128 
     | 
    
         
             
                    return
         
     | 
| 
       132 
129 
     | 
    
         | 
| 
       133 
130 
     | 
    
         
             
                def iterBuildDocument(self, path: Path, bFormat: nwBuildFmt) -> Iterable[tuple[int, bool]]:
         
     | 
| 
       134 
     | 
    
         
            -
                    """ 
     | 
| 
      
 131 
     | 
    
         
            +
                    """Select a builder based on format."""
         
     | 
| 
       135 
132 
     | 
    
         
             
                    self._error = None
         
     | 
| 
       136 
133 
     | 
    
         
             
                    self._cache = None
         
     | 
| 
       137 
134 
     | 
    
         | 
| 
         @@ -341,12 +338,10 @@ class NWBuildDocument: 
     | 
|
| 
       341 
338 
     | 
    
         
             
                            scale*self._build.getFloat("format.rightMargin"),
         
     | 
| 
       342 
339 
     | 
    
         
             
                        )
         
     | 
| 
       343 
340 
     | 
    
         | 
| 
       344 
     | 
    
         
            -
                     
     | 
| 
      
 341 
     | 
    
         
            +
                    return self._build.buildItemFilter(
         
     | 
| 
       345 
342 
     | 
    
         
             
                        self._project, withRoots=self._build.getBool("text.addNoteHeadings")
         
     | 
| 
       346 
343 
     | 
    
         
             
                    )
         
     | 
| 
       347 
344 
     | 
    
         | 
| 
       348 
     | 
    
         
            -
                    return filtered
         
     | 
| 
       349 
     | 
    
         
            -
             
     | 
| 
       350 
345 
     | 
    
         
             
                def _doBuild(self, bldObj: Tokenizer, tHandle: str, convert: bool = True) -> bool:
         
     | 
| 
       351 
346 
     | 
    
         
             
                    """Build a single document and add it to the build object."""
         
     | 
| 
       352 
347 
     | 
    
         
             
                    tItem = self._project.tree[tHandle]
         
     | 
    
        novelwriter/core/document.py
    CHANGED
    
    | 
         @@ -20,7 +20,7 @@ General Public License for more details. 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
22 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
      
 23 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       24 
24 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            import hashlib
         
     | 
| 
         @@ -42,7 +42,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
            class NWDocument:
         
     | 
| 
       45 
     | 
    
         
            -
                """Core: Document Class
         
     | 
| 
      
 45 
     | 
    
         
            +
                """Core: Document Class.
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
       47 
47 
     | 
    
         
             
                A Class wrapping a single novelWriter document file. It represents
         
     | 
| 
       48 
48 
     | 
    
         
             
                a project item of nwItemType FILE. The file is not guaranteed to
         
     | 
| 
         @@ -68,8 +68,6 @@ class NWDocument: 
     | 
|
| 
       68 
68 
     | 
    
         
             
                    if self._handle is not None:
         
     | 
| 
       69 
69 
     | 
    
         
             
                        self._item = self._project.tree[tHandle]
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
                    return
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
71 
     | 
    
         
             
                def __repr__(self) -> str:
         
     | 
| 
       74 
72 
     | 
    
         
             
                    return f"<NWDocument handle={self._handle}>"
         
     | 
| 
       75 
73 
     | 
    
         | 
| 
         @@ -357,5 +355,3 @@ class NWDocument: 
     | 
|
| 
       357 
355 
     | 
    
         | 
| 
       358 
356 
     | 
    
         
             
                    else:
         
     | 
| 
       359 
357 
     | 
    
         
             
                        logger.debug("Unknown meta data: '%s'", metaLine.strip())
         
     | 
| 
       360 
     | 
    
         
            -
             
     | 
| 
       361 
     | 
    
         
            -
                    return
         
     |