novelWriter 2.5.1__py3-none-any.whl → 2.6b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/METADATA +2 -1
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/RECORD +61 -56
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/WHEEL +1 -1
 - novelwriter/__init__.py +3 -3
 - novelwriter/assets/i18n/project_en_GB.json +1 -0
 - novelwriter/assets/icons/typicons_dark/icons.conf +1 -0
 - novelwriter/assets/icons/typicons_dark/mixed_copy.svg +4 -0
 - novelwriter/assets/icons/typicons_light/icons.conf +1 -0
 - novelwriter/assets/icons/typicons_light/mixed_copy.svg +4 -0
 - novelwriter/assets/manual.pdf +0 -0
 - novelwriter/assets/sample.zip +0 -0
 - novelwriter/assets/themes/default_light.conf +2 -2
 - novelwriter/common.py +63 -0
 - novelwriter/config.py +10 -3
 - novelwriter/constants.py +153 -60
 - novelwriter/core/buildsettings.py +66 -39
 - novelwriter/core/coretools.py +34 -22
 - novelwriter/core/docbuild.py +130 -169
 - novelwriter/core/index.py +29 -18
 - novelwriter/core/item.py +2 -2
 - novelwriter/core/options.py +4 -1
 - novelwriter/core/spellcheck.py +9 -14
 - novelwriter/dialogs/preferences.py +45 -32
 - novelwriter/dialogs/projectsettings.py +3 -3
 - novelwriter/enum.py +29 -23
 - novelwriter/extensions/configlayout.py +24 -11
 - novelwriter/extensions/modified.py +13 -1
 - novelwriter/extensions/pagedsidebar.py +5 -5
 - novelwriter/formats/shared.py +155 -0
 - novelwriter/formats/todocx.py +1195 -0
 - novelwriter/formats/tohtml.py +452 -0
 - novelwriter/{core → formats}/tokenizer.py +483 -485
 - novelwriter/formats/tomarkdown.py +217 -0
 - novelwriter/{core → formats}/toodt.py +270 -320
 - novelwriter/formats/toqdoc.py +436 -0
 - novelwriter/formats/toraw.py +91 -0
 - novelwriter/gui/doceditor.py +240 -193
 - novelwriter/gui/dochighlight.py +96 -84
 - novelwriter/gui/docviewer.py +56 -30
 - novelwriter/gui/docviewerpanel.py +3 -3
 - novelwriter/gui/editordocument.py +17 -2
 - novelwriter/gui/itemdetails.py +8 -4
 - novelwriter/gui/mainmenu.py +121 -60
 - novelwriter/gui/noveltree.py +35 -37
 - novelwriter/gui/outline.py +186 -238
 - novelwriter/gui/projtree.py +142 -131
 - novelwriter/gui/sidebar.py +7 -6
 - novelwriter/gui/theme.py +5 -4
 - novelwriter/guimain.py +43 -155
 - novelwriter/shared.py +14 -4
 - novelwriter/text/counting.py +2 -0
 - novelwriter/text/patterns.py +155 -59
 - novelwriter/tools/manusbuild.py +1 -1
 - novelwriter/tools/manuscript.py +121 -78
 - novelwriter/tools/manussettings.py +403 -260
 - novelwriter/tools/welcome.py +4 -4
 - novelwriter/tools/writingstats.py +3 -3
 - novelwriter/types.py +16 -6
 - novelwriter/core/tohtml.py +0 -530
 - novelwriter/core/tomarkdown.py +0 -252
 - novelwriter/core/toqdoc.py +0 -419
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/LICENSE.md +0 -0
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/entry_points.txt +0 -0
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/top_level.txt +0 -0
 
    
        novelwriter/core/tomarkdown.py
    DELETED
    
    | 
         @@ -1,252 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            """
         
     | 
| 
       2 
     | 
    
         
            -
            novelWriter – Markdown Text Converter
         
     | 
| 
       3 
     | 
    
         
            -
            =====================================
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            File History:
         
     | 
| 
       6 
     | 
    
         
            -
            Created: 2021-02-06 [1.2b1] ToMarkdown
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            This file is a part of novelWriter
         
     | 
| 
       9 
     | 
    
         
            -
            Copyright 2018–2024, Veronica Berglyd Olsen
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            This program is free software: you can redistribute it and/or modify
         
     | 
| 
       12 
     | 
    
         
            -
            it under the terms of the GNU General Public License as published by
         
     | 
| 
       13 
     | 
    
         
            -
            the Free Software Foundation, either version 3 of the License, or
         
     | 
| 
       14 
     | 
    
         
            -
            (at your option) any later version.
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            This program is distributed in the hope that it will be useful, but
         
     | 
| 
       17 
     | 
    
         
            -
            WITHOUT ANY WARRANTY; without even the implied warranty of
         
     | 
| 
       18 
     | 
    
         
            -
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
         
     | 
| 
       19 
     | 
    
         
            -
            General Public License for more details.
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
     | 
    
         
            -
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
       24 
     | 
    
         
            -
            from __future__ import annotations
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            import logging
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            from pathlib import Path
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            from novelwriter.constants import nwHeadFmt, nwLabels, nwUnicode
         
     | 
| 
       31 
     | 
    
         
            -
            from novelwriter.core.project import NWProject
         
     | 
| 
       32 
     | 
    
         
            -
            from novelwriter.core.tokenizer import T_Formats, Tokenizer
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
            logger = logging.getLogger(__name__)
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
            # Standard Markdown
         
     | 
| 
       38 
     | 
    
         
            -
            STD_MD = {
         
     | 
| 
       39 
     | 
    
         
            -
                Tokenizer.FMT_B_B: "**",
         
     | 
| 
       40 
     | 
    
         
            -
                Tokenizer.FMT_B_E: "**",
         
     | 
| 
       41 
     | 
    
         
            -
                Tokenizer.FMT_I_B: "_",
         
     | 
| 
       42 
     | 
    
         
            -
                Tokenizer.FMT_I_E: "_",
         
     | 
| 
       43 
     | 
    
         
            -
                Tokenizer.FMT_D_B: "",
         
     | 
| 
       44 
     | 
    
         
            -
                Tokenizer.FMT_D_E: "",
         
     | 
| 
       45 
     | 
    
         
            -
                Tokenizer.FMT_U_B: "",
         
     | 
| 
       46 
     | 
    
         
            -
                Tokenizer.FMT_U_E: "",
         
     | 
| 
       47 
     | 
    
         
            -
                Tokenizer.FMT_M_B: "",
         
     | 
| 
       48 
     | 
    
         
            -
                Tokenizer.FMT_M_E: "",
         
     | 
| 
       49 
     | 
    
         
            -
                Tokenizer.FMT_SUP_B: "",
         
     | 
| 
       50 
     | 
    
         
            -
                Tokenizer.FMT_SUP_E: "",
         
     | 
| 
       51 
     | 
    
         
            -
                Tokenizer.FMT_SUB_B: "",
         
     | 
| 
       52 
     | 
    
         
            -
                Tokenizer.FMT_SUB_E: "",
         
     | 
| 
       53 
     | 
    
         
            -
                Tokenizer.FMT_STRIP: "",
         
     | 
| 
       54 
     | 
    
         
            -
            }
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
            # Extended Markdown
         
     | 
| 
       57 
     | 
    
         
            -
            EXT_MD = {
         
     | 
| 
       58 
     | 
    
         
            -
                Tokenizer.FMT_B_B: "**",
         
     | 
| 
       59 
     | 
    
         
            -
                Tokenizer.FMT_B_E: "**",
         
     | 
| 
       60 
     | 
    
         
            -
                Tokenizer.FMT_I_B: "_",
         
     | 
| 
       61 
     | 
    
         
            -
                Tokenizer.FMT_I_E: "_",
         
     | 
| 
       62 
     | 
    
         
            -
                Tokenizer.FMT_D_B: "~~",
         
     | 
| 
       63 
     | 
    
         
            -
                Tokenizer.FMT_D_E: "~~",
         
     | 
| 
       64 
     | 
    
         
            -
                Tokenizer.FMT_U_B: "",
         
     | 
| 
       65 
     | 
    
         
            -
                Tokenizer.FMT_U_E: "",
         
     | 
| 
       66 
     | 
    
         
            -
                Tokenizer.FMT_M_B: "==",
         
     | 
| 
       67 
     | 
    
         
            -
                Tokenizer.FMT_M_E: "==",
         
     | 
| 
       68 
     | 
    
         
            -
                Tokenizer.FMT_SUP_B: "^",
         
     | 
| 
       69 
     | 
    
         
            -
                Tokenizer.FMT_SUP_E: "^",
         
     | 
| 
       70 
     | 
    
         
            -
                Tokenizer.FMT_SUB_B: "~",
         
     | 
| 
       71 
     | 
    
         
            -
                Tokenizer.FMT_SUB_E: "~",
         
     | 
| 
       72 
     | 
    
         
            -
                Tokenizer.FMT_STRIP: "",
         
     | 
| 
       73 
     | 
    
         
            -
            }
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
            class ToMarkdown(Tokenizer):
         
     | 
| 
       77 
     | 
    
         
            -
                """Core: Markdown Document Writer
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                Extend the Tokenizer class to writer Markdown output. It supports
         
     | 
