Turn main into only release branch (#1408)
This commit is contained in:
@@ -19,22 +19,34 @@ Spell Check Dictionaries
|
||||
novelWriter uses Enchant_ as the spell checking tool. Depending on your operating system, it may or
|
||||
may not load installed spell check dictionaries.
|
||||
|
||||
Linux
|
||||
On Linux, you generally only have to install hunspell or aspell dictionaries on your system like
|
||||
you do for other applications. See your distro's documentation for how to do this. These
|
||||
dictionaries should then show up as available spell check languages in novelWriter.
|
||||
Linux and MacOS
|
||||
---------------
|
||||
|
||||
On Linux and MacOS, you generally only have to install hunspell or aspell dictionaries on your
|
||||
system like you do for other applications. See your distro or OS documentation for how to do this.
|
||||
These dictionaries should then show up as available spell check languages in novelWriter.
|
||||
|
||||
Windows
|
||||
For Windows, English is included with the installation. For other languages you have to download
|
||||
and add dictionaries yourself. You can find the various dictionaries on the `Free Desktop`_
|
||||
website. You should find a folder for your language, if it is available at all, and download the
|
||||
files ending with ``.aff`` and ``.dic``. These files must then be copied to the following
|
||||
location:
|
||||
-------
|
||||
|
||||
``C:\Users\<USER>\AppData\Local\enchant\hunspell``
|
||||
For Windows, English is included with the installation. For other languages you have to download
|
||||
and add dictionaries yourself. You can find the various dictionaries on the `Free Desktop`_
|
||||
website. You should find a folder for your language, if it is available at all, and download the
|
||||
files ending with ``.aff`` and ``.dic``. These files must then be copied to the following location:
|
||||
|
||||
This assumes your user profile is stored at ``C:\Users\<USER>``. The last one or two folders may
|
||||
not exist, so you may need to create them.
|
||||
``C:\Users\<USER>\AppData\Local\enchant\hunspell``
|
||||
|
||||
This assumes your user profile is stored at ``C:\Users\<USER>``. The last one or two folders may
|
||||
not exist, so you may need to create them.
|
||||
|
||||
.. note::
|
||||
|
||||
The Free Desktop link points to a repository, and what may look like file links inside the
|
||||
dictionary folder are actually links to web pages. If you right-click and download those, you
|
||||
get HTML files, not dictionaries!
|
||||
|
||||
In order to download the actual dictionary files, right-click the "plain" label at the end of
|
||||
each line and download that.
|
||||
|
||||
|
||||
.. _a_custom_theme:
|
||||
|
||||
@@ -51,7 +51,7 @@ Merge Multiple Documents Into One
|
||||
If you need to merge a set of documents in your project into a single document, you can achieve
|
||||
this by first making a new folder for just that purpose, and drag all the files you want merged
|
||||
into this folder. Then you can right click the folder, select :guilabel:`Transform` and
|
||||
:guilabel:`Merge Documents in FOlder`.
|
||||
:guilabel:`Merge Documents in Folder`.
|
||||
|
||||
In the dialog that pops up, the documents will be in the same order as in the folder, but you can
|
||||
also rearrange them here of you wish.
|
||||
|
||||
+10
-10
@@ -3352,44 +3352,44 @@
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
@@ -3405,7 +3405,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1207" />
|
||||
<source>Change Label</source>
|
||||
<source>Rename</source>
|
||||
<translation type="unfinished" />
|
||||
</message>
|
||||
<message>
|
||||
|
||||
+9
-9
@@ -3352,44 +3352,44 @@
|
||||
<translation>Neuer Ordner</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation>Derzeit gibt es keinen Papierkorb für dieses Projekt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation>Papierkorb ist bereits leer.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation>Papierkorb leeren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation>{0} Element(e) endgültig löschen?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation>Löschen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation>„{0}“ in den Papierkorb verschieben?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation>Hauptordner können nur gelöscht werden, wenn sie leer sind.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation>„{0}“ endgültig löschen?</translation>
|
||||
</message>
|
||||
|
||||
+9
-9
@@ -3352,44 +3352,44 @@
|
||||
<translation>New Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation>There is currently no Trash folder in this project.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation>The Trash folder is already empty.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation>Empty Trash</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation>Permanently delete {0} file(s) from Trash?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation>Delete</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation>Move '{0}' to Trash?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation>Root folders can only be deleted when they are empty.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation>Permanently delete '{0}'?</translation>
|
||||
</message>
|
||||
|
||||
+10
-10
@@ -1925,7 +1925,7 @@
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/mainmenu.py" line="797" />
|
||||
<source>Check Spelling</source>
|
||||
<translation>Comprobar Ortografía</translation>
|
||||
<translation>Comprobar la Ortografía</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/mainmenu.py" line="805" />
|
||||
@@ -3352,44 +3352,44 @@
|
||||
<translation>Nueva Carpeta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation>No hay actualmente una carpeta Papelera en este proyecto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation>La carpeta Papelera ya está vacía.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation>Vaciar la Papelera</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation>¿Eliminar {0} archivo(s) permanentemente de la Papelera?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation>Eliminar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation>¿Mover '{0}' a la Papelera?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation>Las carpetas raíz sólo pueden eliminarse si están vacías.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation>¿Eliminar Permanentemente '{0}'?</translation>
|
||||
</message>
|
||||
|
||||
+9
-9
@@ -3352,44 +3352,44 @@
|
||||
<translation>Nuova cartella</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation>Al momento non c'è una cartella Cestino in questo progetto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation>La cartella Cestino è già vuota.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation>Svuota il cestino</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation>Eliminare definitivamente {0} file(s) dal cestino?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation>Elimina</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation>Spostare '{0}' nel Cestino?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation>Le cartelle radice possono essere eliminate solo quando sono vuote.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation>Eliminare definitivamente '{0}'?</translation>
|
||||
</message>
|
||||
|
||||
+9
-9
@@ -3352,44 +3352,44 @@
|
||||
<translation>Ny mappe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation>Det er for øyeblikket ingen papirkurv i dette prosjektet.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation>Papirkurven er allerede tom.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation>Tøm papirkurven</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation>Vil du slette {0} filer i papirkurven for godt?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation>Slett</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation>Vil du flytte filen "{0}" til søpla?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation>Rotmapper kan bare slettes når de er tomme.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation>Slette filen "{0}" for godt?</translation>
|
||||
</message>
|
||||
|
||||
+52
-41
@@ -757,32 +757,32 @@
|
||||
<context>
|
||||
<name>GuiDocEditFooter</name>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2924" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2931" />
|
||||
<source>Status</source>
|
||||
<translation>Status</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3073" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3080" />
|
||||
<source>Line: {0} ({1})</source>
|
||||
<translation>Regel: {0} ({1})</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3102" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3109" />
|
||||
<source>Words: {0} ({1})</source>
|
||||
<translation>Woorden: {0} ({1})</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3107" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3114" />
|
||||
<source>Document size is {0} bytes</source>
|
||||
<translation>Document grootte is {0} bytes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3119" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3126" />
|
||||
<source>Words: {0} selected</source>
|
||||
<translation>Woorden: {0} geselecteerd</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3122" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="3129" />
|
||||
<source>Character count: {0}</source>
|
||||
<translation>Aantal tekens: {0}</translation>
|
||||
</message>
|
||||
@@ -790,22 +790,22 @@
|
||||
<context>
|
||||
<name>GuiDocEditHeader</name>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2694" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2701" />
|
||||
<source>Edit document label</source>
|
||||
<translation>Bewerk document label</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2703" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2710" />
|
||||
<source>Search document</source>
|
||||
<translation>Doorzoek document</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2712" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2719" />
|
||||
<source>Toggle Focus Mode</source>
|
||||
<translation>Schakel focus modus in/uit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2721" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2728" />
|
||||
<source>Close the document</source>
|
||||
<translation>Sluit het document</translation>
|
||||
</message>
|
||||
@@ -813,58 +813,58 @@
|
||||
<context>
|
||||
<name>GuiDocEditSearch</name>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2287" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2274" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2294" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2281" />
|
||||
<source>Search</source>
|
||||
<translation>Zoek</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2279" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2286" />
|
||||
<source>Replace</source>
|
||||
<translation>Vervang</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2295" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2302" />
|
||||
<source>Case Sensitive</source>
|
||||
<translation>Hoofdlettergevoelig</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2301" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2308" />
|
||||
<source>Whole Words Only</source>
|
||||
<translation>Alleen hele woorden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2307" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2314" />
|
||||
<source>RegEx Mode</source>
|
||||
<translation>RegEx modus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2313" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2320" />
|
||||
<source>Loop Search</source>
|
||||
<translation>Zoekopdracht lus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2319" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2326" />
|
||||
<source>Search Next File</source>
|
||||
<translation>Doorzoek volgend bestand</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2327" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2334" />
|
||||
<source>Preserve Case</source>
|
||||
<translation>Behoud hoofd/kleine letters</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2335" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2342" />
|
||||
<source>Close Search</source>
|
||||
<translation>Zoekopdracht afsluiten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2351" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2358" />
|
||||
<source>Find in current document</source>
|
||||
<translation>Zoeken in huidige document</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2356" />
|
||||
<location filename="../novelwriter/gui/doceditor.py" line="2363" />
|
||||
<source>Find and replace in current document</source>
|
||||
<translation>Zoek en vervang in huidig document</translation>
|
||||
</message>
|
||||
@@ -2050,55 +2050,66 @@
|
||||
<context>
|
||||
<name>GuiNovelToolBar</name>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="207" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="216" />
|
||||
<source>Outline of {0}</source>
|
||||
<translation>Omlijning van {0}</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="215" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="224" />
|
||||
<source>Novel Root</source>
|
||||
<translation>Roman Hoofdmap</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="221" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="230" />
|
||||
<source>Refresh</source>
|
||||
<translation>Verversen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="228" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="237" />
|
||||
<source>Last Column</source>
|
||||
<translation>Laatste Kolom</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="231" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="240" />
|
||||
<source>Hidden</source>
|
||||
<translation>Verborgen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="232" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="241" />
|
||||
<source>Point of View Character</source>
|
||||
<translation>Perspectief Karakter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="233" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="242" />
|
||||
<source>Focus Character</source>
|
||||
<translation>Focus Karakter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="234" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="243" />
|
||||
<source>Novel Plot</source>
|
||||
<translation>Roman Plot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="237" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="361" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="246" />
|
||||
<source>Column Size</source>
|
||||
<translation>Kolom grootte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="250" />
|
||||
<source>More Options</source>
|
||||
<translation>Meer Opties</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="361" />
|
||||
<source>Maximum column size in %</source>
|
||||
<translation>Maximum kolom grootte in %</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GuiNovelTree</name>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="778" />
|
||||
<location filename="../novelwriter/gui/noveltree.py" line="815" />
|
||||
<source>No meta data</source>
|
||||
<translation>Geen metadata</translation>
|
||||
</message>
|
||||
@@ -3341,44 +3352,44 @@
|
||||
<translation>Nieuwe map</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation>Er is momenteel geen Prullenbak map in dit project.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation>De Prullenbak map is al leeg.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation>Prullenbak legen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation>{0} bestand(en) permanent verwijderen uit de prullenbak?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation>Verwijderen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation>Verplaats '{0}' naar Prullenbak?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation>Root mappen kunnen alleen verwijderd worden wanneer ze leeg zijn.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation>'{0}' permanent verwijderen?</translation>
|
||||
</message>
|
||||
|
||||
+9
-9
@@ -3352,44 +3352,44 @@
|
||||
<translation>Novo Diretório</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="788" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="789" />
|
||||
<source>There is currently no Trash folder in this project.</source>
|
||||
<translation>Não exite um diretório de Lixeira neste projeto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="799" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="800" />
|
||||
<source>The Trash folder is already empty.</source>
|
||||
<translation>O diretório de Lixeira já está vazio.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="1181" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="805" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<source>Empty Trash</source>
|
||||
<translation>Esvaziar a Lixeira</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="806" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="807" />
|
||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||
<translation>Permanentemente remover {0} arquivo(s) da Lixeira?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="908" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="852" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<source>Delete</source>
|
||||
<translation>Excluir</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="853" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="854" />
|
||||
<source>Move '{0}' to Trash?</source>
|
||||
<translation>Mover '{0}' para a Lixeira?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="887" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="888" />
|
||||
<source>Root folders can only be deleted when they are empty.</source>
|
||||
<translation>Os diretórios-raiz só podem ser excluídos quando estiverem vazios.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../novelwriter/gui/projtree.py" line="909" />
|
||||
<location filename="../novelwriter/gui/projtree.py" line="910" />
|
||||
<source>Permanently delete '{0}'?</source>
|
||||
<translation>Excluir permanentemente '{0}?</translation>
|
||||
</message>
|
||||
|
||||
@@ -59,9 +59,9 @@ __license__ = "GPLv3"
|
||||
__author__ = "Veronica Berglyd Olsen"
|
||||
__maintainer__ = "Veronica Berglyd Olsen"
|
||||
__email__ = "code@vkbo.net"
|
||||
__version__ = "2.1-alpha0"
|
||||
__hexversion__ = "0x020100a0"
|
||||
__date__ = "2023-02-12"
|
||||
__version__ = "2.0.6"
|
||||
__hexversion__ = "0x020006f0"
|
||||
__date__ = "2023-02-26"
|
||||
__status__ = "Stable"
|
||||
__domain__ = "novelwriter.io"
|
||||
__url__ = "https://novelwriter.io"
|
||||
@@ -246,6 +246,8 @@ def main(sysArgs=None):
|
||||
nwApp.setApplicationName(CONFIG.appName)
|
||||
nwApp.setApplicationVersion(__version__)
|
||||
nwApp.setOrganizationDomain(__domain__)
|
||||
nwApp.setOrganizationName(__domain__)
|
||||
nwApp.setDesktopFileName(CONFIG.appName)
|
||||
|
||||
# Connect the exception handler before making the main GUI
|
||||
sys.excepthook = exceptionHandler
|
||||
|
||||
@@ -1359,7 +1359,7 @@ class GuiDocEditor(QTextEdit):
|
||||
if self._docHandle is None or self._nwItem is None:
|
||||
return
|
||||
|
||||
logger.debug("User selectee %d words", wCount)
|
||||
logger.debug("User selected %d words", wCount)
|
||||
self.docFooter.updateCounts(wCount=wCount, cCount=cCount)
|
||||
self.wcTimerSel.stop()
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ from PyQt5.QtWidgets import (
|
||||
QMenu, QShortcut, QSizePolicy, QToolButton, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget
|
||||
)
|
||||
from novelwriter.core.item import NWItem
|
||||
|
||||
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout, nwAlert, nwWidget
|
||||
from novelwriter.constants import nwHeaders, nwUnicode, trConst, nwLabels
|
||||
@@ -108,6 +109,9 @@ class GuiProjectView(QWidget):
|
||||
self.keyContext.setContext(Qt.WidgetShortcut)
|
||||
self.keyContext.activated.connect(lambda: self.projTree.openContextOnSelected())
|
||||
|
||||
# Signals
|
||||
self.selectedItemChanged.connect(self.projBar._treeSelectionChanged)
|
||||
|
||||
# Function Mappings
|
||||
self.emptyTrash = self.projTree.emptyTrash
|
||||
self.requestDeleteItem = self.projTree.requestDeleteItem
|
||||
@@ -418,6 +422,23 @@ class GuiProjectToolBar(QWidget):
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Slots
|
||||
##
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _treeSelectionChanged(self, tHandle):
|
||||
"""Toggle the visibility of the new item enties for novel
|
||||
documents. They should only be visible if novel documents can
|
||||
actually be added.
|
||||
"""
|
||||
nwItem = self.theProject.tree[tHandle]
|
||||
allowDoc = isinstance(nwItem, NWItem) and nwItem.documentAllowed()
|
||||
self.aAddEmpty.setVisible(allowDoc)
|
||||
self.aAddChap.setVisible(allowDoc)
|
||||
self.aAddScene.setVisible(allowDoc)
|
||||
return
|
||||
|
||||
# END Class GuiProjectToolBar
|
||||
|
||||
|
||||
@@ -1204,7 +1225,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
# Edit Item Settings
|
||||
# ==================
|
||||
|
||||
aLabel = ctxMenu.addAction(self.tr("Change Label"))
|
||||
aLabel = ctxMenu.addAction(self.tr("Rename"))
|
||||
aLabel.triggered.connect(lambda: self.renameTreeItem(tHandle))
|
||||
|
||||
if isFile:
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
"""
|
||||
novelWriter – Manuscript Build Init File
|
||||
"""
|
||||
@@ -1,241 +0,0 @@
|
||||
"""
|
||||
novelWriter – Build Document Tool
|
||||
=================================
|
||||
A class to build one or more novelWriter files to a single document
|
||||
|
||||
File History:
|
||||
Created: 2022-12-01 [2.1b1]
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2023, Veronica Berglyd Olsen
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import novelwriter
|
||||
|
||||
from PyQt5.QtGui import QFont, QFontInfo
|
||||
|
||||
from novelwriter.error import formatException
|
||||
from novelwriter.core.tomd import ToMarkdown
|
||||
from novelwriter.core.toodt import ToOdt
|
||||
from novelwriter.core.tohtml import ToHtml
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NWBuildDocument:
|
||||
|
||||
def __init__(self, project):
|
||||
|
||||
self._conf = novelwriter.CONFIG
|
||||
self._project = project
|
||||
self._build = {}
|
||||
self._documents = []
|
||||
self._error = None
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Properties
|
||||
##
|
||||
|
||||
@property
|
||||
def error(self):
|
||||
return self._error
|
||||
|
||||
@property
|
||||
def buildLength(self):
|
||||
return len(self._documents)
|
||||
|
||||
##
|
||||
# Setters
|
||||
##
|
||||
|
||||
def setBuildConfig(self, config):
|
||||
"""Set the build config dictionary.
|
||||
"""
|
||||
self._build = config
|
||||
return
|
||||
|
||||
def addDocument(self, tHandle):
|
||||
"""Add a document to the build queue.
|
||||
"""
|
||||
self._documents.append(tHandle)
|
||||
return
|
||||
|
||||
##
|
||||
# Methods
|
||||
##
|
||||
|
||||
def iterBuildOpenDocument(self, savePath, isFlat):
|
||||
"""Build an Open Document file.
|
||||
"""
|
||||
makeOdt = ToOdt(self._project, isFlat=isFlat)
|
||||
self._setupBuild(makeOdt)
|
||||
makeOdt.initDocument()
|
||||
|
||||
for i, tHandle in enumerate(self._documents):
|
||||
yield i, self._doBuild(makeOdt, tHandle)
|
||||
|
||||
makeOdt.closeDocument()
|
||||
|
||||
self._error = None
|
||||
try:
|
||||
if isFlat:
|
||||
makeOdt.saveFlatXML(savePath)
|
||||
else:
|
||||
makeOdt.saveOpenDocText(savePath)
|
||||
except Exception as exc:
|
||||
self._error = formatException(exc)
|
||||
|
||||
return
|
||||
|
||||
def iterBuildHTML(self, savePath):
|
||||
"""Build an HTML file.
|
||||
"""
|
||||
makeHtml = ToHtml(self._project)
|
||||
self._setupBuild(makeHtml)
|
||||
|
||||
if self._build.get("process.replaceTabs", False):
|
||||
makeHtml.replaceTabs()
|
||||
|
||||
for i, tHandle in enumerate(self._documents):
|
||||
yield i, self._doBuild(makeHtml, tHandle)
|
||||
|
||||
self._error = None
|
||||
try:
|
||||
makeHtml.saveHTML5(savePath)
|
||||
except Exception as exc:
|
||||
self._error = formatException(exc)
|
||||
|
||||
return
|
||||
|
||||
def iterBuildMarkdown(self, savePath, extendedMd):
|
||||
"""Build a Markdown file.
|
||||
"""
|
||||
makeMd = ToMarkdown(self._project)
|
||||
self._setupBuild(makeMd)
|
||||
|
||||
if extendedMd:
|
||||
makeMd.setGitHubMarkdown()
|
||||
else:
|
||||
makeMd.setStandardMarkdown()
|
||||
|
||||
if self._build.get("process.replaceTabs", False):
|
||||
makeMd.replaceTabs(nSpaces=4, spaceChar=" ")
|
||||
|
||||
for i, tHandle in enumerate(self._documents):
|
||||
yield i, self._doBuild(makeMd, tHandle)
|
||||
|
||||
self._error = None
|
||||
try:
|
||||
makeMd.saveMarkdown(savePath)
|
||||
except Exception as exc:
|
||||
self._error = formatException(exc)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _setupBuild(self, bldObj):
|
||||
"""Configure the build object.
|
||||
"""
|
||||
# Get Settings
|
||||
fmtTitle = self._build.get("format.fmtTitle", "%title%")
|
||||
fmtChapter = self._build.get("format.fmtChapter", "%title%")
|
||||
fmtUnnumbered = self._build.get("format.fmtUnnumbered", "%title%")
|
||||
fmtScene = self._build.get("format.fmtScene", "%title%")
|
||||
fmtSection = self._build.get("format.fmtSection", "%title%")
|
||||
buildLang = self._build.get("format.buildLang", "en_GB")
|
||||
hideScene = self._build.get("format.hideScene", False)
|
||||
hideSection = self._build.get("format.hideSection", False)
|
||||
textFont = self._build.get("format.textFont", self._conf.textFont)
|
||||
textSize = self._build.get("format.textSize", self._conf.textSize)
|
||||
lineHeight = self._build.get("format.lineHeight", 1.15)
|
||||
justifyText = self._build.get("format.justifyText", False)
|
||||
noStyling = self._build.get("format.noStyling", False)
|
||||
replaceUCode = self._build.get("format.replaceUCode", False)
|
||||
incSynopsis = self._build.get("filter.includeSynopsis", False)
|
||||
incComments = self._build.get("filter.includeComments", False)
|
||||
incKeywords = self._build.get("filter.includeKeywords", False)
|
||||
includeBody = self._build.get("filter.includeBody", True)
|
||||
|
||||
# The language lookup dict is reloaded if needed
|
||||
self._project.setProjectLang(buildLang)
|
||||
|
||||
# Get font information
|
||||
fontInfo = QFontInfo(QFont(textFont, textSize))
|
||||
textFixed = fontInfo.fixedPitch()
|
||||
|
||||
bldObj.setTitleFormat(fmtTitle)
|
||||
bldObj.setChapterFormat(fmtChapter)
|
||||
bldObj.setUnNumberedFormat(fmtUnnumbered)
|
||||
bldObj.setSceneFormat(fmtScene, hideScene)
|
||||
bldObj.setSectionFormat(fmtSection, hideSection)
|
||||
|
||||
bldObj.setFont(textFont, textSize, textFixed)
|
||||
bldObj.setJustify(justifyText)
|
||||
bldObj.setLineHeight(lineHeight)
|
||||
|
||||
bldObj.setSynopsis(incSynopsis)
|
||||
bldObj.setComments(incComments)
|
||||
bldObj.setKeywords(incKeywords)
|
||||
bldObj.setBodyText(includeBody)
|
||||
|
||||
if isinstance(bldObj, ToHtml):
|
||||
bldObj.setStyles(not noStyling)
|
||||
bldObj.setReplaceUnicode(replaceUCode)
|
||||
|
||||
if isinstance(bldObj, ToOdt):
|
||||
bldObj.setColourHeaders(not noStyling)
|
||||
bldObj.setLanguage(buildLang)
|
||||
|
||||
return
|
||||
|
||||
def _doBuild(self, bldObj, tHandle):
|
||||
"""Build a single document and add it to the build object.
|
||||
"""
|
||||
self._error = None
|
||||
tItem = self._project.tree[tHandle]
|
||||
if tItem is None:
|
||||
self._error = f"Build: Unknown item '{tHandle}'"
|
||||
logger.error(self._error)
|
||||
return False
|
||||
|
||||
try:
|
||||
if tItem.isRootType() and not tItem.isNovelLike():
|
||||
bldObj.addRootHeading(tItem.itemHandle)
|
||||
bldObj.doConvert()
|
||||
elif tItem.isFileType():
|
||||
bldObj.setText(tHandle)
|
||||
bldObj.doPreProcessing()
|
||||
bldObj.tokenizeText()
|
||||
bldObj.doHeaders()
|
||||
bldObj.doConvert()
|
||||
bldObj.doPostProcessing()
|
||||
else:
|
||||
logger.info(f"Build: Skipping '{tHandle}'")
|
||||
|
||||
except Exception:
|
||||
self._error = f"Build: Failed to build '{tHandle}'"
|
||||
logger.error(self._error)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
# END Class NWBuildDocument
|
||||
@@ -1,282 +0,0 @@
|
||||
"""
|
||||
novelWriter – Manuscript Builder Class Tests
|
||||
============================================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2023, Veronica Berglyd Olsen
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from shutil import copyfile
|
||||
|
||||
from mock import causeException, causeOSError
|
||||
from tools import ODT_IGNORE, cmpFiles
|
||||
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.mbuild.docbuild import NWBuildDocument
|
||||
|
||||
BUILD_CONF = {
|
||||
"format.fmtTitle": "Title: %title%",
|
||||
"format.fmtChapter": "Chapter: %title%",
|
||||
"format.fmtUnnumbered": "%title%",
|
||||
"format.fmtScene": "Scene: %title%",
|
||||
"format.fmtSection": "Section: %title%",
|
||||
"format.buildLang": "en_GB",
|
||||
"format.hideScene": False,
|
||||
"format.hideSection": False,
|
||||
"format.textFont": "Arial",
|
||||
"format.textSize": 12,
|
||||
"format.lineHeight": 1.5,
|
||||
"format.justifyText": True,
|
||||
"format.noStyling": False,
|
||||
"format.replaceUCode": False,
|
||||
"filter.includeSynopsis": True,
|
||||
"filter.includeComments": True,
|
||||
"filter.includeKeywords": True,
|
||||
"filter.includeBody": True,
|
||||
"process.replaceTabs": True,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testMBuildDocBuild_OpenDocument(monkeypatch, mockGUI, prjLipsum, fncPath, tstPaths):
|
||||
"""Test builing an open document manuscript.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theProject.openProject(prjLipsum)
|
||||
|
||||
docBuild = NWBuildDocument(theProject)
|
||||
docBuild.setBuildConfig(BUILD_CONF)
|
||||
|
||||
for tItem in theProject.tree:
|
||||
docBuild.addDocument(tItem.itemHandle)
|
||||
|
||||
assert docBuild.buildLength == 21
|
||||
|
||||
# Check FODT Build
|
||||
# ================
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum.fodt"
|
||||
tstFile = tstPaths.outDir / "mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt"
|
||||
cmpFile = tstPaths.refDir / "mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt"
|
||||
|
||||
count = 0
|
||||
error = []
|
||||
for _, success in docBuild.iterBuildOpenDocument(docFile, True):
|
||||
count += 1 if success else 0
|
||||
if docBuild.error:
|
||||
error.append(docBuild.error)
|
||||
|
||||
assert count == 21
|
||||
assert error == []
|
||||
|
||||
copyfile(docFile, tstFile)
|
||||
assert cmpFiles(tstFile, cmpFile, ignoreStart=ODT_IGNORE)
|
||||
|
||||
# Check ODT Build
|
||||
# ===============
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum.odt"
|
||||
|
||||
count = 0
|
||||
error = []
|
||||
for _, success in docBuild.iterBuildOpenDocument(docFile, False):
|
||||
count += 1 if success else 0
|
||||
if docBuild.error:
|
||||
error.append(docBuild.error)
|
||||
|
||||
assert count == 21
|
||||
assert error == []
|
||||
|
||||
assert docFile.is_file()
|
||||
|
||||
# Check Error Handling
|
||||
# ====================
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum Err.fodt"
|
||||
for _ in docBuild.iterBuildOpenDocument(docFile, True):
|
||||
pass
|
||||
|
||||
assert docBuild.error == "OSError: Mock OSError"
|
||||
assert not docFile.is_file()
|
||||
|
||||
# Check Build Issues
|
||||
# ==================
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("novelwriter.core.toodt.ToOdt.doConvert", causeException)
|
||||
|
||||
docBuild.addDocument("0000000000000")
|
||||
assert docBuild.buildLength == 22
|
||||
|
||||
count = 0
|
||||
error = []
|
||||
docFile = fncPath / "Lorem Ipsum Err.fodt"
|
||||
for _, success in docBuild.iterBuildOpenDocument(docFile, True):
|
||||
count += 1 if success else 0
|
||||
if docBuild.error:
|
||||
error.append(docBuild.error)
|
||||
|
||||
assert count == 3
|
||||
assert error == [
|
||||
"Build: Failed to build '7a992350f3eb6'",
|
||||
"Build: Failed to build '8c58a65414c23'",
|
||||
"Build: Failed to build '88d59a277361b'",
|
||||
"Build: Failed to build 'db7e733775d4d'",
|
||||
"Build: Failed to build 'fb609cd8319dc'",
|
||||
"Build: Failed to build '88243afbe5ed8'",
|
||||
"Build: Failed to build 'f96ec11c6a3da'",
|
||||
"Build: Failed to build '846352075de7d'",
|
||||
"Build: Failed to build '441420a886d82'",
|
||||
"Build: Failed to build 'eb103bc70c90c'",
|
||||
"Build: Failed to build 'f8c0562e50f1b'",
|
||||
"Build: Failed to build '47666c91c7ccf'",
|
||||
"Build: Failed to build '67a8707f2f249'",
|
||||
"Build: Failed to build '4c4f28287af27'",
|
||||
"Build: Failed to build '6c6afb1247750'",
|
||||
"Build: Failed to build '2426c6f0ca922'",
|
||||
"Build: Failed to build '60bdf227455cc'",
|
||||
"Build: Failed to build '04468803b92e1'",
|
||||
"Build: Unknown item '0000000000000'",
|
||||
]
|
||||
|
||||
# END Test testMBuildDocBuild_OpenDocument
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testMBuildDocBuild_HTML(monkeypatch, mockGUI, prjLipsum, fncPath, tstPaths):
|
||||
"""Test builing an HTML manuscript.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theProject.openProject(prjLipsum)
|
||||
|
||||
docBuild = NWBuildDocument(theProject)
|
||||
docBuild.setBuildConfig(BUILD_CONF)
|
||||
|
||||
for tItem in theProject.tree:
|
||||
docBuild.addDocument(tItem.itemHandle)
|
||||
|
||||
assert docBuild.buildLength == 21
|
||||
|
||||
# Check HTML5 Build
|
||||
# =================
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum.htm"
|
||||
tstFile = tstPaths.outDir / "mBuildDocBuild_HTML5_Lorem_Ipsum.htm"
|
||||
cmpFile = tstPaths.refDir / "mBuildDocBuild_HTML5_Lorem_Ipsum.htm"
|
||||
|
||||
count = 0
|
||||
error = []
|
||||
for _, success in docBuild.iterBuildHTML(docFile):
|
||||
count += 1 if success else 0
|
||||
if docBuild.error:
|
||||
error.append(docBuild.error)
|
||||
|
||||
assert count == 21
|
||||
assert error == []
|
||||
|
||||
copyfile(docFile, tstFile)
|
||||
assert cmpFiles(tstFile, cmpFile)
|
||||
|
||||
# Check Error Handling
|
||||
# ====================
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum Err.htm"
|
||||
for _ in docBuild.iterBuildHTML(docFile):
|
||||
pass
|
||||
|
||||
assert docBuild.error == "OSError: Mock OSError"
|
||||
assert not docFile.is_file()
|
||||
|
||||
# END Test testMBuildDocBuild_HTML
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testMBuildDocBuild_Markdown(monkeypatch, mockGUI, prjLipsum, fncPath, tstPaths):
|
||||
"""Test builing an Markdown manuscript.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theProject.openProject(prjLipsum)
|
||||
|
||||
docBuild = NWBuildDocument(theProject)
|
||||
docBuild.setBuildConfig(BUILD_CONF)
|
||||
|
||||
for tItem in theProject.tree:
|
||||
docBuild.addDocument(tItem.itemHandle)
|
||||
|
||||
assert docBuild.buildLength == 21
|
||||
|
||||
# Check Standard Markdown Build
|
||||
# =============================
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum Standard.md"
|
||||
tstFile = tstPaths.outDir / "mBuildDocBuild_Standard_Markdown_Lorem_Ipsum.md"
|
||||
cmpFile = tstPaths.refDir / "mBuildDocBuild_Standard_Markdown_Lorem_Ipsum.md"
|
||||
|
||||
count = 0
|
||||
error = []
|
||||
for _, success in docBuild.iterBuildMarkdown(docFile, False):
|
||||
count += 1 if success else 0
|
||||
if docBuild.error:
|
||||
error.append(docBuild.error)
|
||||
|
||||
assert count == 21
|
||||
assert error == []
|
||||
|
||||
copyfile(docFile, tstFile)
|
||||
assert cmpFiles(tstFile, cmpFile)
|
||||
|
||||
# Check Extended Markdown Build
|
||||
# =============================
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum Standard.md"
|
||||
tstFile = tstPaths.outDir / "mBuildDocBuild_Extended_Markdown_Lorem_Ipsum.md"
|
||||
cmpFile = tstPaths.refDir / "mBuildDocBuild_Extended_Markdown_Lorem_Ipsum.md"
|
||||
|
||||
count = 0
|
||||
error = []
|
||||
for _, success in docBuild.iterBuildMarkdown(docFile, True):
|
||||
count += 1 if success else 0
|
||||
if docBuild.error:
|
||||
error.append(docBuild.error)
|
||||
|
||||
assert count == 21
|
||||
assert error == []
|
||||
|
||||
copyfile(docFile, tstFile)
|
||||
assert cmpFiles(tstFile, cmpFile)
|
||||
|
||||
# Check Error Handling
|
||||
# ====================
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
|
||||
docFile = fncPath / "Lorem Ipsum Err.md"
|
||||
for _ in docBuild.iterBuildMarkdown(docFile, False):
|
||||
pass
|
||||
|
||||
assert docBuild.error == "OSError: Mock OSError"
|
||||
assert not docFile.is_file()
|
||||
|
||||
# END Test testMBuildDocBuild_Markdown
|
||||
Reference in New Issue
Block a user