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
 
    
        novelwriter/formats/toodt.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
         
     | 
| 
         @@ -40,7 +40,7 @@ from novelwriter import __version__ 
     | 
|
| 
       40 
40 
     | 
    
         
             
            from novelwriter.common import xmlElement, xmlIndent, xmlSubElem
         
     | 
| 
       41 
41 
     | 
    
         
             
            from novelwriter.constants import nwHeadFmt, nwStyles
         
     | 
| 
       42 
42 
     | 
    
         
             
            from novelwriter.formats.shared import BlockFmt, BlockTyp, TextFmt, stripEscape
         
     | 
| 
       43 
     | 
    
         
            -
            from novelwriter.formats.tokenizer import Tokenizer
         
     | 
| 
      
 43 
     | 
    
         
            +
            from novelwriter.formats.tokenizer import COMMENT_BLOCKS, Tokenizer
         
     | 
| 
       44 
44 
     | 
    
         
             
            from novelwriter.types import FONT_STYLE, QtHexRgb
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
            if TYPE_CHECKING:
         
     | 
| 
         @@ -128,7 +128,7 @@ FONT_WEIGHT_MAP = {"400": "normal", "700": "bold"} 
     | 
|
| 
       128 
128 
     | 
    
         | 
| 
       129 
129 
     | 
    
         | 
| 
       130 
130 
     | 
    
         
             
            class ToOdt(Tokenizer):
         
     | 
| 
       131 
     | 
    
         
            -
                """Core: Open Document Writer
         
     | 
| 
      
 131 
     | 
    
         
            +
                """Core: Open Document Writer.
         
     | 
| 
       132 
132 
     | 
    
         | 
| 
       133 
133 
     | 
    
         
             
                Extend the Tokenizer class to writer Open Document files. The output
         
     | 
| 
       134 
134 
     | 
    
         
             
                should conform to the 1.3 Extended standard.
         
     | 
| 
         @@ -189,8 +189,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       189 
189 
     | 
    
         
             
                    self._mDocLeft   = "2.000cm"
         
     | 
| 
       190 
190 
     | 
    
         
             
                    self._mDocRight  = "2.000cm"
         
     | 
| 
       191 
191 
     | 
    
         | 
| 
       192 
     | 
    
         
            -
                    return
         
     | 
| 
       193 
     | 
    
         
            -
             
     | 
| 
       194 
192 
     | 
    
         
             
                ##
         
     | 
| 
       195 
193 
     | 
    
         
             
                #  Setters
         
     | 
| 
       196 
194 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -205,20 +203,18 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       205 
203 
     | 
    
         
             
                    self._mDocBtm    = f"{bottom/10.0:.3f}cm"
         
     | 
| 
       206 
204 
     | 
    
         
             
                    self._mDocLeft   = f"{left/10.0:.3f}cm"
         
     | 
| 
       207 
205 
     | 
    
         
             
                    self._mDocRight  = f"{right/10.0:.3f}cm"
         
     | 
| 
       208 
     | 
    
         
            -
                    return
         
     | 
| 
       209 
206 
     | 
    
         | 
| 
       210 
207 
     | 
    
         
             
                def setHeaderFormat(self, value: str, offset: int) -> None:
         
     | 
| 
       211 
208 
     | 
    
         
             
                    """Set the document header format."""
         
     | 
| 
       212 
209 
     | 
    
         
             
                    self._headerFormat = value.strip()
         
     | 
| 
       213 
210 
     | 
    
         
             
                    self._pageOffset = offset
         
     | 
| 
       214 
     | 
    
         
            -
                    return
         
     | 
| 
       215 
211 
     | 
    
         | 
| 
       216 
212 
     | 
    
         
             
                ##
         
     | 
| 
       217 
213 
     | 
    
         
             
                #  Class Methods
         
     | 
| 
       218 
214 
     | 
    
         
             
                ##
         
     | 
| 
       219 
215 
     | 
    
         | 
| 
       220 
216 
     | 
    
         
             
                def initDocument(self) -> None:
         
     | 
| 
       221 
     | 
    
         
            -
                    """ 
     | 
| 
      
 217 
     | 
    
         
            +
                    """Initialise a new open document XML tree."""
         
     | 
| 
       222 
218 
     | 
    
         
             
                    super().initDocument()
         
     | 
| 
       223 
219 
     | 
    
         | 
| 
       224 
220 
     | 
    
         
             
                    # Initialise Variables
         
     | 
| 
         @@ -325,8 +321,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       325 
321 
     | 
    
         
             
                    self._useableStyles()
         
     | 
| 
       326 
322 
     | 
    
         
             
                    self._writeHeader()
         
     | 
| 
       327 
323 
     | 
    
         | 
| 
       328 
     | 
    
         
            -
                    return
         
     | 
| 
       329 
     | 
    
         
            -
             
     | 
| 
       330 
324 
     | 
    
         
             
                def doConvert(self) -> None:
         
     | 
| 
       331 
325 
     | 
    
         
             
                    """Convert the list of text tokens into XML elements."""
         
     | 
| 
       332 
326 
     | 
    
         
             
                    xText = self._xText
         
     | 
| 
         @@ -389,14 +383,12 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       389 
383 
     | 
    
         
             
                        elif tType == BlockTyp.SKIP:
         
     | 
| 
       390 
384 
     | 
    
         
             
                            self._addTextPar(xText, S_TEXT, oStyle, "")
         
     | 
| 
       391 
385 
     | 
    
         | 
| 
       392 
     | 
    
         
            -
                        elif tType  
     | 
| 
      
 386 
     | 
    
         
            +
                        elif tType in COMMENT_BLOCKS:
         
     | 
| 
       393 
387 
     | 
    
         
             
                            self._addTextPar(xText, S_META, oStyle, tText, tFmt=tFormat)
         
     | 
| 
       394 
388 
     | 
    
         | 
| 
       395 
389 
     | 
    
         
             
                        elif tType == BlockTyp.KEYWORD:
         
     | 
| 
       396 
390 
     | 
    
         
             
                            self._addTextPar(xText, S_META, oStyle, tText, tFmt=tFormat)
         
     | 
| 
       397 
391 
     | 
    
         | 
| 
       398 
     | 
    
         
            -
                    return
         
     | 
| 
       399 
     | 
    
         
            -
             
     | 
| 
       400 
392 
     | 
    
         
             
                def closeDocument(self) -> None:
         
     | 
| 
       401 
393 
     | 
    
         
             
                    """Add additional collected information to the XML."""
         
     | 
| 
       402 
394 
     | 
    
         
             
                    for style in self._autoPara.values():
         
     | 
| 
         @@ -412,7 +404,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       412 
404 
     | 
    
         
             
                                _mkTag("text", "name"): f"Manuscript{key[:1].upper()}{key[1:]}",
         
     | 
| 
       413 
405 
     | 
    
         
             
                            })
         
     | 
| 
       414 
406 
     | 
    
         
             
                        self._xText.insert(0, xFields)
         
     | 
| 
       415 
     | 
    
         
            -
                    return
         
     | 
| 
       416 
407 
     | 
    
         | 
| 
       417 
408 
     | 
    
         
             
                def saveDocument(self, path: Path) -> None:
         
     | 
| 
       418 
409 
     | 
    
         
             
                    """Save the data to an .fodt or .odt file."""
         
     | 
| 
         @@ -456,8 +447,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       456 
447 
     | 
    
         | 
| 
       457 
448 
     | 
    
         
             
                    logger.info("Wrote file: %s", path)
         
     | 
| 
       458 
449 
     | 
    
         | 
| 
       459 
     | 
    
         
            -
                    return
         
     | 
| 
       460 
     | 
    
         
            -
             
     | 
| 
       461 
450 
     | 
    
         
             
                ##
         
     | 
| 
       462 
451 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
       463 
452 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -670,7 +659,7 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       670 
659 
     | 
    
         
             
                    return None
         
     | 
| 
       671 
660 
     | 
    
         | 
| 
       672 
661 
     | 
    
         
             
                def _emToCm(self, value: float) -> str:
         
     | 
| 
       673 
     | 
    
         
            -
                    """ 
     | 