| 
       80 
     | 
    
         
            -
                both Standard Markdown and Extended Markdown. The class also
         
     | 
| 
       81 
     | 
    
         
            -
                supports concatenating novelWriter markup files.
         
     | 
| 
       82 
     | 
    
         
            -
                """
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                def __init__(self, project: NWProject) -> None:
         
     | 
| 
       85 
     | 
    
         
            -
                    super().__init__(project)
         
     | 
| 
       86 
     | 
    
         
            -
                    self._fullMD: list[str] = []
         
     | 
| 
       87 
     | 
    
         
            -
                    self._usedNotes: dict[str, int] = {}
         
     | 
| 
       88 
     | 
    
         
            -
                    self._extended = True
         
     | 
| 
       89 
     | 
    
         
            -
                    return
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                ##
         
     | 
| 
       92 
     | 
    
         
            -
                #  Properties
         
     | 
| 
       93 
     | 
    
         
            -
                ##
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
                @property
         
     | 
| 
       96 
     | 
    
         
            -
                def fullMD(self) -> list[str]:
         
     | 
| 
       97 
     | 
    
         
            -
                    """Return the markdown as a list."""
         
     | 
| 
       98 
     | 
    
         
            -
                    return self._fullMD
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
                ##
         
     | 
| 
       101 
     | 
    
         
            -
                #  Setters
         
     | 
| 
       102 
     | 
    
         
            -
                ##
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
                def setExtendedMarkdown(self, state: bool) -> None:
         
     | 
| 
       105 
     | 
    
         
            -
                    """Set the converter to use Extended Markdown formatting."""
         
     | 
| 
       106 
     | 
    
         
            -
                    self._extended = state
         
     | 
| 
       107 
     | 
    
         
            -
                    return
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                ##
         
     | 
| 
       110 
     | 
    
         
            -
                #  Class Methods
         
     | 
| 
       111 
     | 
    
         
            -
                ##
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                def getFullResultSize(self) -> int:
         
     | 
| 
       114 
     | 
    
         
            -
                    """Return the size of the full Markdown result."""
         
     | 
| 
       115 
     | 
    
         
            -
                    return sum(len(x) for x in self._fullMD)
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
                def doConvert(self) -> None:
         
     | 
| 
       118 
     | 
    
         
            -
                    """Convert the list of text tokens into a Markdown document."""
         
     | 
| 
       119 
     | 
    
         
            -
                    self._result = ""
         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
                    if self._extended:
         
     | 
| 
       122 
     | 
    
         
            -
                        mTags = EXT_MD
         
     | 
| 
       123 
     | 
    
         
            -
                        cSkip = nwUnicode.U_MMSP
         
     | 
| 
       124 
     | 
    
         
            -
                    else:
         
     | 
| 
       125 
     | 
    
         
            -
                        mTags = STD_MD
         
     | 
| 
       126 
     | 
    
         
            -
                        cSkip = ""
         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
                    lines = []
         
     | 
| 
       129 
     | 
    
         
            -
                    for tType, _, tText, tFormat, tStyle in self._tokens:
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
                        if tType == self.T_TEXT:
         
     | 
| 
       132 
     | 
    
         
            -
                            tTemp = self._formatText(tText, tFormat, mTags).replace("\n", "  \n")
         
     | 
| 
       133 
     | 
    
         
            -
                            lines.append(f"{tTemp}\n\n")
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
                        elif tType == self.T_TITLE:
         
     | 
| 
       136 
     | 
    
         
            -
                            tHead = tText.replace(nwHeadFmt.BR, "\n")
         
     | 
| 
       137 
     | 
    
         
            -
                            lines.append(f"# {tHead}\n\n")
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
                        elif tType == self.T_HEAD1:
         
     | 
| 
       140 
     | 
    
         
            -
                            tHead = tText.replace(nwHeadFmt.BR, "\n")
         
     | 
| 
       141 
     | 
    
         
            -
                            lines.append(f"# {tHead}\n\n")
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
                        elif tType == self.T_HEAD2:
         
     | 
| 
       144 
     | 
    
         
            -
                            tHead = tText.replace(nwHeadFmt.BR, "\n")
         
     | 
| 
       145 
     | 
    
         
            -
                            lines.append(f"## {tHead}\n\n")
         
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                        elif tType == self.T_HEAD3:
         
     | 
| 
       148 
     | 
    
         
            -
                            tHead = tText.replace(nwHeadFmt.BR, "\n")
         
     | 
| 
       149 
     | 
    
         
            -
                            lines.append(f"### {tHead}\n\n")
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
                        elif tType == self.T_HEAD4:
         
     | 
| 
       152 
     | 
    
         
            -
                            tHead = tText.replace(nwHeadFmt.BR, "\n")
         
     | 
| 
       153 
     | 
    
         
            -
                            lines.append(f"#### {tHead}\n\n")
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
                        elif tType == self.T_SEP:
         
     | 
| 
       156 
     | 
    
         
            -
                            lines.append(f"{tText}\n\n")
         
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
                        elif tType == self.T_SKIP:
         
     | 
| 
       159 
     | 
    
         
            -
                            lines.append(f"{cSkip}\n\n")
         
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
                        elif tType == self.T_SYNOPSIS and self._doSynopsis:
         
     | 
| 
       162 
     | 
    
         
            -
                            label = self._localLookup("Synopsis")
         
     | 
| 
       163 
     | 
    
         
            -
                            lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
         
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
                        elif tType == self.T_SHORT and self._doSynopsis:
         
     | 
| 
       166 
     | 
    
         
            -
                            label = self._localLookup("Short Description")
         
     | 
| 
       167 
     | 
    
         
            -
                            lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
         
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
                        elif tType == self.T_COMMENT and self._doComments:
         
     | 
| 
       170 
     | 
    
         
            -
                            label = self._localLookup("Comment")
         
     | 
| 
       171 
     | 
    
         
            -
                            lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
                        elif tType == self.T_KEYWORD and self._doKeywords:
         
     | 
| 
       174 
     | 
    
         
            -
                            lines.append(self._formatKeywords(tText, tStyle))
         
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
                    self._result = "".join(lines)
         
     | 
| 
       177 
     | 
    
         
            -
                    self._fullMD.append(self._result)
         
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
                    return
         
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
                def appendFootnotes(self) -> None:
         
     | 
| 
       182 
     | 
    
         
            -
                    """Append the footnotes in the buffer."""
         
     | 
| 
       183 
     | 
    
         
            -
                    if self._usedNotes:
         
     | 
| 
       184 
     | 
    
         
            -
                        tags = EXT_MD if self._extended else STD_MD
         
     | 
| 
       185 
     | 
    
         
            -
                        footnotes = self._localLookup("Footnotes")
         
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
                        lines = []
         
     | 
| 
       188 
     | 
    
         
            -
                        lines.append(f"### {footnotes}\n\n")
         
     | 
| 
       189 
     | 
    
         
            -
                        for key, index in self._usedNotes.items():
         
     | 
| 
       190 
     | 
    
         
            -
                            if content := self._footnotes.get(key):
         
     | 
| 
       191 
     | 
    
         
            -
                                marker = f"{index}. "
         
     | 
| 
       192 
     | 
    
         
            -
                                text = self._formatText(*content, tags)
         
     | 
| 
       193 
     | 
    
         
            -
                                lines.append(f"{marker}{text}\n")
         
     | 
| 
       194 
     | 
    
         
            -
                        lines.append("\n")
         
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
                        result = "".join(lines)
         
     | 
| 
       197 
     | 
    
         
            -
                        self._result += result
         
     | 
| 
       198 
     | 
    
         
            -
                        self._fullMD.append(result)
         
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
                    return
         
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
                def saveMarkdown(self, path: str | Path) -> None:
         
     | 
| 
       203 
     | 
    
         
            -
                    """Save the data to a plain text file."""
         
     | 
| 
       204 
     | 
    
         
            -
                    with open(path, mode="w", encoding="utf-8") as outFile:
         
     | 
| 
       205 
     | 
    
         
            -
                        outFile.write("".join(self._fullMD))
         
     | 
| 
       206 
     | 
    
         
            -
                    logger.info("Wrote file: %s", path)
         
     | 
| 
       207 
     | 
    
         
            -
                    return
         
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
                def replaceTabs(self, nSpaces: int = 8, spaceChar: str = " ") -> None:
         
     | 
| 
       210 
     | 
    
         
            -
                    """Replace tabs with spaces."""
         
     | 
| 
       211 
     | 
    
         
            -
                    spaces = spaceChar*nSpaces
         
     | 
| 
       212 
     | 
    
         
            -
                    self._fullMD = [p.replace("\t", spaces) for p in self._fullMD]
         
     | 
| 
       213 
     | 
    
         
            -
                    if self._keepMD:
         
     | 
| 
       214 
     | 
    
         
            -
                        self._markdown = [p.replace("\t", spaces) for p in self._markdown]
         
     | 
| 
       215 
     | 
    
         
            -
                    return
         
     | 
| 
       216 
     | 
    
         
            -
             
     | 
| 
       217 
     | 
    
         
            -
                ##
         
     | 
| 
       218 
     | 
    
         
            -
                #  Internal Functions
         
     | 
| 
       219 
     | 
    
         
            -
                ##
         
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
       221 
     | 
    
         
            -
                def _formatText(self, text: str, tFmt: T_Formats, tags: dict[int, str]) -> str:
         
     | 
| 
       222 
     | 
    
         
            -
                    """Apply formatting tags to text."""
         
     | 
| 
       223 
     | 
    
         
            -
                    temp = text
         
     | 
| 
       224 
     | 
    
         
            -
                    for pos, fmt, data in reversed(tFmt):
         
     | 
| 
       225 
     | 
    
         
            -
                        md = ""
         
     | 
| 
       226 
     | 
    
         
            -
                        if fmt == self.FMT_FNOTE:
         
     | 
| 
       227 
     | 
    
         
            -
                            if data in self._footnotes:
         
     | 
| 
       228 
     | 
    
         
            -
                                index = len(self._usedNotes) + 1
         
     | 
| 
       229 
     | 
    
         
            -
                                self._usedNotes[data] = index
         
     | 
| 
       230 
     | 
    
         
            -
                                md = f"[{index}]"
         
     | 
| 
       231 
     | 
    
         
            -
                            else:
         
     | 
| 
       232 
     | 
    
         
            -
                                md = "[ERR]"
         
     | 
| 
       233 
     | 
    
         
            -
                        else:
         
     | 
| 
       234 
     | 
    
         
            -
                            md = tags.get(fmt, "")
         
     | 
| 
       235 
     | 
    
         
            -
                        temp = f"{temp[:pos]}{md}{temp[pos:]}"
         
     | 
| 
       236 
     | 
    
         
            -
                    return temp
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
                def _formatKeywords(self, text: str, style: int) -> str:
         
     | 
| 
       239 
     | 
    
         
            -
                    """Apply Markdown formatting to keywords."""
         
     | 
| 
       240 
     | 
    
         
            -
                    valid, bits, _ = self._project.index.scanThis("@"+text)
         
     | 
| 
       241 
     | 
    
         
            -
                    if not valid or not bits:
         
     | 
| 
       242 
     | 
    
         
            -
                        return ""
         
     | 
| 
       243 
     | 
    
         
            -
             
     | 
| 
       244 
     | 
    
         
            -
                    result = ""
         
     | 
| 
       245 
     | 
    
         
            -
                    if bits[0] in nwLabels.KEY_NAME:
         
     | 
| 
       246 
     | 
    
         
            -
                        result += f"**{self._localLookup(nwLabels.KEY_NAME[bits[0]])}:** "
         
     | 
| 
       247 
     | 
    
         
            -
                        if len(bits) > 1:
         
     | 
| 
       248 
     | 
    
         
            -
                            result += ", ".join(bits[1:])
         
     | 
| 
       249 
     | 
    
         
            -
             
     | 
| 
       250 
     | 
    
         
            -
                    result += "  \n" if style & self.A_Z_BTMMRG else "\n\n"
         
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
       252 
     | 
    
         
            -
                    return result
         
     | 
    
        novelwriter/core/toqdoc.py
    DELETED
    
    | 
         @@ -1,419 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            """
         
     | 
| 
       2 
     | 
    
         
            -
            novelWriter – QTextDocument Converter
         
     | 
| 
       3 
     | 
    
         
            -
            =====================================
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            File History:
         
     | 
| 
       6 
     | 
    
         
            -
            Created: 2024-05-21 [2.5b1] ToQTextDocument
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            This file is a part of novelWriter
         
     | 
| 
       9 
     | 
    
         
            -
            Copyright 2018–2024, Veronica Berglyd Olsen
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            This program is free software: you can redistribute it and/or modify
         
     | 
| 
       12 
     | 
    
         
            -
            it under the terms of the GNU General Public License as published by
         
     | 
| 
       13 
     | 
    
         
            -
            the Free Software Foundation, either version 3 of the License, or
         
     | 
| 
       14 
     | 
    
         
            -
            (at your option) any later version.
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            This program is distributed in the hope that it will be useful, but
         
     | 
| 
       17 
     | 
    
         
            -
            WITHOUT ANY WARRANTY; without even the implied warranty of
         
     | 
| 
       18 
     | 
    
         
            -
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
         
     | 
| 
       19 
     | 
    
         
            -
            General Public License for more details.
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
     | 
    
         
            -
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
       24 
     | 
    
         
            -
            from __future__ import annotations
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            import logging
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            from PyQt5.QtGui import (
         
     | 
| 
       29 
     | 
    
         
            -
                QColor, QFont, QFontMetricsF, QTextBlockFormat, QTextCharFormat,
         
     | 
| 
       30 
     | 
    
         
            -
                QTextCursor, QTextDocument
         
     | 
| 
       31 
     | 
    
         
            -
            )
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            from novelwriter.constants import nwHeaders, nwHeadFmt, nwKeyWords, nwLabels, nwUnicode
         
     | 