| 
      
 662 
     | 
    
         
            +
                    """Convert an em value to centimetres."""
         
     | 
| 
       674 
663 
     | 
    
         
             
                    return f"{value*self._fontSize*2.54/72.0:.3f}cm"
         
     | 
| 
       675 
664 
     | 
    
         | 
| 
       676 
665 
     | 
    
         
             
                def _emToPt(self, scale: float) -> str:
         
     | 
| 
         @@ -705,8 +694,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       705 
694 
     | 
    
         
             
                        _mkTag("fo", "margin-bottom"): self._emToCm(0.5),
         
     | 
| 
       706 
695 
     | 
    
         
             
                    })
         
     | 
| 
       707 
696 
     | 
    
         | 
| 
       708 
     | 
    
         
            -
                    return
         
     | 
| 
       709 
     | 
    
         
            -
             
     | 
| 
       710 
697 
     | 
    
         
             
                def _defaultStyles(self) -> None:
         
     | 
| 
       711 
698 
     | 
    
         
             
                    """Set the default styles."""
         
     | 
| 
       712 
699 
     | 
    
         
             
                    hScale = self._scaleHeads
         
     | 
| 
         @@ -783,8 +770,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       783 
770 
     | 
    
         
             
                        _mkTag("number", "min-integer-digits"): "1",
         
     | 
| 
       784 
771 
     | 
    
         
             
                    })
         
     | 
| 
       785 
772 
     | 
    
         | 
| 
       786 
     | 
    
         
            -
                    return
         
     | 
| 
       787 
     | 
    
         
            -
             
     | 
| 
       788 
773 
     | 
    
         
             
                def _useableStyles(self) -> None:
         
     | 
| 
       789 
774 
     | 
    
         
             
                    """Set the usable styles."""
         
     | 
| 
       790 
775 
     | 
    
         
             
                    hScale = self._scaleHeads
         
     | 
| 
         @@ -954,8 +939,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       954 
939 
     | 
    
         
             
                    style.packXML(self._xStyl)
         
     | 
| 
       955 
940 
     | 
    
         
             
                    self._mainPara[style.name] = style
         
     | 
| 
       956 
941 
     | 
    
         | 
| 
       957 
     | 
    
         
            -
                    return
         
     | 
| 
       958 
     | 
    
         
            -
             
     | 
| 
       959 
942 
     | 
    
         
             
                def _writeHeader(self) -> None:
         
     | 
| 
       960 
943 
     | 
    
         
             
                    """Write the header elements."""
         
     | 
| 
       961 
944 
     | 
    
         
             
                    xPage = ET.SubElement(self._xMast, _mkTag("style", "master-page"), attrib={
         
     | 
| 
         @@ -993,8 +976,6 @@ class ToOdt(Tokenizer): 
     | 
|
| 
       993 
976 
     | 
    
         
             
                        _mkTag("text", "style-name"): "Header"
         
     | 
| 
       994 
977 
     | 
    
         
             
                    })
         
     | 
| 
       995 
978 
     | 
    
         | 
| 
       996 
     | 
    
         
            -
                    return
         
     | 
| 
       997 
     | 
    
         
            -
             
     | 
| 
       998 
979 
     | 
    
         | 
| 
       999 
980 
     | 
    
         
             
            # Auto-Style Classes
         
     | 
| 
       1000 
981 
     | 
    
         
             
            # ==================
         
     | 
| 
         @@ -1004,6 +985,7 @@ class ODTParagraphStyle: 
     | 
|
| 
       1004 
985 
     | 
    
         
             
                exporter. Only the used settings are exposed here to keep the class
         
     | 
| 
       1005 
986 
     | 
    
         
             
                minimal and fast.
         
     | 
| 
       1006 