| 
       34 
     | 
    
         
            -
            from novelwriter.core.project import NWProject
         
     | 
| 
       35 
     | 
    
         
            -
            from novelwriter.core.tokenizer import T_Formats, Tokenizer
         
     | 
| 
       36 
     | 
    
         
            -
            from novelwriter.types import (
         
     | 
| 
       37 
     | 
    
         
            -
                QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
         
     | 
| 
       38 
     | 
    
         
            -
                QtBlack, QtPageBreakAfter, QtPageBreakBefore, QtTransparent,
         
     | 
| 
       39 
     | 
    
         
            -
                QtVAlignNormal, QtVAlignSub, QtVAlignSuper
         
     | 
| 
       40 
     | 
    
         
            -
            )
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
            logger = logging.getLogger(__name__)
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
            T_TextStyle = tuple[QTextBlockFormat, QTextCharFormat]
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
            class TextDocumentTheme:
         
     | 
| 
       48 
     | 
    
         
            -
                text:      QColor = QtBlack
         
     | 
| 
       49 
     | 
    
         
            -
                highlight: QColor = QtTransparent
         
     | 
| 
       50 
     | 
    
         
            -
                head:      QColor = QtBlack
         
     | 
| 
       51 
     | 
    
         
            -
                comment:   QColor = QtBlack
         
     | 
| 
       52 
     | 
    
         
            -
                note:      QColor = QtBlack
         
     | 
| 
       53 
     | 
    
         
            -
                code:      QColor = QtBlack
         
     | 
| 
       54 
     | 
    
         
            -
                modifier:  QColor = QtBlack
         
     | 
| 
       55 
     | 
    
         
            -
                keyword:   QColor = QtBlack
         
     | 
| 
       56 
     | 
    
         
            -
                tag:       QColor = QtBlack
         
     | 
| 
       57 
     | 
    
         
            -
                optional:  QColor = QtBlack
         
     | 
| 
       58 
     | 
    
         
            -
                dialog:    QColor = QtBlack
         
     | 
| 
       59 
     | 
    
         
            -
                altdialog: QColor = QtBlack
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
            def newBlock(cursor: QTextCursor, bFmt: QTextBlockFormat) -> None:
         
     | 
| 
       63 
     | 
    
         
            -
                if cursor.position() > 0:
         
     | 
| 
       64 
     | 
    
         
            -
                    cursor.insertBlock(bFmt)
         
     | 
| 
       65 
     | 
    
         
            -
                else:
         
     | 
| 
       66 
     | 
    
         
            -
                    cursor.setBlockFormat(bFmt)
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
            class ToQTextDocument(Tokenizer):
         
     | 
| 
       70 
     | 
    
         
            -
                """Core: QTextDocument Writer
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                Extend the Tokenizer class to generate a QTextDocument output. This
         
     | 
| 
       73 
     | 
    
         
            -
                is intended for usage in the document viewer and build tool preview.
         
     | 
| 
       74 
     | 
    
         
            -
                """
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                def __init__(self, project: NWProject) -> None:
         
     | 
| 
       77 
     | 
    
         
            -
                    super().__init__(project)
         
     | 
| 
       78 
     | 
    
         
            -
                    self._document = QTextDocument()
         
     | 
| 
       79 
     | 
    
         
            -
                    self._document.setUndoRedoEnabled(False)
         
     | 
| 
       80 
     | 
    
         
            -
                    self._document.setDocumentMargin(0)
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
                    self._theme = TextDocumentTheme()
         
     | 
| 
       83 
     | 
    
         
            -
                    self._styles: dict[int, T_TextStyle] = {}
         
     | 
| 
       84 
     | 
    
         
            -
                    self._usedNotes: dict[str, int] = {}
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                    self._init = False
         
     | 
| 
       87 
     | 
    
         
            -
                    self._bold = QFont.Weight.Bold
         
     | 
| 
       88 
     | 
    
         
            -
                    self._normal = QFont.Weight.Normal
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                    return
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                def initDocument(self, font: QFont, theme: TextDocumentTheme) -> None:
         
     | 
| 
       93 
     | 
    
         
            -
                    """Initialise all computed values of the document."""
         
     | 
| 
       94 
     | 
    
         
            -
                    self._textFont = font
         
     | 
| 
       95 
     | 
    
         
            -
                    self._theme = theme
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
                    self._document.setUndoRedoEnabled(False)
         
     | 
| 
       98 
     | 
    
         
            -
                    self._document.blockSignals(True)
         
     | 
| 
       99 
     | 
    
         
            -
                    self._document.clear()
         
     | 
| 
       100 
     | 
    
         
            -
                    self._document.setDefaultFont(self._textFont)
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
                    qMetric = QFontMetricsF(self._textFont)
         
     | 
| 
       103 
     | 
    
         
            -
                    mPx = qMetric.ascent()  # 1 em in pixels
         
     | 
| 
       104 
     | 
    
         
            -
                    fPt = self._textFont.pointSizeF()
         
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
                    # Scaled Sizes
         
     | 
| 
       107 
     | 
    
         
            -
                    # ============
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                    self._mHead = {
         
     | 
| 
       110 
     | 
    
         
            -
                        self.T_TITLE: (mPx * self._marginTitle[0], mPx * self._marginTitle[1]),
         
     | 
| 
       111 
     | 
    
         
            -
                        self.T_HEAD1: (mPx * self._marginHead1[0], mPx * self._marginHead1[1]),
         
     | 
| 
       112 
     | 
    
         
            -
                        self.T_HEAD2: (mPx * self._marginHead2[0], mPx * self._marginHead2[1]),
         
     | 
| 
       113 
     | 
    
         
            -
                        self.T_HEAD3: (mPx * self._marginHead3[0], mPx * self._marginHead3[1]),
         
     | 
| 
       114 
     | 
    
         
            -
                        self.T_HEAD4: (mPx * self._marginHead4[0], mPx * self._marginHead4[1]),
         
     | 
| 
       115 
     | 
    
         
            -
                    }
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
                    self._sHead = {
         
     | 
| 
       118 
     | 
    
         
            -
                        self.T_TITLE: nwHeaders.H_SIZES.get(0, 1.0) * fPt,
         
     | 
| 
       119 
     | 
    
         
            -
                        self.T_HEAD1: nwHeaders.H_SIZES.get(1, 1.0) * fPt,
         
     | 
| 
       120 
     | 
    
         
            -
                        self.T_HEAD2: nwHeaders.H_SIZES.get(2, 1.0) * fPt,
         
     | 
| 
       121 
     | 
    
         
            -
                        self.T_HEAD3: nwHeaders.H_SIZES.get(3, 1.0) * fPt,
         
     | 
| 
       122 
     | 
    
         
            -
                        self.T_HEAD4: nwHeaders.H_SIZES.get(4, 1.0) * fPt,
         
     | 
| 
       123 
     | 
    
         
            -
                    }
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
                    self._mText = (mPx * self._marginText[0], mPx * self._marginText[1])
         
     | 
| 
       126 
     | 
    
         
            -
                    self._mMeta = (mPx * self._marginMeta[0], mPx * self._marginMeta[1])
         
     | 
| 
       127 
     | 
    
         
            -
                    self._mSep  = (mPx * self._marginSep[0], mPx * self._marginSep[1])
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
                    self._mIndent = mPx * 2.0
         
     | 
| 
       130 
     | 
    
         
            -
                    self._tIndent = mPx * self._firstWidth
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                    # Block Format
         
     | 
| 
       133 
     | 
    
         
            -
                    # ============
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
                    self._blockFmt = QTextBlockFormat()
         
     | 
| 
       136 
     | 
    
         
            -
                    self._blockFmt.setTopMargin(self._mText[0])
         
     | 
| 
       137 
     | 
    
         
            -
                    self._blockFmt.setBottomMargin(self._mText[1])
         
     | 
| 
       138 
     | 
    
         
            -
                    self._blockFmt.setAlignment(QtAlignJustify if self._doJustify else QtAlignAbsolute)
         
     | 
| 
       139 
     | 
    
         
            -
                    self._blockFmt.setLineHeight(
         
     | 
| 
       140 
     | 
    
         
            -
                        100*self._lineHeight, QTextBlockFormat.LineHeightTypes.ProportionalHeight
         
     | 
| 
       141 
     | 
    
         
            -
                    )
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
                    # Character Formats
         
     | 
| 
       144 
     | 
    
         
            -
                    # =================
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                    self._cText = QTextCharFormat()
         
     | 
| 
       147 
     | 
    
         
            -
                    self._cText.setBackground(QtTransparent)
         
     | 
| 
       148 
     | 
    
         
            -
                    self._cText.setForeground(self._theme.text)
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
                    self._cHead = QTextCharFormat(self._cText)
         
     | 
| 
       151 
     | 
    
         
            -
                    self._cHead.setForeground(self._theme.head)
         
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
                    self._cComment = QTextCharFormat(self._cText)
         
     | 
| 
       154 
     | 
    
         
            -
                    self._cComment.setForeground(self._theme.comment)
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
                    self._cCommentMod = QTextCharFormat(self._cText)
         
     | 
| 
       157 
     | 
    
         
            -
                    self._cCommentMod.setForeground(self._theme.comment)
         
     | 
| 
       158 
     | 
    
         
            -
                    self._cCommentMod.setFontWeight(self._bold)
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
                    self._cNote = QTextCharFormat(self._cText)
         
     | 
| 
       161 
     | 
    
         
            -
                    self._cNote.setForeground(self._theme.note)
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
                    self._cCode = QTextCharFormat(self._cText)
         
     | 
| 
       164 
     | 
    
         
            -
                    self._cCode.setForeground(self._theme.code)
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
                    self._cModifier = QTextCharFormat(self._cText)
         
     | 
| 
       167 
     | 
    
         
            -
                    self._cModifier.setForeground(self._theme.modifier)
         
     | 
| 
       168 
     | 
    
         
            -
                    self._cModifier.setFontWeight(self._bold)
         
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
                    self._cKeyword = QTextCharFormat(self._cText)
         
     | 
| 
       171 
     | 
    
         
            -
                    self._cKeyword.setForeground(self._theme.keyword)
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
                    self._cTag = QTextCharFormat(self._cText)
         
     | 
| 
       174 
     | 
    
         
            -
                    self._cTag.setForeground(self._theme.tag)
         
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
                    self._cOptional = QTextCharFormat(self._cText)
         
     | 
| 
       177 
     | 
    
         
            -
                    self._cOptional.setForeground(self._theme.optional)
         
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
                    self._init = True
         
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
                    return
         
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
                ##
         
     | 
| 
       184 
     | 
    
         
            -
                #  Properties
         
     | 
| 
       185 
     | 
    
         
            -
                ##
         
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
                @property
         
     | 
| 
       188 
     | 
    
         
            -
                def document(self) -> QTextDocument:
         
     | 
| 
       189 
     | 
    
         
            -
                    """Return the document."""
         
     | 
| 
       190 
     | 
    
         
            -
                    return self._document
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                ##
         
     | 
| 
       193 
     | 
    
         
            -
                #  Class Methods
         
     | 
| 
       194 
     | 
    
         
            -
                ##
         
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
                def doConvert(self) -> None:
         
     | 
| 
       197 
     | 
    
         
            -
                    """Write text tokens into the document."""
         
     | 
| 
       198 
     | 
    
         
            -
                    if not self._init:
         
     | 
| 
       199 
     | 
    
         
            -
                        return
         
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
                    self._document.blockSignals(True)
         
     | 
| 
       202 
     | 
    
         
            -
                    cursor = QTextCursor(self._document)
         
     | 