987 
     | 
    
         
             
                """
         
     | 
| 
      
 988 
     | 
    
         
            +
             
     | 
| 
       1007 
989 
     | 
    
         
             
                VALID_ALIGN: Final[list[str]]  = ["start", "center", "end", "justify", "left", "right"]
         
     | 
| 
       1008 
990 
     | 
    
         
             
                VALID_BREAK: Final[list[str]]  = ["auto", "page", "even-page", "odd-page", "inherit"]
         
     | 
| 
       1009 
991 
     | 
    
         
             
                VALID_LEVEL: Final[list[str]]  = ["1", "2", "3", "4"]
         
     | 
| 
         @@ -1046,8 +1028,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1046 
1028 
     | 
    
         
             
                        "opacity":     ["loext", None],
         
     | 
| 
       1047 
1029 
     | 
    
         
             
                    }
         
     | 
| 
       1048 
1030 
     | 
    
         | 
| 
       1049 
     | 
    
         
            -
                    return
         
     | 
| 
       1050 
     | 
    
         
            -
             
     | 
| 
       1051 
1031 
     | 
    
         
             
                @property
         
     | 
| 
       1052 
1032 
     | 
    
         
             
                def name(self) -> str:
         
     | 
| 
       1053 
1033 
     | 
    
         
             
                    return self._name
         
     | 
| 
         @@ -1059,7 +1039,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1059 
1039 
     | 
    
         
             
                def setName(self, name: str) -> None:
         
     | 
| 
       1060 
1040 
     | 
    
         
             
                    """Set the paragraph style name."""
         
     | 
| 
       1061 
1041 
     | 
    
         
             
                    self._name = name
         
     | 
| 
       1062 
     | 
    
         
            -
                    return
         
     | 
| 
       1063 
1042 
     | 
    
         | 
| 
       1064 
1043 
     | 
    
         
             
                ##
         
     | 
| 
       1065 
1044 
     | 
    
         
             
                #  Attribute Setters
         
     | 
| 
         @@ -1068,17 +1047,14 @@ class ODTParagraphStyle: 
     | 
|
| 
       1068 
1047 
     | 
    
         
             
                def setDisplayName(self, value: str | None) -> None:
         
     | 
| 
       1069 
1048 
     | 
    
         
             
                    """Set style display name."""
         
     | 
| 
       1070 
1049 
     | 
    
         
             
                    self._mAttr["display-name"][1] = value
         
     | 
| 
       1071 
     | 
    
         
            -
                    return
         
     | 
| 
       1072 
1050 
     | 
    
         | 
| 
       1073 
1051 
     | 
    
         
             
                def setParentStyleName(self, value: str | None) -> None:
         
     | 
| 
       1074 
1052 
     | 
    
         
             
                    """Set parent style name."""
         
     | 
| 
       1075 
1053 
     | 
    
         
             
                    self._mAttr["parent-style-name"][1] = value
         
     | 
| 
       1076 
     | 
    
         
            -
                    return
         
     | 
| 
       1077 
1054 
     | 
    
         | 
| 
       1078 
1055 
     | 
    
         
             
                def setNextStyleName(self, value: str | None) -> None:
         
     | 
| 
       1079 
1056 
     | 
    
         
             
                    """Set next style name."""
         
     | 
| 
       1080 
1057 
     | 
    
         
             
                    self._mAttr["next-style-name"][1] = value
         
     | 
| 
       1081 
     | 
    
         
            -
                    return
         
     | 
| 
       1082 
1058 
     | 
    
         | 
| 
       1083 
1059 
     | 
    
         
             
                def setOutlineLevel(self, value: str | None) -> None:
         
     | 
| 
       1084 
1060 
     | 
    
         
             
                    """Set paragraph outline level."""
         
     | 
| 
         @@ -1086,7 +1062,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1086 
1062 
     | 
    
         
             
                        self._mAttr["default-outline-level"][1] = value
         
     | 
| 
       1087 
1063 
     | 
    
         
             
                    else:
         
     | 
| 
       1088 
1064 
     | 
    
         
             
                        self._mAttr["default-outline-level"][1] = None
         
     | 
| 
       1089 
     | 
    
         
            -
                    return
         
     | 
| 
       1090 
1065 
     | 
    
         | 
| 
       1091 
1066 
     | 
    
         
             
                def setClass(self, value: str | None) -> None:
         
     | 
| 
       1092 
1067 
     | 
    
         
             
                    """Set paragraph class."""
         
     | 
| 
         @@ -1094,7 +1069,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1094 
1069 
     | 
    
         
             
                        self._mAttr["class"][1] = value
         
     | 
| 
       1095 
1070 
     | 
    
         
             
                    else:
         
     | 
| 
       1096 
1071 
     | 
    
         
             
                        self._mAttr["class"][1] = None
         
     | 
| 
       1097 
     | 
    
         
            -
                    return
         
     | 
| 
       1098 
1072 
     | 
    
         | 
| 
       1099 
1073 
     | 
    
         
             
                ##
         
     | 
| 
       1100 
1074 
     | 
    
         
             
                #  Paragraph Setters
         
     | 
| 
         @@ -1103,32 +1077,26 @@ class ODTParagraphStyle: 
     | 
|
| 
       1103 
1077 
     | 
    
         
             
                def setMarginTop(self, value: str | None) -> None:
         
     | 
| 
       1104 
1078 
     | 
    
         
             
                    """Set paragraph top margin."""
         
     | 
| 
       1105 
1079 
     | 
    
         
             
                    self._pAttr["margin-top"][1] = value
         
     | 
| 
       1106 
     | 
    
         
            -
                    return
         
     | 
| 
       1107 
1080 
     | 
    
         | 
| 
       1108 
1081 
     | 
    
         
             
                def setMarginBottom(self, value: str | None) -> None:
         
     | 
| 
       1109 
1082 
     | 
    
         
             
                    """Set paragraph bottom margin."""
         
     | 
| 
       1110 
1083 
     | 
    
         
             
                    self._pAttr["margin-bottom"][1] = value
         
     | 
| 
       1111 
     | 
    
         
            -
                    return
         
     | 
| 
       1112 
1084 
     | 
    
         | 
| 
       1113 
1085 
     | 
    
         
             
                def setMarginLeft(self, value: str | None) -> None:
         
     | 
| 
       1114 
1086 
     | 
    
         
             
                    """Set paragraph left margin."""
         
     | 
| 
       1115 
1087 
     | 
    
         
             
                    self._pAttr["margin-left"][1] = value
         
     | 
| 
       1116 
     | 
    
         
            -
                    return
         
     | 
| 
       1117 
1088 
     | 
    
         | 
| 
       1118 
1089 
     | 
    
         
             
                def setMarginRight(self, value: str | None) -> None:
         
     | 
| 
       1119 
1090 
     | 
    
         
             
                    """Set paragraph right margin."""
         
     | 
| 
       1120 
1091 
     | 
    
         
             
                    self._pAttr["margin-right"][1] = value
         
     | 
| 
       1121 
     | 
    
         
            -
                    return
         
     | 
| 
       1122 
1092 
     | 
    
         | 
| 
       1123 
1093 
     | 
    
         
             
                def setTextIndent(self, value: str | None) -> None:
         
     | 
| 
       1124 
1094 
     | 
    
         
             
                    """Set text indentation."""
         
     | 
| 
       1125 
1095 
     | 
    
         
             
                    self._pAttr["text-indent"][1] = value
         
     | 
| 
       1126 
     | 
    
         
            -
                    return
         
     | 
| 
       1127 
1096 
     | 
    
         | 
| 
       1128 
1097 
     | 
    
         
             
                def setLineHeight(self, value: str | None) -> None:
         
     | 
| 
       1129 
1098 
     | 
    
         
             
                    """Set line height."""
         
     | 
| 
       1130 
1099 
     | 
    
         
             
                    self._pAttr["line-height"][1] = value
         
     | 
| 
       1131 
     | 
    
         
            -
                    return
         
     | 
| 
       1132 
1100 
     | 
    
         | 
| 
       1133 
1101 
     | 
    
         
             
                def setTextAlign(self, value: str | None) -> None:
         
     | 
| 
       1134 
1102 
     | 
    
         
             
                    """Set paragraph text alignment."""
         
     | 
| 
         @@ -1136,7 +1104,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1136 
1104 
     | 
    
         
             
                        self._pAttr["text-align"][1] = value
         
     | 
| 
       1137 
1105 
     | 
    
         
             
                    else:
         
     | 
| 
       1138 
1106 
     | 
    
         
             
                        self._pAttr["text-align"][1] = None
         
     | 
| 
       1139 
     | 
    
         
            -
                    return
         
     | 
| 
       1140 
1107 
     | 
    
         | 
| 
       1141 
1108 
     | 
    
         
             
                def setBreakBefore(self, value: str | None) -> None:
         
     | 
| 
       1142 
1109 
     | 
    
         
             
                    """Set page break before policy."""
         
     | 
| 
         @@ -1144,7 +1111,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1144 
1111 
     | 
    
         
             
                        self._pAttr["break-before"][1] = value
         
     | 
| 
       1145 
1112 
     | 
    
         
             
                    else:
         
     | 
| 
       1146 
1113 
     | 
    
         
             
                        self._pAttr["break-before"][1] = None
         
     | 
| 
       1147 
     | 
    
         
            -
                    return
         
     | 
| 
       1148 
1114 
     | 
    
         | 
| 
       1149 
1115 
     | 
    
         
             
                def setBreakAfter(self, value: str | None) -> None:
         
     | 
| 
       1150 
1116 
     | 
    
         
             
                    """Set page break after policy."""
         
     | 
| 
         @@ -1152,7 +1118,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1152 
1118 
     | 
    
         
             
                        self._pAttr["break-after"][1] = value
         
     | 
| 
       1153 
1119 
     | 
    
         
             
                    else:
         
     | 
| 
       1154 
1120 
     | 
    
         
             
                        self._pAttr["break-after"][1] = None
         
     | 
| 
       1155 
     | 
    
         
            -
                    return
         
     | 
| 
       1156 
1121 
     | 
    
         | 
| 
       1157 
1122 
     | 
    
         
             
                ##
         
     | 
| 
       1158 
1123 
     | 
    
         
             
                #  Text Setters
         
     | 
| 
         @@ -1161,17 +1126,14 @@ class ODTParagraphStyle: 
     | 
|
| 
       1161 
1126 
     | 
    
         
             
                def setFontName(self, value: str | None) -> None:
         
     | 
| 
       1162 
1127 
     | 
    
         
             
                    """Set font name."""
         
     | 
| 
       1163 
1128 
     | 
    
         
             
                    self._tAttr["font-name"][1] = value
         
     | 
| 
       1164 
     | 
    
         
            -
                    return
         
     | 
| 
       1165 
1129 
     | 
    
         | 
| 
       1166 
1130 
     | 
    
         
             
                def setFontFamily(self, value: str | None) -> None:
         
     | 
| 
       1167 
1131 
     | 
    
         
             
                    """Set font family."""
         
     | 
| 
       1168 
1132 
     | 
    
         
             
                    self._tAttr["font-family"][1] = value
         
     | 
| 
       1169 
     | 
    
         
            -
                    return
         
     | 
| 
       1170 
1133 
     | 
    
         | 
| 
       1171 
1134 
     | 
    
         
             
                def setFontSize(self, value: str | None) -> None:
         
     | 
| 
       1172 
1135 
     | 
    
         
             
                    """Set font size."""
         
     | 
| 
       1173 
1136 
     | 
    
         
             
                    self._tAttr["font-size"][1] = value
         
     | 
| 
       1174 
     | 
    
         
            -
                    return
         
     | 
| 
       1175 
1137 
     | 
    
         | 
| 
       1176 
1138 
     | 
    
         
             
                def setFontWeight(self, value: str | None) -> None:
         
     | 
| 
       1177 
1139 
     | 
    
         
             
                    """Set font weight."""
         
     | 
| 
         @@ -1179,7 +1141,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1179 
1141 
     | 
    
         
             
                        self._tAttr["font-weight"][1] = value
         
     | 
| 
       1180 
1142 
     | 
    
         
             
                    else:
         
     | 
| 
       1181 
1143 
     | 
    
         
             
                        self._tAttr["font-weight"][1] = None
         
     | 
| 
       1182 
     | 
    
         
            -
                    return
         
     | 
| 
       1183 
1144 
     | 
    
         | 
| 
       1184 
1145 
     | 
    
         
             
                def setColor(self, value: QColor | None) -> None:
         
     | 
| 
       1185 
1146 
     | 
    
         
             
                    """Set text colour."""
         
     | 
| 
         @@ -1189,7 +1150,6 @@ class ODTParagraphStyle: 
     | 
|
| 
       1189 
1150 
     | 
    
         
             
                    else:
         
     | 
| 
       1190 
1151 
     | 
    
         
             
                        self._tAttr["color"][1] = None
         
     | 
| 
       1191 
1152 
     | 
    
         
             
                        self._tAttr["opacity"][1] = None
         
     | 
| 
       1192 
     | 
    
         
            -
                    return
         
     | 
| 
       1193 
1153 
     | 
    
         | 
| 
       1194 
1154 
     | 
    
         
             
                ##
         
     | 
| 
       1195 
1155 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -1233,14 +1193,13 @@ class ODTParagraphStyle: 
     | 
|
| 
       1233 
1193 
     | 
    
         
             
                    if attr := {_mkTag(n, m): v for m, (n, v) in self._tAttr.items() if v}:
         
     | 
| 
       1234 
1194 
     | 
    
         
             
                        ET.SubElement(xEntry, _mkTag("style", "text-properties"), attrib=attr)
         
     | 
| 
       1235 
1195 
     | 
    
         | 
| 
       1236 
     | 
    
         
            -
                    return
         
     | 
| 
       1237 
     | 
    
         
            -
             
     | 
| 
       1238 
1196 
     | 
    
         | 
| 
       1239 
1197 
     | 
    
         
             
            class ODTTextStyle:
         
     | 
| 
       1240 
1198 
     | 
    
         
             
                """Wrapper class for the text style setting used by the exporter.
         
     | 
| 
       1241 
1199 
     | 
    
         
             
                Only the used settings are exposed here to keep the class minimal
         
     | 
| 
       1242 
1200 
     | 
    
         
             
                and fast.
         
     | 
| 
       1243 
1201 
     | 
    
         
             
                """
         
     | 
| 
      
 1202 
     | 
    
         
            +
             
     | 
| 
       1244 
1203 
     | 
    
         
             
                VALID_WEIGHT: Final[list[str]] = ["normal", "bold", *FONT_WEIGHT_NUM]
         
     | 
| 
       1245 
1204 
     | 
    
         
             
                VALID_STYLE: Final[list[str]]  = ["normal", "italic", "oblique"]
         
     | 
| 
       1246 
1205 
     | 
    
         
             
                VALID_POS: Final[list[str]]    = ["super", "sub"]
         
     | 
| 
         @@ -1263,7 +1222,6 @@ class ODTTextStyle: 
     | 
|
| 
       1263 
1222 
     | 
    
         
             
                        "text-underline-width":    ["style", None],
         
     | 
| 
       1264 
1223 
     | 
    
         
             
                        "text-underline-color":    ["style", None],
         
     | 
| 
       1265 
1224 
     | 
    
         
             
                    }
         
     | 
| 
       1266 
     | 
    
         
            -
                    return
         
     | 
| 
       1267 
1225 
     | 
    
         | 
| 
       1268 
1226 
     | 
    
         
             
                @property
         
     | 
| 
       1269 
1227 
     | 
    
         
             
                def name(self) -> str:
         
     | 
| 
         @@ -1279,7 +1237,6 @@ class ODTTextStyle: 
     | 
|
| 
       1279 
1237 
     | 
    
         
             
                        self._tAttr["font-weight"][1] = value
         
     | 
| 
       1280 
1238 
     | 
    
         
             
                    else:
         
     | 
| 
       1281 
1239 
     | 
    
         
             
                        self._tAttr["font-weight"][1] = None
         
     | 
| 
       1282 
     | 
    
         
            -
                    return
         
     | 
| 
       1283 
1240 
     | 
    
         | 
| 
       1284 
1241 
     | 
    
         
             
                def setFontStyle(self, value: str | None) -> None:
         
     | 
| 
       1285 
1242 
     | 
    
         
             
                    """Set text font style."""
         
     | 
| 
         @@ -1287,7 +1244,6 @@ class ODTTextStyle: 
     | 
|
| 
       1287 
1244 
     | 
    
         
             
                        self._tAttr["font-style"][1] = value
         
     | 
| 
       1288 
1245 
     | 
    
         
             
                    else:
         
     | 
| 
       1289 
1246 
     | 
    
         
             
                        self._tAttr["font-style"][1] = None
         
     | 
| 
       1290 
     | 
    
         
            -
                    return
         
     | 
| 
       1291 
1247 
     | 
    
         | 
| 
       1292 
1248 
     | 
    
         
             
                def setColor(self, value: QColor | None) -> None:
         
     | 
| 
       1293 
1249 
     | 
    
         
             
                    """Set text colour."""
         
     | 
| 
         @@ -1295,7 +1251,6 @@ class ODTTextStyle: 
     | 
|
| 
       1295 
1251 
     | 
    
         
             
                        self._tAttr["color"][1] = value.name(QtHexRgb)
         
     | 
| 
       1296 
1252 
     | 
    
         
             
                    else:
         
     | 
| 
       1297 
1253 
     | 
    
         
             
                        self._tAttr["color"][1] = None
         
     | 
| 
       1298 
     | 
    
         
            -
                    return
         
     | 
| 
       1299 
1254 
     | 
    
         | 
| 
       1300 
1255 
     | 
    
         
             
                def setBackgroundColor(self, value: QColor | None) -> None:
         
     | 
| 
       1301 
1256 
     | 
    
         
             
                    """Set text background colour."""
         
     | 
| 
         @@ -1303,7 +1258,6 @@ class ODTTextStyle: 
     | 
|
| 
       1303 
1258 
     | 
    
         
             
                        self._tAttr["background-color"][1] = value.name(QtHexRgb)
         
     | 
| 
       1304 
1259 
     | 
    
         
             
                    else:
         
     | 
| 
       1305 
1260 
     | 
    
         
             
                        self._tAttr["background-color"][1] = None
         
     | 
| 
       1306 
     | 
    
         
            -
                    return
         
     | 
| 
       1307 
1261 
     | 
    
         | 
| 
       1308 
1262 
     | 
    
         
             
                def setTextPosition(self, value: str | None) -> None:
         
     | 
| 
       1309 
1263 
     | 
    
         
             
                    """Set text vertical position."""
         
     | 
| 
         @@ -1311,7 +1265,6 @@ class ODTTextStyle: 
     | 
|
| 
       1311 
1265 
     | 
    
         
             
                        self._tAttr["text-position"][1] = f"{value} 58%"
         
     | 
| 
       1312 
1266 
     | 
    
         
             
                    else:
         
     | 
| 
       1313 
1267 
     | 
    
         
             
                        self._tAttr["text-position"][1] = None
         
     | 
| 
       1314 
     | 
    
         
            -
                    return
         
     | 
| 
       1315 
1268 
     | 
    
         | 
| 
       1316 
1269 
     | 
    
         
             
                def setStrikeStyle(self, value: str | None) -> None:
         
     | 
| 
       1317 
1270 
     | 
    
         
             
                    """Set text line-trough style."""
         
     | 
| 
         @@ -1319,7 +1272,6 @@ class ODTTextStyle: 
     | 
|
| 
       1319 
1272 
     | 
    
         
             
                        self._tAttr["text-line-through-style"][1] = value
         
     | 
| 
       1320 
1273 
     | 
    
         
             
                    else:
         
     | 
| 
       1321 
1274 
     | 
    
         
             
                        self._tAttr["text-line-through-style"][1] = None
         
     | 
| 
       1322 
     | 
    
         
            -
                    return
         
     | 
| 
       1323 
1275 
     | 
    
         | 
| 
       1324 
1276 
     | 
    
         
             
                def setStrikeType(self, value: str | None) -> None:
         
     | 
| 
       1325 
1277 
     | 
    
         
             
                    """Set text line-through type."""
         
     | 
| 
         @@ -1327,7 +1279,6 @@ class ODTTextStyle: 
     | 
|
| 
       1327 
1279 
     | 
    
         
             
                        self._tAttr["text-line-through-type"][1] = value
         
     | 
| 
       1328 
1280 
     | 
    
         
             
                    else:
         
     | 
| 
       1329 
1281 
     | 
    
         
             
                        self._tAttr["text-line-through-type"][1] = None
         
     | 
| 
       1330 
     | 
    
         
            -
                    return
         
     | 
| 
       1331 
1282 
     | 
    
         | 
| 
       1332 
1283 
     | 
    
         
             
                def setUnderlineStyle(self, value: str | None) -> None:
         
     | 
| 
       1333 
1284 
     | 
    
         
             
                    """Set text underline style."""
         
     | 
| 
         @@ -1335,7 +1286,6 @@ class ODTTextStyle: 
     | 
|
| 
       1335 
1286 
     | 
    
         
             
                        self._tAttr["text-underline-style"][1] = value
         
     | 
| 
       1336 
1287 
     | 
    
         
             
                    else:
         
     | 
| 
       1337 
1288 
     | 
    
         
             
                        self._tAttr["text-underline-style"][1] = None
         
     | 
| 
       1338 
     | 
    
         
            -
                    return
         
     | 
| 
       1339 
1289 
     | 
    
         | 
| 
       1340 
1290 
     | 
    
         
             
                def setUnderlineWidth(self, value: str | None) -> None:
         
     | 
| 
       1341 
1291 
     | 
    
         
             
                    """Set text underline width."""
         
     | 
| 
         @@ -1343,7 +1293,6 @@ class ODTTextStyle: 
     | 
|
| 
       1343 
1293 
     | 
    
         
             
                        self._tAttr["text-underline-width"][1] = value
         
     | 
| 
       1344 
1294 
     | 
    
         
             
                    else:
         
     | 
| 
       1345 
1295 
     | 
    
         
             
                        self._tAttr["text-underline-width"][1] = None
         
     | 
| 
       1346 
     | 
    
         
            -
                    return
         
     | 
| 
       1347 
1296 
     | 
    
         | 
| 
       1348 
1297 
     | 
    
         
             
                def setUnderlineColor(self, value: str | None) -> None:
         
     | 
| 
       1349 
1298 
     | 
    
         
             
                    """Set text underline colour."""
         
     | 
| 
         @@ -1351,7 +1300,6 @@ class ODTTextStyle: 
     | 
|
| 
       1351 
1300 
     | 
    
         
             
                        self._tAttr["text-underline-color"][1] = value
         
     | 
| 
       1352 
1301 
     | 
    
         
             
                    else:
         
     | 
| 
       1353 
1302 
     | 
    
         
             
                        self._tAttr["text-underline-color"][1] = None
         
     | 
| 
       1354 
     | 
    
         
            -
                    return
         
     | 
| 
       1355 
1303 
     | 
    
         | 
| 
       1356 
1304 
     | 
    
         
             
                ##
         
     | 
| 
       1357 
1305 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -1365,7 +1313,6 @@ class ODTTextStyle: 
     | 
|
| 
       1365 
1313 
     | 
    
         
             
                    })
         
     | 
| 
       1366 
1314 
     | 
    
         
             
                    if attr := {_mkTag(n, m): v for m, (n, v) in self._tAttr.items() if v}:
         
     | 
| 
       1367 
1315 
     | 
    
         
             
                        ET.SubElement(xEntry, _mkTag("style", "text-properties"), attrib=attr)
         
     | 
| 
       1368 
     | 
    
         
            -
                    return
         
     | 
| 
       1369 
1316 
     | 
    
         | 
| 
       1370 
1317 
     | 
    
         | 
| 
       1371 
1318 
     | 
    
         
             
            # XML Complex Element Helper Class
         
     | 
| 
         @@ -1378,7 +1325,9 @@ X_SPAN_SING = 3 
     | 
|
| 
       1378 
1325 
     | 
    
         | 
| 
       1379 
1326 
     | 
    
         | 
| 
       1380 
1327 
     | 
    
         
             
            class XMLParagraph:
         
     | 
| 
       1381 
     | 
    
         
            -
                """ 
     | 