| 
       203 
     | 
    
         
            -
                    cursor.movePosition(QTextCursor.MoveOperation.End)
         
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
                    for tType, nHead, tText, tFormat, tStyle in self._tokens:
         
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
                        # Styles
         
     | 
| 
       208 
     | 
    
         
            -
                        bFmt = QTextBlockFormat(self._blockFmt)
         
     | 
| 
       209 
     | 
    
         
            -
                        if tStyle is not None:
         
     | 
| 
       210 
     | 
    
         
            -
                            if tStyle & self.A_LEFT:
         
     | 
| 
       211 
     | 
    
         
            -
                                bFmt.setAlignment(QtAlignLeft)
         
     | 
| 
       212 
     | 
    
         
            -
                            elif tStyle & self.A_RIGHT:
         
     | 
| 
       213 
     | 
    
         
            -
                                bFmt.setAlignment(QtAlignRight)
         
     | 
| 
       214 
     | 
    
         
            -
                            elif tStyle & self.A_CENTRE:
         
     | 
| 
       215 
     | 
    
         
            -
                                bFmt.setAlignment(QtAlignCenter)
         
     | 
| 
       216 
     | 
    
         
            -
                            elif tStyle & self.A_JUSTIFY:
         
     | 
| 
       217 
     | 
    
         
            -
                                bFmt.setAlignment(QtAlignJustify)
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
                            if tStyle & self.A_PBB:
         
     | 
| 
       220 
     | 
    
         
            -
                                bFmt.setPageBreakPolicy(QtPageBreakBefore)
         
     | 
| 
       221 
     | 
    
         
            -
                            if tStyle & self.A_PBA:
         
     | 
| 
       222 
     | 
    
         
            -
                                bFmt.setPageBreakPolicy(QtPageBreakAfter)
         
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
                            if tStyle & self.A_Z_BTMMRG:
         
     | 
| 
       225 
     | 
    
         
            -
                                bFmt.setBottomMargin(0.0)
         
     | 
| 
       226 
     | 
    
         
            -
                            if tStyle & self.A_Z_TOPMRG:
         
     | 
| 
       227 
     | 
    
         
            -
                                bFmt.setTopMargin(0.0)
         
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
                            if tStyle & self.A_IND_L:
         
     | 
| 
       230 
     | 
    
         
            -
                                bFmt.setLeftMargin(self._mIndent)
         
     | 
| 
       231 
     | 
    
         
            -
                            if tStyle & self.A_IND_R:
         
     | 
| 
       232 
     | 
    
         
            -
                                bFmt.setRightMargin(self._mIndent)
         
     | 
| 
       233 
     | 
    
         
            -
                            if tStyle & self.A_IND_T:
         
     | 
| 
       234 
     | 
    
         
            -
                                bFmt.setTextIndent(self._tIndent)
         
     | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
       236 
     | 
    
         
            -
                        if tType == self.T_TEXT:
         
     | 
| 
       237 
     | 
    
         
            -
                            newBlock(cursor, bFmt)
         
     | 
| 
       238 
     | 
    
         
            -
                            self._insertFragments(tText, tFormat, cursor, self._cText)
         
     | 
| 
       239 
     | 
    
         
            -
             
     | 
| 
       240 
     | 
    
         
            -
                        elif tType in self.L_HEADINGS:
         
     | 
| 
       241 
     | 
    
         
            -
                            bFmt, cFmt = self._genHeadStyle(tType, nHead, bFmt)
         
     | 
| 
       242 
     | 
    
         
            -
                            newBlock(cursor, bFmt)
         
     | 
| 
       243 
     | 
    
         
            -
                            cursor.insertText(tText.replace(nwHeadFmt.BR, "\n"), cFmt)
         
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
                        elif tType == self.T_SEP:
         
     | 
| 
       246 
     | 
    
         
            -
                            sFmt = QTextBlockFormat(bFmt)
         
     | 
| 
       247 
     | 
    
         
            -
                            sFmt.setTopMargin(self._mSep[0])
         
     | 
| 
       248 
     | 
    
         
            -
                            sFmt.setBottomMargin(self._mSep[1])
         
     | 
| 
       249 
     | 
    
         
            -
                            newBlock(cursor, sFmt)
         
     | 
| 
       250 
     | 
    
         
            -
                            cursor.insertText(tText, self._cText)
         
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
       252 
     | 
    
         
            -
                        elif tType == self.T_SKIP:
         
     | 
| 
       253 
     | 
    
         
            -
                            newBlock(cursor, bFmt)
         
     | 
| 
       254 
     | 
    
         
            -
                            cursor.insertText(nwUnicode.U_NBSP, self._cText)
         
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
       256 
     | 
    
         
            -
                        elif tType in self.L_SUMMARY and self._doSynopsis:
         
     | 
| 
       257 
     | 
    
         
            -
                            newBlock(cursor, bFmt)
         
     | 
| 
       258 
     | 
    
         
            -
                            modifier = self._localLookup(
         
     | 
| 
       259 
     | 
    
         
            -
                                "Short Description" if tType == self.T_SHORT else "Synopsis"
         
     | 
| 
       260 
     | 
    
         
            -
                            )
         
     | 
| 
       261 
     | 
    
         
            -
                            cursor.insertText(f"{modifier}: ", self._cModifier)
         
     | 
| 
       262 
     | 
    
         
            -
                            self._insertFragments(tText, tFormat, cursor, self._cNote)
         
     | 
| 
       263 
     | 
    
         
            -
             
     | 
| 
       264 
     | 
    
         
            -
                        elif tType == self.T_COMMENT and self._doComments:
         
     | 
| 
       265 
     | 
    
         
            -
                            newBlock(cursor, bFmt)
         
     | 
| 
       266 
     | 
    
         
            -
                            modifier = self._localLookup("Comment")
         
     | 
| 
       267 
     | 
    
         
            -
                            cursor.insertText(f"{modifier}: ", self._cCommentMod)
         
     | 
| 
       268 
     | 
    
         
            -
                            self._insertFragments(tText, tFormat, cursor, self._cComment)
         
     | 
| 
       269 
     | 
    
         
            -
             
     | 
| 
       270 
     | 
    
         
            -
                        elif tType == self.T_KEYWORD and self._doKeywords:
         
     | 
| 
       271 
     | 
    
         
            -
                            newBlock(cursor, bFmt)
         
     | 
| 
       272 
     | 
    
         
            -
                            self._insertKeywords(tText, cursor)
         
     | 
| 
       273 
     | 
    
         
            -
             
     | 
| 
       274 
     | 
    
         
            -
                    self._document.blockSignals(False)
         
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
       276 
     | 
    
         
            -
                    return
         
     | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
       278 
     | 
    
         
            -
                def appendFootnotes(self) -> None:
         
     | 
| 
       279 
     | 
    
         
            -
                    """Append the footnotes in the buffer."""
         
     | 
| 
       280 
     | 
    
         
            -
                    if self._usedNotes:
         
     | 
| 
       281 
     | 
    
         
            -
                        self._document.blockSignals(True)
         
     | 