| 
      
 1328 
     | 
    
         
            +
                """ODT Text Paragraph.
         
     | 
| 
      
 1329 
     | 
    
         
            +
             
     | 
| 
      
 1330 
     | 
    
         
            +
                This is a helper class to manage the text content of a single
         
     | 
| 
       1382 
1331 
     | 
    
         
             
                XML element using mixed content tags.
         
     | 
| 
       1383 
1332 
     | 
    
         | 
| 
       1384 
1333 
     | 
    
         
             
                Rules:
         
     | 
| 
         @@ -1408,8 +1357,6 @@ class XMLParagraph: 
     | 
|
| 
       1408 
1357 
     | 
    
         
             
                    self._rawTxt = ""
         
     | 
| 
       1409 
1358 
     | 
    
         
             
                    self._xRoot.text = ""
         
     | 
| 
       1410 
1359 
     | 
    
         | 
| 
       1411 
     | 
    
         
            -
                    return
         
     | 
| 
       1412 
     | 
    
         
            -
             
     | 
| 
       1413 
1360 
     | 
    
         
             
                def appendText(self, text: str) -> None:
         
     | 
| 
       1414 
1361 
     | 
    
         
             
                    """Append text to the XML element. We do this one character at
         
     | 
| 
       1415 
1362 
     | 
    
         
             
                    the time in order to be able to process line breaks, tabs and
         
     | 
| 
         @@ -1424,7 +1371,7 @@ class XMLParagraph: 
     | 
|
| 
       1424 
1371 
     | 
    
         
             
                        if c == " ":
         
     | 
| 
       1425 
1372 
     | 
    
         
             
                            nSpaces += 1
         
     | 
| 
       1426 
1373 
     | 
    
         
             
                            continue
         
     | 
| 
       1427 
     | 
    
         
            -
                         
     | 
| 
      
 1374 
     | 
    
         
            +
                        if nSpaces > 0:
         
     | 
| 
       1428 
1375 
     | 
    
         
             
                            self._processSpaces(nSpaces)
         
     | 
| 
       1429 
1376 
     | 
    
         
             
                            nSpaces = 0
         
     | 
| 
       1430 
1377 
     | 
    
         | 
| 
         @@ -1468,8 +1415,6 @@ class XMLParagraph: 
     | 
|
| 
       1468 
1415 
     | 
    
         
             
                        # Handle trailing spaces
         
     | 
| 
       1469 
1416 
     | 
    
         
             
                        self._processSpaces(nSpaces)
         
     | 
| 
       1470 
1417 
     | 
    
         | 
| 
       1471 
     | 
    
         
            -
                    return
         
     | 
| 
       1472 
     | 
    
         
            -
             
     | 
| 
       1473 
1418 
     | 
    
         
             
                def appendSpan(self, text: str, style: str, link: str) -> None:
         
     | 
| 
       1474 
1419 
     | 
    
         
             
                    """Append a text span to the XML element. The span is always
         
     | 
| 
       1475 
1420 
     | 
    
         
             
                    closed since we do not produce nested spans (like Libre Office).
         
     | 
| 
         @@ -1491,7 +1436,6 @@ class XMLParagraph: 
     | 
|
| 
       1491 
1436 
     | 
    
         
             
                    self._nState = X_SPAN_TEXT
         
     | 
| 
       1492 
1437 
     | 
    
         
             
                    self.appendText(text)
         
     | 
| 
       1493 
1438 
     | 
    
         
             
                    self._nState = X_ROOT_TAIL
         
     | 
| 
       1494 
     | 
    
         
            -
                    return
         
     | 
| 
       1495 
1439 
     | 
    
         | 
| 
       1496 
1440 
     | 
    
         
             
                def appendNode(self, xNode: ET.Element | None) -> None:
         
     | 
| 
       1497 
1441 
     | 
    
         
             
                    """Append an XML node to the paragraph. We only check for the
         
     | 
| 
         @@ -1504,7 +1448,6 @@ class XMLParagraph: 
     | 
|
| 
       1504 
1448 
     | 
    
         
             
                        self._xTail = xNode
         
     | 
| 
       1505 
1449 
     | 
    
         
             
                        self._xTail.tail = ""
         
     | 
| 
       1506 
1450 
     | 
    
         
             
                        self._nState = X_ROOT_TAIL
         
     | 
| 
       1507 
     | 
    
         
            -
                    return
         
     | 
| 
       1508 
1451 
     | 
    
         | 
| 
       1509 
1452 
     | 
    
         
             
                def checkError(self) -> tuple[int, str]:
         
     | 
| 
       1510 