| 
       282 
     | 
    
         
            -
             
     | 
| 
       283 
     | 
    
         
            -
                        cursor = QTextCursor(self._document)
         
     | 
| 
       284 
     | 
    
         
            -
                        cursor.movePosition(QTextCursor.MoveOperation.End)
         
     | 
| 
       285 
     | 
    
         
            -
             
     | 
| 
       286 
     | 
    
         
            -
                        bFmt, cFmt = self._genHeadStyle(self.T_HEAD4, -1, self._blockFmt)
         
     | 
| 
       287 
     | 
    
         
            -
                        newBlock(cursor, bFmt)
         
     | 
| 
       288 
     | 
    
         
            -
                        cursor.insertText(self._localLookup("Footnotes"), cFmt)
         
     | 
| 
       289 
     | 
    
         
            -
             
     | 
| 
       290 
     | 
    
         
            -
                        for key, index in self._usedNotes.items():
         
     | 
| 
       291 
     | 
    
         
            -
                            if content := self._footnotes.get(key):
         
     | 
| 
       292 
     | 
    
         
            -
                                cFmt = QTextCharFormat(self._cCode)
         
     | 
| 
       293 
     | 
    
         
            -
                                cFmt.setAnchor(True)
         
     | 
| 
       294 
     | 
    
         
            -
                                cFmt.setAnchorNames([f"footnote_{index}"])
         
     | 
| 
       295 
     | 
    
         
            -
                                newBlock(cursor, self._blockFmt)
         
     | 
| 
       296 
     | 
    
         
            -
                                cursor.insertText(f"{index}. ", cFmt)
         
     | 
| 
       297 
     | 
    
         
            -
                                self._insertFragments(*content, cursor, self._cText)
         
     | 
| 
       298 
     | 
    
         
            -
             
     | 
| 
       299 
     | 
    
         
            -
                        self._document.blockSignals(False)
         
     | 
| 
       300 
     | 
    
         
            -
             
     | 
| 
       301 
     | 
    
         
            -
                    return
         
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
                ##
         
     | 
| 
       304 
     | 
    
         
            -
                #  Internal Functions
         
     | 
| 
       305 
     | 
    
         
            -
                ##
         
     | 
| 
       306 
     | 
    
         
            -
             
     | 
| 
       307 
     | 
    
         
            -
                def _insertFragments(
         
     | 
| 
       308 
     | 
    
         
            -
                    self, text: str, tFmt: T_Formats, cursor: QTextCursor, dFmt: QTextCharFormat
         
     | 
| 
       309 
     | 
    
         
            -
                ) -> None:
         
     | 
| 
       310 
     | 
    
         
            -
                    """Apply formatting tags to text."""
         
     | 
| 
       311 
     | 
    
         
            -
                    cFmt = QTextCharFormat(dFmt)
         
     | 
| 
       312 
     | 
    
         
            -
                    start = 0
         
     | 
| 
       313 
     | 
    
         
            -
                    temp = text.replace("\n", nwUnicode.U_LSEP)
         
     | 
| 
       314 
     | 
    
         
            -
                    for pos, fmt, data in tFmt:
         
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
       316 
     | 
    
         
            -
                        # Insert buffer with previous format
         
     | 
| 
       317 
     | 
    
         
            -
                        cursor.insertText(temp[start:pos], cFmt)
         
     | 
| 
       318 
     | 
    
         
            -
             
     | 
| 
       319 
     | 
    
         
            -
                        # Construct next format
         
     | 
| 
       320 
     | 
    
         
            -
                        if fmt == self.FMT_B_B:
         
     | 
| 
       321 
     | 
    
         
            -
                            cFmt.setFontWeight(self._bold)
         
     | 
| 
       322 
     | 
    
         
            -
                        elif fmt == self.FMT_B_E:
         
     | 
| 
       323 
     | 
    
         
            -
                            cFmt.setFontWeight(self._normal)
         
     | 
| 
       324 
     | 
    
         
            -
                        elif fmt == self.FMT_I_B:
         
     | 
| 
       325 
     | 
    
         
            -
                            cFmt.setFontItalic(True)
         
     | 
| 
       326 
     | 
    
         
            -
                        elif fmt == self.FMT_I_E:
         
     | 
| 
       327 
     | 
    
         
            -
                            cFmt.setFontItalic(False)
         
     | 
| 
       328 
     | 
    
         
            -
                        elif fmt == self.FMT_D_B:
         
     | 
| 
       329 
     | 
    
         
            -
                            cFmt.setFontStrikeOut(True)
         
     | 
| 
       330 
     | 
    
         
            -
                        elif fmt == self.FMT_D_E:
         
     | 
| 
       331 
     | 
    
         
            -
                            cFmt.setFontStrikeOut(False)
         
     | 
| 
       332 
     | 
    
         
            -
                        elif fmt == self.FMT_U_B:
         
     | 
| 
       333 
     | 
    
         
            -
                            cFmt.setFontUnderline(True)
         
     | 
| 
       334 
     | 
    
         
            -
                        elif fmt == self.FMT_U_E:
         
     | 
| 
       335 
     | 
    
         
            -
                            cFmt.setFontUnderline(False)
         
     | 
| 
       336 
     | 
    
         
            -
                        elif fmt == self.FMT_M_B:
         
     | 
| 
       337 
     | 
    
         
            -
                            cFmt.setBackground(self._theme.highlight)
         
     | 
| 
       338 
     | 
    
         
            -
                        elif fmt == self.FMT_M_E:
         
     | 
| 
       339 
     | 
    
         
            -
                            cFmt.setBackground(QtTransparent)
         
     | 
| 
       340 
     | 
    
         
            -
                        elif fmt == self.FMT_SUP_B:
         
     | 
| 
       341 
     | 
    
         
            -
                            cFmt.setVerticalAlignment(QtVAlignSuper)
         
     | 
| 
       342 
     | 
    
         
            -
                        elif fmt == self.FMT_SUP_E:
         
     | 
| 
       343 
     | 
    
         
            -
                            cFmt.setVerticalAlignment(QtVAlignNormal)
         
     | 
| 
       344 
     | 
    
         
            -
                        elif fmt == self.FMT_SUB_B:
         
     | 
| 
       345 
     | 
    
         
            -
                            cFmt.setVerticalAlignment(QtVAlignSub)
         
     | 
| 
       346 
     | 
    
         
            -
                        elif fmt == self.FMT_SUB_E:
         
     | 
| 
       347 
     | 
    
         
            -
                            cFmt.setVerticalAlignment(QtVAlignNormal)
         
     | 
| 
       348 
     | 
    
         
            -
                        elif fmt == self.FMT_DL_B:
         
     | 
| 
       349 
     | 
    
         
            -
                            cFmt.setForeground(self._theme.dialog)
         
     | 
| 
       350 
     | 
    
         
            -
                        elif fmt == self.FMT_DL_E:
         
     | 
| 
       351 
     | 
    
         
            -
                            cFmt.setForeground(self._theme.text)
         
     | 