1453 
     | 
    
         
             
                    """Check that the number of characters written matches the
         
     | 
| 
         @@ -1575,5 +1518,3 @@ class XMLParagraph: 
     | 
|
| 
       1575 
1518 
     | 
    
         
             
                            self._xSing.tail = ""
         
     | 
| 
       1576 
1519 
     | 
    
         
             
                            self._nState = X_SPAN_SING
         
     | 
| 
       1577 
1520 
     | 
    
         
             
                            self._chrPos += nSpaces - 1
         
     | 
| 
       1578 
     | 
    
         
            -
             
     | 
| 
       1579 
     | 
    
         
            -
                    return
         
     | 
    
        novelwriter/formats/toqdoc.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
         
     | 
| 
         @@ -37,7 +37,7 @@ from PyQt6.QtPrintSupport import QPrinter 
     | 
|
| 
       37 
37 
     | 
    
         
             
            from novelwriter import __version__
         
     | 
| 
       38 
38 
     | 
    
         
             
            from novelwriter.constants import nwStyles, nwUnicode
         
     | 
| 
       39 
39 
     | 
    
         
             
            from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt, stripEscape
         
     | 
| 
       40 
     | 
    
         
            -
            from novelwriter.formats.tokenizer import  
     | 
| 
      
 40 
     | 
    
         
            +
            from novelwriter.formats.tokenizer import HEADING_BLOCKS, META_BLOCKS, Tokenizer
         
     | 
| 
       41 
41 
     | 
    
         
             
            from novelwriter.types import (
         
     | 
| 
       42 
42 
     | 
    
         
             
                QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
         
     | 
| 
       43 
43 
     | 
    
         
             
                QtKeepAnchor, QtMoveAnchor, QtPageBreakAfter, QtPageBreakAuto,
         
     | 
| 
         @@ -56,6 +56,7 @@ T_TextStyle = tuple[QTextBlockFormat, QTextCharFormat] 
     | 
|
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         | 
| 
       58 
58 
     | 
    
         
             
            def newBlock(cursor: QTextCursor, bFmt: QTextBlockFormat) -> None:
         
     | 
| 
      
 59 
     | 
    
         
            +
                """Insert a new block if not at the beginning of the document."""
         
     | 
| 
       59 
60 
     | 
    
         
             
                if cursor.position() > 0:
         
     | 
| 
       60 
61 
     | 
    
         
             
                    cursor.insertBlock(bFmt)
         
     | 
| 
       61 
62 
     | 
    
         
             
                else:
         
     | 
| 
         @@ -63,7 +64,7 @@ def newBlock(cursor: QTextCursor, bFmt: QTextBlockFormat) -> None: 
     | 
|
| 
       63 
64 
     | 
    
         | 
| 
       64 
65 
     | 
    
         | 
| 
       65 
66 
     | 
    
         
             
            class ToQTextDocument(Tokenizer):
         
     | 
| 
       66 
     | 
    
         
            -
                """Core: QTextDocument Writer
         
     | 
| 
      
 67 
     | 
    
         
            +
                """Core: QTextDocument Writer.
         
     | 
| 
       67 
68 
     | 
    
         | 
| 
       68 
69 
     | 
    
         
             
                Extend the Tokenizer class to generate a QTextDocument output. This
         
     | 
| 
       69 
70 
     | 
    
         
             
                is intended for usage in the document viewer and build tool preview.
         
     | 
| 
         @@ -92,8 +93,6 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       92 
93 
     | 
    
         
             
                    self._pageSize = QPageSize(QPageSize.PageSizeId.A4)
         
     | 
| 
       93 
94 
     | 
    
         
             
                    self._pageMargins = QMarginsF(20.0, 20.0, 20.0, 20.0)
         
     | 
| 
       94 
95 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
                    return
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
96 
     | 
    
         
             
                ##
         
     | 
| 
       98 
97 
     | 
    
         
             
                #  Properties
         
     | 
| 
       99 
98 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -113,17 +112,14 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       113 
112 
     | 
    
         
             
                    """Set the document page size and margins in millimetres."""
         
     | 
| 
       114 
113 
     | 
    
         
             
                    self._pageSize = QPageSize(QSizeF(width, height), QPageSize.Unit.Millimeter)
         
     | 
| 
       115 
114 
     | 
    
         
             
                    self._pageMargins = QMarginsF(left, top, right, bottom)
         
     | 
| 
       116 
     | 
    
         
            -
                    return
         
     | 
| 
       117 
115 
     | 
    
         | 
| 
       118 
116 
     | 
    
         
             
                def setShowNewPage(self, state: bool) -> None:
         
     | 
| 
       119 
117 
     | 
    
         
             
                    """Add markers for page breaks."""
         
     | 
| 
       120 
118 
     | 
    
         
             
                    self._newPage = state
         
     | 
| 
       121 
     | 
    
         
            -
                    return
         
     | 
| 
       122 
119 
     | 
    
         | 
| 
       123 
120 
     | 
    
         
             
                def disableAnchors(self) -> None:
         
     | 
| 
       124 
121 
     | 
    
         
             
                    """Disable anchors for when writing to file."""
         
     | 
| 
       125 
122 
     | 
    
         
             
                    self._anchors = False
         
     | 
| 
       126 
     | 
    
         
            -
                    return
         
     | 
| 
       127 
123 
     | 
    
         | 
| 
       128 
124 
     | 
    
         
             
                ##
         
     | 
| 
       129 
125 
     | 
    
         
             
                #  Class Methods
         
     | 
| 
         @@ -200,8 +196,6 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       200 
196 
     | 
    
         | 
| 
       201 
197 
     | 
    
         
             
                    self._init = True
         
     | 
| 
       202 
198 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
                    return
         
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
199 
     | 
    
         
             
                def doConvert(self) -> None:
         
     | 
| 
       206 
200 
     | 
    
         
             
                    """Write text tokens into the document."""
         
     | 
| 
       207 
201 
     | 
    
         
             
                    if not self._init:
         
     | 
| 
         @@ -214,7 +208,7 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       214 
208 
     | 
    
         
             
                    for tType, tMeta, tText, tFormat, tStyle in self._blocks:
         
     | 
| 
       215 
209 
     | 
    
         | 
| 
       216 
210 
     | 
    
         
             
                        bFmt = QTextBlockFormat(self._blockFmt)
         
     | 
| 
       217 
     | 
    
         
            -
                        if tType in  
     | 
| 
      
 211 
     | 
    
         
            +
                        if tType in META_BLOCKS:
         
     | 
| 
       218 
212 
     | 
    
         
             
                            bFmt.setTopMargin(self._mMeta[0])
         
     | 
| 
       219 
213 
     | 
    
         
             
                            bFmt.setBottomMargin(self._mMeta[1])
         
     | 
| 
       220 
214 
     | 
    
         
             
                        elif tType == BlockTyp.SEP:
         
     | 
| 
         @@ -248,17 +242,21 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       248 
242 
     | 
    
         
             
                        if tStyle & BlockFmt.IND_T:
         
     | 
| 
       249 
243 
     | 
    
         
             
                            bFmt.setTextIndent(self._tIndent)
         
     | 
| 
       250 
244 
     | 
    
         | 
| 
       251 
     | 
    
         
            -
                        if tType  
     | 
| 
      
 245 
     | 
    
         
            +
                        if tType == BlockTyp.TEXT:
         
     | 
| 
       252 
246 
     | 
    
         
             
                            newBlock(cursor, bFmt)
         
     | 
| 
       253 
247 
     | 
    
         
             
                            self._insertFragments(tText, tFormat, cursor, self._charFmt)
         
     | 
| 
       254 
248 
     | 
    
         | 
| 
       255 
     | 
    
         
            -
                        elif tType in  
     | 
| 
      
 249 
     | 
    
         
            +
                        elif tType in HEADING_BLOCKS:
         
     | 
| 
       256 
250 
     | 
    
         
             
                            bFmt, cFmt = self._genHeadStyle(tType, tMeta, bFmt)
         
     | 
| 
       257 
251 
     | 
    
         
             
                            for tPart in tText.split("\n"):
         
     | 
| 
       258 
252 
     | 
    
         
             
                                newBlock(cursor, bFmt)
         
     | 
| 
       259 
253 
     | 
    
         
             
                                cursor.insertText(tPart, cFmt)
         
     | 
| 
       260 
254 
     | 
    
         
             
                                bFmt.setPageBreakPolicy(QtPageBreakAuto)
         
     | 
| 
       261 
255 
     | 
    
         | 
| 
      
 256 
     | 
    
         
            +
                        elif tType in META_BLOCKS:
         
     | 
| 
      
 257 
     | 
    
         
            +
                            newBlock(cursor, bFmt)
         
     | 
| 
      
 258 
     | 
    
         
            +
                            self._insertFragments(tText, tFormat, cursor, self._charFmt)
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
       262 
260 
     | 
    
         
             
                        elif tType == BlockTyp.SEP:
         
     | 
| 
       263 
261 
     | 
    
         
             
                            newBlock(cursor, bFmt)
         
     | 
| 
       264 
262 
     | 
    
         
             
                            cursor.insertText(tText, self._charFmt)
         
     | 
| 
         @@ -293,8 +291,6 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       293 
291 
     | 
    
         
             
                    self._document.setPageSize(printer.pageRect(QPrinter.Unit.DevicePixel).size())
         
     | 
| 
       294 
292 
     | 
    
         
             
                    self._document.print(printer)
         
     | 
| 
       295 
293 
     | 
    
         | 
| 
       296 
     | 
    
         
            -
                    return
         
     | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
       298 
294 
     | 
    
         
             
                def closeDocument(self) -> None:
         
     | 
| 
       299 
295 
     | 
    
         
             
                    """Run close document tasks."""
         
     | 
| 
       300 
296 
     | 
    
         
             
                    self._document.blockSignals(True)
         
     | 
| 
         @@ -329,8 +325,6 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       329 
325 
     | 
    
         | 
| 
       330 
326 
     | 
    
         
             
                    self._document.blockSignals(False)
         
     | 
| 
       331 
327 
     | 
    
         | 
| 
       332 
     | 
    
         
            -
                    return
         
     | 
| 
       333 
     | 
    
         
            -
             
     | 
| 
       334 
328 
     | 
    
         
             
                ##
         
     | 
| 
       335 
329 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
       336 
330 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -435,8 +429,6 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       435 
429 
     | 
    
         
             
                    # Insert whatever is left in the buffer
         
     | 
| 
       436 
430 
     | 
    
         
             
                    cursor.insertText(stripEscape(temp[start:]), cFmt)
         
     | 
| 
       437 
431 
     | 
    
         | 
| 
       438 
     | 
    
         
            -
                    return
         
     | 
| 
       439 
     | 
    
         
            -
             
     | 
| 
       440 
432 
     | 
    
         
             
                def _insertNewPageMarker(self, cursor: QTextCursor) -> None:
         
     | 
| 
       441 
433 
     | 
    
         
             
                    """Insert a new page marker."""
         
     | 
| 
       442 
434 
     | 
    
         
             
                    if self._newPage:
         
     | 
| 
         @@ -471,8 +463,6 @@ class ToQTextDocument(Tokenizer): 
     | 
|
| 
       471 
463 
     | 
    
         
             
                        if root := self._document.rootFrame():
         
     | 
| 
       472 
464 
     | 
    
         
             
                            cursor.swap(root.lastCursorPosition())
         
     | 
| 
       473 
465 
     | 
    
         | 
| 
       474 
     | 
    
         
            -
                    return
         
     | 
| 
       475 
     | 
    
         
            -
             
     | 
| 
       476 
466 
     | 
    
         
             
                def _genHeadStyle(self, hType: BlockTyp, hKey: str, rFmt: QTextBlockFormat) -> T_TextStyle:
         
     | 
| 
       477 
467 
     | 
    
         
             
                    """Generate a heading style set."""
         
     | 
| 
       478 
468 
     | 
    
         
             
                    mTop, mBottom = self._mHead.get(hType, (0.0, 0.0))
         
     | 
    
        novelwriter/formats/toraw.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 json
         
     | 
| 
         @@ -41,7 +41,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
            class ToRaw(Tokenizer):
         
     | 
| 
       44 
     | 
    
         
            -
                """Core: Raw novelWriter Text Writer
         
     | 
| 
      
 44 
     | 
    
         
            +
                """Core: Raw novelWriter Text Writer.
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                A class that will collect the minimally altered original source text
         
     | 
| 
       47 
47 
     | 
    
         
             
                and write it to either a text or JSON file.
         
     | 
| 
         @@ -51,7 +51,6 @@ class ToRaw(Tokenizer): 
     | 
|
| 
       51 
51 
     | 
    
         
             
                    super().__init__(project)
         
     | 
| 
       52 
52 
     | 
    
         
             
                    self._keepRaw = True
         
     | 
| 
       53 
53 
     | 
    
         
             
                    self._noTokens = True
         
     | 
| 
       54 
     | 
    
         
            -
                    return
         
     | 
| 
       55 
54 
     | 
    
         | 
| 
       56 
55 
     | 
    
         
             
                def doConvert(self) -> None:
         
     | 
| 
       57 
56 
     | 
    
         
             
                    """No conversion to perform."""
         
     | 
| 
         @@ -86,10 +85,7 @@ class ToRaw(Tokenizer): 
     | 
|
| 
       86 
85 
     | 
    
         | 
| 
       87 
86 
     | 
    
         
             
                    logger.info("Wrote file: %s", path)
         
     | 
| 
       88 
87 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                    return
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
88 
     | 
    
         
             
                def replaceTabs(self, nSpaces: int = 8, spaceChar: str = " ") -> None:
         
     | 
| 
       92 
89 
     | 
    
         
             
                    """Replace tabs with spaces."""
         
     | 
| 
       93 
90 
     | 
    
         
             
                    spaces = spaceChar*nSpaces
         
     | 
| 
       94 
91 
     | 
    
         
             
                    self._raw = [p.replace("\t", spaces) for p in self._raw]
         
     | 
| 
       95 
     | 
    
         
            -
                    return
         
     |