| 
       352 
     | 
    
         
            -
                        elif fmt == self.FMT_ADL_B:
         
     | 
| 
       353 
     | 
    
         
            -
                            cFmt.setForeground(self._theme.altdialog)
         
     | 
| 
       354 
     | 
    
         
            -
                        elif fmt == self.FMT_ADL_E:
         
     | 
| 
       355 
     | 
    
         
            -
                            cFmt.setForeground(self._theme.text)
         
     | 
| 
       356 
     | 
    
         
            -
                        elif fmt == self.FMT_FNOTE:
         
     | 
| 
       357 
     | 
    
         
            -
                            xFmt = QTextCharFormat(self._cCode)
         
     | 
| 
       358 
     | 
    
         
            -
                            xFmt.setVerticalAlignment(QtVAlignSuper)
         
     | 
| 
       359 
     | 
    
         
            -
                            if data in self._footnotes:
         
     | 
| 
       360 
     | 
    
         
            -
                                index = len(self._usedNotes) + 1
         
     | 
| 
       361 
     | 
    
         
            -
                                self._usedNotes[data] = index
         
     | 
| 
       362 
     | 
    
         
            -
                                xFmt.setAnchor(True)
         
     | 
| 
       363 
     | 
    
         
            -
                                xFmt.setAnchorHref(f"#footnote_{index}")
         
     | 
| 
       364 
     | 
    
         
            -
                                xFmt.setFontUnderline(True)
         
     | 
| 
       365 
     | 
    
         
            -
                                cursor.insertText(f"[{index}]", xFmt)
         
     | 
| 
       366 
     | 
    
         
            -
                            else:
         
     | 
| 
       367 
     | 
    
         
            -
                                cursor.insertText("[ERR]", cFmt)
         
     | 
| 
       368 
     | 
    
         
            -
             
     | 
| 
       369 
     | 
    
         
            -
                        # Move pos for next pass
         
     | 
| 
       370 
     | 
    
         
            -
                        start = pos
         
     | 
| 
       371 
     | 
    
         
            -
             
     | 
| 
       372 
     | 
    
         
            -
                    # Insert whatever is left in the buffer
         
     | 
| 
       373 
     | 
    
         
            -
                    cursor.insertText(temp[start:], cFmt)
         
     | 
| 
       374 
     | 
    
         
            -
             
     | 
| 
       375 
     | 
    
         
            -
                    return
         
     | 
| 
       376 
     | 
    
         
            -
             
     | 
| 
       377 
     | 
    
         
            -
                def _insertKeywords(self, text: str, cursor: QTextCursor) -> None:
         
     | 
| 
       378 
     | 
    
         
            -
                    """Apply Markdown formatting to keywords."""
         
     | 
| 
       379 
     | 
    
         
            -
                    valid, bits, _ = self._project.index.scanThis("@"+text)
         
     | 
| 
       380 
     | 
    
         
            -
                    if valid and bits:
         
     | 
| 
       381 
     | 
    
         
            -
                        key = f"{self._localLookup(nwLabels.KEY_NAME[bits[0]])}: "
         
     | 
| 
       382 
     | 
    
         
            -
                        cursor.insertText(key, self._cKeyword)
         
     | 
| 
       383 
     | 
    
         
            -
                        if (num := len(bits)) > 1:
         
     | 
| 
       384 
     | 
    
         
            -
                            if bits[0] == nwKeyWords.TAG_KEY:
         
     | 
| 
       385 
     | 
    
         
            -
                                one, two = self._project.index.parseValue(bits[1])
         
     | 
| 
       386 
     | 
    
         
            -
                                cFmt = QTextCharFormat(self._cTag)
         
     | 
| 
       387 
     | 
    
         
            -
                                cFmt.setAnchor(True)
         
     | 
| 
       388 
     | 
    
         
            -
                                cFmt.setAnchorNames([f"tag_{one}".lower()])
         
     | 
| 
       389 
     | 
    
         
            -
                                cursor.insertText(one, cFmt)
         
     | 
| 
       390 
     | 
    
         
            -
                                if two:
         
     | 
| 
       391 
     | 
    
         
            -
                                    cursor.insertText(" | ", self._cText)
         
     | 
| 
       392 
     | 
    
         
            -
                                    cursor.insertText(two, self._cOptional)
         
     | 
| 
       393 
     | 
    
         
            -
                            else:
         
     | 
| 
       394 
     | 
    
         
            -
                                for n, bit in enumerate(bits[1:], 2):
         
     | 
| 
       395 
     | 
    
         
            -
                                    cFmt = QTextCharFormat(self._cTag)
         
     | 
| 
       396 
     | 
    
         
            -
                                    cFmt.setFontUnderline(True)
         
     | 
| 
       397 
     | 
    
         
            -
                                    cFmt.setAnchor(True)
         
     | 
| 
       398 
     | 
    
         
            -
                                    cFmt.setAnchorHref(f"#tag_{bit}".lower())
         
     | 
| 
       399 
     | 
    
         
            -
                                    cursor.insertText(bit, cFmt)
         
     | 
| 
       400 
     | 
    
         
            -
                                    if n < num:
         
     | 
| 
       401 
     | 
    
         
            -
                                        cursor.insertText(", ", self._cText)
         
     | 
| 
       402 
     | 
    
         
            -
                    return
         
     | 
| 
       403 
     | 
    
         
            -
             
     | 
| 
       404 
     | 
    
         
            -
                def _genHeadStyle(self, hType: int, nHead: int, rFmt: QTextBlockFormat) -> T_TextStyle:
         
     | 
| 
       405 
     | 
    
         
            -
                    """Generate a heading style set."""
         
     | 
| 
       406 
     | 
    
         
            -
                    mTop, mBottom = self._mHead.get(hType, (0.0, 0.0))
         
     | 
| 
       407 
     | 
    
         
            -
             
     | 
| 
       408 
     | 
    
         
            -
                    bFmt = QTextBlockFormat(rFmt)
         
     | 
| 
       409 
     | 
    
         
            -
                    bFmt.setTopMargin(mTop)
         
     | 
| 
       410 
     | 
    
         
            -
                    bFmt.setBottomMargin(mBottom)
         
     | 
| 
       411 
     | 
    
         
            -
             
     | 
| 
       412 
     | 
    
         
            -
                    cFmt = QTextCharFormat(self._cText if hType == self.T_TITLE else self._cHead)
         
     | 
| 
       413 
     | 
    
         
            -
                    cFmt.setFontWeight(self._bold)
         
     | 
| 
       414 
     | 
    
         
            -
                    cFmt.setFontPointSize(self._sHead.get(hType, 1.0))
         
     | 
| 
       415 
     | 
    
         
            -
                    if nHead >= 0:
         
     | 
| 
       416 
     | 
    
         
            -
                        cFmt.setAnchorNames([f"{self._handle}:T{nHead:04d}"])
         
     | 
| 
       417 
     | 
    
         
            -
                        cFmt.setAnchor(True)
         
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
                    return bFmt, cFmt
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |