Compare commits

...

314 Commits
v2.2 ... v2.3.1

Author SHA1 Message Date
Veronica Berglyd Olsen
cfcf05fdad Release 2.3.1 (#1762) 2024-03-17 11:13:04 +01:00
Veronica Berglyd Olsen
423bde0c03 Bump version to 2.3.1 and update release notes 2024-03-17 11:00:37 +01:00
Veronica Berglyd Olsen
c254581a3f Prepare for release 2.3.1 (#1760) 2024-03-17 10:48:07 +01:00
Veronica Berglyd Olsen
ca27dc65b7 Update translation files, and complete French, Dutch and Spanish 2024-03-17 10:44:40 +01:00
Veronica Berglyd Olsen
cdb84851b2 Revert "Simplify the ODT header format" (#1758) 2024-03-17 10:42:27 +01:00
Veronica Berglyd Olsen
439938ba58 Update Italian and Japanese translations 2024-03-14 22:11:56 +01:00
Veronica Berglyd Olsen
4defc1d4a3 Simplify the ODT header format (#1758) 2024-03-13 16:34:48 +01:00
Veronica Berglyd Olsen
fb7bf6fb98 Simplify the ODT header format 2024-03-13 16:24:56 +01:00
Veronica Berglyd Olsen
9a9b2c6d2f Fix i18n issues (#1754) 2024-03-12 21:03:28 +01:00
Veronica Berglyd Olsen
37c935d027 Update US English, Norwegian and German translations 2024-03-12 21:00:46 +01:00
Veronica Berglyd Olsen
1279834849 Improve the custom widget docstring 2024-03-12 20:54:54 +01:00
Veronica Berglyd Olsen
ea50ae3279 Add a custom box layout for the wrapped widget 2024-03-12 19:10:48 +01:00
Veronica Berglyd Olsen
f51720dbd8 Update base translation file 2024-03-12 18:48:26 +01:00
Veronica Berglyd Olsen
d090230b67 Make it optional to split string for chapter and scene count on welcome dialog (#1750) 2024-03-12 18:41:16 +01:00
Veronica Berglyd Olsen
6a3f6048c2 Fix malformed translation string (#1749) 2024-03-12 18:27:15 +01:00
Veronica Berglyd Olsen
d15e4ebb17 Bump project file format revision (#1748) 2024-03-11 16:39:18 +01:00
Veronica Berglyd Olsen
d6fae17b3b Update tests 2024-03-11 16:34:50 +01:00
Veronica Berglyd Olsen
dd82c935e5 Set new revision number 2024-03-11 16:34:44 +01:00
Veronica Berglyd Olsen
bc414246d2 Update file format spec 2024-03-11 16:34:05 +01:00
Veronica Berglyd Olsen
27ea697b90 Fix i18n issues (#1744) 2024-03-11 08:48:49 +01:00
Veronica Berglyd Olsen
f38f25f65a Update translation files 2024-03-10 16:20:54 +01:00
Veronica Berglyd Olsen
3edb76abbf Fix missing translation in Project Word List 2024-03-10 14:52:10 +01:00
Veronica Berglyd Olsen
a5064d6237 Release 2.3 (#1742) 2024-03-10 12:41:19 +01:00
Veronica Berglyd Olsen
483a9aedfd Bump version and update changelog 2024-03-10 12:01:50 +01:00
Veronica Berglyd Olsen
98f94efbdd Update i18n (#1741) 2024-03-10 11:28:45 +01:00
Veronica Berglyd Olsen
3335c08a42 Merge branch 'main' into update_i18n 2024-03-10 11:26:38 +01:00
Veronica Berglyd Olsen
013e94afc9 Update documentation (#1703) 2024-03-09 21:00:42 +01:00
Veronica Berglyd Olsen
7829c894ff Add the new additional section 2024-03-09 20:58:43 +01:00
Veronica Berglyd Olsen
924bf67bfb Update the project section 2024-03-09 20:56:44 +01:00
Veronica Berglyd Olsen
7aea468103 Update the usage section 2024-03-09 19:59:12 +01:00
Veronica Berglyd Olsen
9336410180 Update the introduction section 2024-03-09 18:33:37 +01:00
Veronica Berglyd Olsen
22162d3915 Merge branch 'main' into update_docs 2024-03-09 17:39:05 +01:00
Veronica Berglyd Olsen
edf4256648 Refresh translation files 2024-03-09 17:25:55 +01:00
Veronica Berglyd Olsen
29f9ea2a55 Update German and Spanish translations 2024-03-09 17:25:41 +01:00
Veronica Berglyd Olsen
8d614c2aeb Improve Open Project error handling (#1740) 2024-03-09 12:50:48 +01:00
Veronica Berglyd Olsen
604df85e62 Open welcome dialog again if no project was opened 2024-03-09 12:39:11 +01:00
Veronica Berglyd Olsen
075a9bf850 Be a bit more precise on open project errors (#1737) 2024-03-09 12:12:19 +01:00
Veronica Berglyd Olsen
02f20b7a4f Add more syntax themes (#1738) 2024-03-09 11:52:44 +01:00
Veronica Berglyd Olsen
5df369a831 Add Tango syntax colour theme 2024-03-09 11:49:06 +01:00
Veronica Berglyd Olsen
ead1740f83 Update test 2024-03-09 10:44:24 +01:00
Veronica Berglyd Olsen
791eebe8a6 Add custom sorting function so that default themes come first 2024-03-09 10:36:59 +01:00
Veronica Berglyd Olsen
5178c41e54 Add cyberpunk night theme by @alemvigh (#1730) 2024-03-09 10:17:22 +01:00
Veronica Berglyd Olsen
4c55bfe49f Remove the cli entry in setup.cfg (#1734) 2024-03-07 16:18:03 +01:00
Veronica Berglyd Olsen
7137494740 Remove the novelwriter-cli entry point (#1732) 2024-03-07 16:12:38 +01:00
Veronica Berglyd Olsen
a3bd0d38a4 Fix Trash and Delete entries for multi-select (#1728) 2024-03-03 21:30:59 +01:00
Veronica Berglyd Olsen
925d9fd5ad Update translations 2024-03-03 21:25:49 +01:00
Veronica Berglyd Olsen
d12e626bc4 Update tests 2024-03-03 21:17:18 +01:00
Veronica Berglyd Olsen
c182cc4383 Fix move to trash and permanently delete for multi select menu 2024-03-03 21:16:46 +01:00
Veronica Berglyd Olsen
750ba36d32 Emit clear index signal when project is closed (#1720) 2024-02-29 23:10:05 +01:00
Veronica Berglyd Olsen
72b14ff08c Clean up imports 2024-02-29 23:07:22 +01:00
Veronica Berglyd Olsen
4ac050fe75 Add regression test 2024-02-29 23:06:19 +01:00
Veronica Berglyd Olsen
311b611afe Clear index when closing project (#1718) 2024-02-29 22:58:52 +01:00
Veronica Berglyd Olsen
37e2392237 Update i18n (#1714) 2024-02-28 17:08:49 +01:00
Veronica Berglyd Olsen
a1e6398116 Merge branch 'main' into update_i18n 2024-02-28 16:58:06 +01:00
Veronica Berglyd Olsen
b0b1c0d386 Improve i18n tests 2024-02-28 16:53:29 +01:00
Veronica Berglyd Olsen
56ed4b88f8 Update Dutch translation 2024-02-27 19:44:38 +01:00
Veronica Berglyd Olsen
5f79186d10 Remove scene separator insertion after text (#1716) 2024-02-25 22:56:50 +01:00
Veronica Berglyd Olsen
87a1bb050e Update tests 2024-02-25 22:49:27 +01:00
Veronica Berglyd Olsen
de16d2d6a1 Make plain text not affect scene separator insertion 2024-02-25 22:49:12 +01:00
Veronica Berglyd Olsen
4fa21107ee Update Italian translation 2024-02-25 18:07:33 +01:00
Veronica Berglyd Olsen
97371533bc Update Japanese translation, and fix line numbers in others 2024-02-25 10:51:42 +01:00
Veronica Berglyd Olsen
c3cf69cbe6 Update Norwegian and US English, and Dutch and Portuguese project translations 2024-02-24 18:22:31 +01:00
Veronica Berglyd Olsen
1353eaa460 Update base translation and fix tr string issues 2024-02-24 18:20:09 +01:00
Veronica Berglyd Olsen
4273ba5158 Release 2.3 RC 1 (#1712) 2024-02-24 16:00:49 +01:00
Veronica Berglyd Olsen
368cbdc62c Bump version and update changelog 2024-02-24 15:57:33 +01:00
Veronica Berglyd Olsen
b0614e8c25 Fix scene separators and chapter and scene counters (#1711) 2024-02-24 15:32:50 +01:00
Veronica Berglyd Olsen
6ef646acb2 Simplify the scene separator handler 2024-02-24 15:29:58 +01:00
Veronica Berglyd Olsen
6db7f049bc Add test coverage 2024-02-24 15:24:31 +01:00
Veronica Berglyd Olsen
404b102a54 Rename some variables in the tokenizer 2024-02-24 14:44:11 +01:00
Veronica Berglyd Olsen
ef84588145 Make sure scene and chapter info is properly reset on headers in the tokenizer 2024-02-24 14:29:13 +01:00
Veronica Berglyd Olsen
eb105951ac Clean up the tokenizer code a little 2024-02-24 14:28:12 +01:00
Veronica Berglyd Olsen
9f6a1b4bc0 Update design elements (#1709) 2024-02-21 17:47:29 +01:00
Veronica Berglyd Olsen
dfd4df46ce Drop the welcome dialog help text now that the language option has been dropped 2024-02-21 17:45:01 +01:00
Veronica Berglyd Olsen
3c8e3b3653 Rename buttons on welcome dialog 2024-02-21 17:39:28 +01:00
Veronica Berglyd Olsen
6500975cc3 Replace template root folder icon 2024-02-21 17:39:10 +01:00
Veronica Berglyd Olsen
2fb87c415e Fix various issues on the Welcome dialog (#1707) 2024-02-20 23:34:23 +01:00
Veronica Berglyd Olsen
996f48a85f Make some minor fixes to the welcome dialog source 2024-02-20 23:31:18 +01:00
Veronica Berglyd Olsen
1c91ba6fd9 Fix welcome dialog tests 2024-02-20 23:21:02 +01:00
Veronica Berglyd Olsen
10764a2041 Block overwriting when creating sample project 2024-02-20 23:20:49 +01:00
Veronica Berglyd Olsen
576c13d045 Redesign button row on welcome dialog 2024-02-20 23:10:08 +01:00
Veronica Berglyd Olsen
f0e86dad10 Drop language setting on new project form 2024-02-20 23:07:32 +01:00
Veronica Berglyd Olsen
4bf82e4df7 Hide unused controls on new project form 2024-02-20 23:03:57 +01:00
Veronica Berglyd Olsen
eab8bb2351 Block welcome dialog open button when project list is not visible 2024-02-20 12:48:14 +01:00
Veronica Berglyd Olsen
02d805122f Fix typo 2024-02-18 21:14:45 +01:00
Veronica Berglyd Olsen
595fd01863 Fix some typos on the tags and references docs 2024-02-18 18:24:48 +01:00
Veronica Berglyd Olsen
7b8b303886 Use markdown formatting on example text in docs 2024-02-16 21:58:11 +01:00
Veronica Berglyd Olsen
8b701f8651 Post release fixes for 2.3b1 (#1700) 2024-02-16 21:07:11 +01:00
Veronica Berglyd Olsen
e6071e613b Update windows package installer 2024-02-16 21:01:30 +01:00
Veronica Berglyd Olsen
75de1a1888 Release 2.3 Beta 1 (#1698) 2024-02-16 18:39:14 +01:00
Veronica Berglyd Olsen
f25c172705 Bump version to 2.3b1 and update changelog 2024-02-15 22:56:19 +01:00
Veronica Berglyd Olsen
b741b21db8 Add CSV export for Outline View (#1697) 2024-02-15 22:07:32 +01:00
Veronica Berglyd Olsen
a350d38d4e Fix CSV newlines on Windows 2024-02-15 22:04:16 +01:00
Veronica Berglyd Olsen
2e55d28a10 Improve the test file compare function 2024-02-15 21:46:35 +01:00
Veronica Berglyd Olsen
76864f2a2f Update test coverage 2024-02-15 21:34:19 +01:00
Veronica Berglyd Olsen
25b6d1c001 Add CSV export to outline 2024-02-15 21:09:41 +01:00
Veronica Berglyd Olsen
1a635f60a9 Rewrite checking for updates (#1696) 2024-02-14 23:35:32 +01:00
Veronica Berglyd Olsen
c6524d02ea Delete the old updates dialog 2024-02-14 23:22:43 +01:00
Veronica Berglyd Olsen
ed7dde2aaa Add test coverage 2024-02-14 23:19:25 +01:00
Veronica Berglyd Olsen
5917c9da08 Change version checker to use regular GitHub API 2024-02-14 21:46:10 +01:00
Veronica Berglyd Olsen
3a1f77b8f8 Make the new version lookup run in the background 2024-02-14 18:55:01 +01:00
Veronica Berglyd Olsen
bdf100e608 Add more subtle link colours to themes 2024-02-14 18:32:28 +01:00
Veronica Berglyd Olsen
f8d57539d4 Add a version info widget 2024-02-14 18:32:09 +01:00
Veronica Berglyd Olsen
453a228182 Simplify the About dialog (#1695) 2024-02-13 18:26:42 +01:00
Veronica Berglyd Olsen
ea14f06245 Update credits 2024-02-13 18:15:27 +01:00
Veronica Berglyd Olsen
5e9d96788e Update tests 2024-02-13 18:10:24 +01:00
Veronica Berglyd Olsen
b793842f6d Simplify the About dialog to only show credits 2024-02-13 18:04:41 +01:00
Veronica Berglyd Olsen
827702159d Change the new release info to a simple pop-up dialog 2024-02-13 18:04:12 +01:00
Veronica Berglyd Olsen
17aae16345 Fix deprecated typing (#1694) 2024-02-13 14:10:56 +01:00
Veronica Berglyd Olsen
16d2f1cc2a Fix new linting errors 2024-02-13 14:06:32 +01:00
Veronica Berglyd Olsen
e778d05ee3 Add PEP585 checks to linting checks 2024-02-13 14:06:22 +01:00
Veronica Berglyd Olsen
fb92c6c333 Add formatter helper for file extensions filters (#1693) 2024-02-11 21:08:08 +01:00
Veronica Berglyd Olsen
701fe29de9 Add the file filter function where needed 2024-02-11 20:59:29 +01:00
Veronica Berglyd Olsen
642b5e3681 Add a formatting function for file extension filters for file dialogs 2024-02-11 20:57:27 +01:00
Veronica Berglyd Olsen
81a9d51986 Add context menu option to rename item to first heading (#1692) 2024-02-11 20:05:01 +01:00
Veronica Berglyd Olsen
e6efd15b9a Update test 2024-02-11 19:58:51 +01:00
Veronica Berglyd Olsen
f883de6e03 Add context menu option to rename item to header text 2024-02-11 19:56:46 +01:00
Veronica Berglyd Olsen
dc661b7a70 Add import and export to project word list (#1691) 2024-02-11 19:37:35 +01:00
Veronica Berglyd Olsen
edfb4e60c6 Use the same header label style as on other dialogs 2024-02-11 19:15:18 +01:00
Veronica Berglyd Olsen
e185f87875 Add test coverage 2024-02-11 19:09:40 +01:00
Veronica Berglyd Olsen
ce3a8f56c8 Add import icon 2024-02-11 18:55:27 +01:00
Veronica Berglyd Olsen
23b7baf62c Add import and export feature to word list 2024-02-11 00:52:20 +01:00
Veronica Berglyd Olsen
56cb545fab Bump version to 2.3 Alpha 5 2024-02-10 18:42:27 +01:00
Veronica Berglyd Olsen
71c4d7aa94 Update welcome dialog (#1689) 2024-02-10 18:39:36 +01:00
Veronica Berglyd Olsen
c8b1a10f26 Merge branch 'dev' into update_welcome 2024-02-10 18:37:45 +01:00
Veronica Berglyd Olsen
e9e4788602 Add an ignore text format and allow multi-paragraph formatting (#1690) 2024-02-10 18:31:48 +01:00
Veronica Berglyd Olsen
2f20266602 Use regular block format function for single block 2024-02-10 18:26:18 +01:00
Veronica Berglyd Olsen
1c3b252b6b Add test coverage of multi-block formatting 2024-02-10 18:22:21 +01:00
Veronica Berglyd Olsen
bc2f91e54f Allow comment, ignore and clear formatting to be applied to all selected text 2024-02-10 18:20:51 +01:00
Veronica Berglyd Olsen
8a41748173 Refactor block formatting to support multi-block selections 2024-02-10 16:43:12 +01:00
Veronica Berglyd Olsen
c3e6b4e10a Update tests 2024-02-10 15:49:49 +01:00
Veronica Berglyd Olsen
9c1bdef9ad Add block format that completely ignores a line of text in the tokenizer 2024-02-10 15:40:30 +01:00
Veronica Berglyd Olsen
fe22949cb4 Add an indicator for missing project paths in welcome dialog 2024-02-10 12:20:38 +01:00
Veronica Berglyd Olsen
a9bda1deed Update welcome dialog illustration 2024-02-10 00:03:08 +01:00
Veronica Berglyd Olsen
492dd58068 Change the scaling and margins of the welcome dialog 2024-02-09 23:26:53 +01:00
Veronica Berglyd Olsen
186cead603 Remove the width setting from the switch widget 2024-02-09 23:26:26 +01:00
Veronica Berglyd Olsen
467772c489 Add file template feature (#1688) 2024-02-08 23:17:18 +01:00
Veronica Berglyd Olsen
8ff292fec8 Add test coverage of template feature 2024-02-08 23:10:20 +01:00
Veronica Berglyd Olsen
4113be7a4c Allow filtering templates by setting them to inactive 2024-02-08 22:12:05 +01:00
Veronica Berglyd Olsen
0aaf42de21 Connect the bits for the file template feature 2024-02-08 21:49:07 +01:00
Veronica Berglyd Olsen
d9a5db5884 Add file copy feature to project class 2024-02-08 21:37:53 +01:00
Veronica Berglyd Olsen
fe8a112328 Add a custom templates menu to project tree add items 2024-02-08 00:06:01 +01:00
Veronica Berglyd Olsen
bbb23b4bc9 Fix some widgets without parent, and update template file record keeping 2024-02-07 20:37:53 +01:00
Veronica Berglyd Olsen
c420d8ae38 Add template icon 2024-02-07 20:36:39 +01:00
Veronica Berglyd Olsen
e78545fcdb Don't highlight tags in inactive files 2024-02-03 17:00:27 +01:00
Veronica Berglyd Olsen
0a1c5b20ed Merge branch 'dev' into doc_templates 2024-02-03 16:38:09 +01:00
Veronica Berglyd Olsen
321e57a3b7 Add creating new project from zipped existing project (#1684) 2024-02-03 15:40:06 +01:00
Veronica Berglyd Olsen
4d016c3b75 Clean up top level window access and add coverage to shared data class 2024-02-03 15:34:33 +01:00
Veronica Berglyd Olsen
d5064a8333 Add test for new project creation path 2024-02-03 15:34:08 +01:00
Veronica Berglyd Olsen
a11657c145 Allow creating new project from zip archive 2024-02-03 14:54:01 +01:00
Veronica Berglyd Olsen
64889ac5d8 Add a templates root folder 2024-02-02 20:40:57 +01:00
Veronica Berglyd Olsen
8af720cbd6 Improvements functionality of various dialogs (#1681) 2024-02-01 23:43:57 +01:00
Veronica Berglyd Olsen
68a6390868 Add test coverage of modified widgets 2024-02-01 23:35:30 +01:00
Veronica Berglyd Olsen
a8f61f2b98 Add modified combo and spinboxes that don't scroll on mouse wheel 2024-02-01 23:35:14 +01:00
Veronica Berglyd Olsen
c866491910 Remove test lines that sometimes fail, as they cover no additional code 2024-02-01 22:22:22 +01:00
Veronica Berglyd Olsen
c1a14e7aa5 Fix test 2024-02-01 21:28:20 +01:00
Veronica Berglyd Olsen
27fa356846 Make the closing + opening of projects from welcome screen a little smoother 2024-02-01 21:22:12 +01:00
Veronica Berglyd Olsen
54f36d4e8e Improve item auto-select on welcome dialog 2024-02-01 20:49:06 +01:00
Veronica Berglyd Olsen
3b9ef47e0f Make some minor improvements to custom widget highlighting 2024-02-01 20:34:42 +01:00
Veronica Berglyd Olsen
d504c0a7ec Allow creating project from other projects (#1680) 2024-02-01 00:24:16 +01:00
Veronica Berglyd Olsen
58fa3e64ec Add test coverage 2024-02-01 00:15:39 +01:00
Veronica Berglyd Olsen
b0f1db0aea Add copy project feature to project builder class 2024-01-31 23:56:09 +01:00
Veronica Berglyd Olsen
90dda43205 Bump dev version to 2.3 Alpha 4 2024-01-31 22:03:26 +01:00
Veronica Berglyd Olsen
d20af1283c Allow inserting characters in manuscript headers (#1677) 2024-01-31 20:36:25 +01:00
Veronica Berglyd Olsen
2cd6cc299e Merge branch 'dev' into chars_in_build_alt2 2024-01-31 20:25:55 +01:00
Veronica Berglyd Olsen
a227c58d55 Add a 'Create New' menu for documents in project tree context menu (#1679) 2024-01-31 20:23:34 +01:00
Veronica Berglyd Olsen
d23fdf28ad Fix test, again ... 2024-01-31 20:18:17 +01:00
Veronica Berglyd Olsen
9803dc16fd Fix a couple of minor issues with project tree context menu 2024-01-31 20:10:53 +01:00
Veronica Berglyd Olsen
7fcc9a3928 Update test 2024-01-31 20:05:16 +01:00
Veronica Berglyd Olsen
ec7f50b566 Add a 'Create New' submenu to project tree context menu (#1519) 2024-01-31 20:05:10 +01:00
Veronica Berglyd Olsen
76ab9c3908 Change tokenizer parsed data to always use a list for format, even when empty 2024-01-30 23:25:11 +01:00
Veronica Berglyd Olsen
e6193ed858 Update tags documentation 2024-01-30 23:01:12 +01:00
Veronica Berglyd Olsen
5b4ccad19b Improve test coverage 2024-01-30 22:37:43 +01:00
Veronica Berglyd Olsen
e1531009d3 Update Lipsum test project 2024-01-30 22:10:25 +01:00
Veronica Berglyd Olsen
ca188fee08 Implement alternative tag display name format 2024-01-30 21:34:36 +01:00
Veronica Berglyd Olsen
c5edbbfaf6 Improve type checking in common module, and delete unused function 2024-01-30 21:13:38 +01:00
Veronica Berglyd Olsen
f15563cf6e Revert parts of previous implementation 2024-01-30 21:00:04 +01:00
Veronica Berglyd Olsen
e5c6dae080 Fix tests and tag index validation (uncommited changes from yesterday) 2024-01-30 10:42:07 +01:00
Veronica Berglyd Olsen
6952211607 Update docs 2024-01-29 17:47:37 +01:00
Veronica Berglyd Olsen
b396cff9a7 Add a display name filed to index, and improve handling of it 2024-01-29 17:47:30 +01:00
Veronica Berglyd Olsen
ca7ae6b666 Add a syntax colour for optional values 2024-01-29 17:45:53 +01:00
Veronica Berglyd Olsen
cbf5f1ead3 Add POV or Focus char field to manuscript header format 2024-01-29 17:32:43 +01:00
Veronica Berglyd Olsen
a48a4e5674 Add customisation option for ODT build document header (#1675) 2024-01-28 15:58:06 +01:00
Veronica Berglyd Olsen
1ec0bff159 Add page offset option to ODT build (#1505) 2024-01-28 15:52:38 +01:00
Veronica Berglyd Olsen
116409bb8d Sort imports 2024-01-28 15:29:05 +01:00
Veronica Berglyd Olsen
0e41a48ad1 Update tests 2024-01-28 15:25:12 +01:00
Veronica Berglyd Olsen
f732d13807 Add build setting for customising ODT page header (#1505) 2024-01-28 15:15:03 +01:00
Veronica Berglyd Olsen
8e4e6903b1 Clean up variables and formatting 2024-01-28 00:28:01 +01:00
Veronica Berglyd Olsen
97b791511f Bump dev version to 2.3 Alpha 3 2024-01-27 18:20:29 +01:00
Veronica Berglyd Olsen
100989030d Update build settings layout (#1674) 2024-01-27 18:16:33 +01:00
Veronica Berglyd Olsen
6c75bdecdc Update widget flow on preferences dialog 2024-01-27 18:06:41 +01:00
Veronica Berglyd Olsen
51314804bf Update remaining build settings pages and delete old config layouts 2024-01-27 18:06:08 +01:00
Veronica Berglyd Olsen
6b106599dd Merge branch 'dev' into build_settings 2024-01-27 17:07:09 +01:00
Veronica Berglyd Olsen
82d5899f2e Merge branch 'main' into dev 2024-01-27 17:04:44 +01:00
Veronica Berglyd Olsen
11c4428a8a Fix some issues after release 2.2.1 (#1672) 2024-01-27 16:42:56 +01:00
Veronica Berglyd Olsen
c0a5d257ac Fix package name issue with upload artifact version 4 2024-01-27 16:17:20 +01:00
Veronica Berglyd Olsen
6a30ce5fe3 Update artifacts download action 2024-01-27 16:08:12 +01:00
Veronica Berglyd Olsen
3ba345acc8 Update GitHub actions 2024-01-27 16:03:34 +01:00
Veronica Berglyd Olsen
b27589d3d6 Update the help info on Launchpad packages 2024-01-27 16:03:26 +01:00
Veronica Berglyd Olsen
5979503dc8 Release 2.2.1 (#1667) 2024-01-27 15:50:19 +01:00
Veronica Berglyd Olsen
b008721bdb Update changelog and change release date 2024-01-27 15:47:02 +01:00
Veronica Berglyd Olsen
bcd1e7e245 Merge branch 'main' into release_2.2.1 2024-01-27 15:44:16 +01:00
Veronica Berglyd Olsen
d455cb714d Handle non-modal dialogs better (#1671) 2024-01-27 15:43:11 +01:00
Veronica Berglyd Olsen
9311117257 Prevent multiple non-modal dialogs of the same kind from being opened 2024-01-27 15:38:44 +01:00
Veronica Berglyd Olsen
855c525670 Redesign Build Settings tool to match other config dialogs 2024-01-27 15:22:37 +01:00
Veronica Berglyd Olsen
d113b3feb3 Drop the project .bak file (#1670) 2024-01-27 14:55:11 +01:00
Veronica Berglyd Olsen
7a2d239aaa Merge branch 'dev' into project_handling 2024-01-27 14:42:43 +01:00
Veronica Berglyd Olsen
9ae36eaa24 Update Ubuntu release targets 2024-01-27 11:23:28 +01:00
Veronica Berglyd Olsen
a76268743f Update Ubuntu releases 2024-01-26 23:18:36 +01:00
Veronica Berglyd Olsen
7d9ca66fd6 Remove Ubuntu 23.04 release 2024-01-26 23:12:47 +01:00
Veronica Berglyd Olsen
e752a97ea7 Bump dev version to 2.3 Alpha 2 2024-01-26 23:11:13 +01:00
Veronica Berglyd Olsen
ed3e513544 Drop novel title field (#1669) 2024-01-26 23:07:08 +01:00
Veronica Berglyd Olsen
d6eafccde6 Update the docstring in the project XML reader 2024-01-26 23:02:35 +01:00
Veronica Berglyd Olsen
119d572050 Update file format spec document 2024-01-26 23:00:36 +01:00
Veronica Berglyd Olsen
7a1fab0c0a Update test reference files 2024-01-26 22:57:25 +01:00
Veronica Berglyd Olsen
de6fd65664 Update sample project and tests 2024-01-26 22:45:28 +01:00
Veronica Berglyd Olsen
838a2a8062 Drop the Novel Title data from the project and code 2024-01-26 22:45:12 +01:00
Veronica Berglyd Olsen
e03305d601 Update Project Settings dialog (#1668) 2024-01-26 22:40:04 +01:00
Veronica Berglyd Olsen
4c5f68242a Remove unused code in old config layout classes 2024-01-26 22:32:39 +01:00
Veronica Berglyd Olsen
40a8d728bb Update project settings tests 2024-01-26 22:32:20 +01:00
Veronica Berglyd Olsen
a7a2eaff55 Delete the old config dialog base class 2024-01-26 21:36:05 +01:00
Veronica Berglyd Olsen
3761b1729f Make the style of config dialogs consistent 2024-01-26 21:31:14 +01:00
Veronica Berglyd Olsen
0dc4719400 Fix log formatting for longer file names 2024-01-26 19:51:54 +01:00
Veronica Berglyd Olsen
c6ee6746a2 Make layout improvements to Project Settings 2024-01-26 19:51:31 +01:00
Veronica Berglyd Olsen
ee21045ee2 Update the design on the Project Settings dialog 2024-01-26 19:50:17 +01:00
Veronica Berglyd Olsen
5abb8d566a Bump version and update changelog and release notes 2024-01-25 23:45:02 +01:00
Veronica Berglyd Olsen
2772c9bf0b Update i18n (#1666) 2024-01-25 23:31:38 +01:00
Veronica Berglyd Olsen
883ef3457b Update German and Chinese translations 2024-01-25 23:27:11 +01:00
Veronica Berglyd Olsen
a10fff92e7 Fix focus switch bug in project tree (#1649) 2024-01-25 23:22:44 +01:00
Veronica Berglyd Olsen
df4993c38e Drop outdated info in docstring 2024-01-25 23:20:47 +01:00
Veronica Berglyd Olsen
d73763b1f7 Redesign Project Details dialog (#1665) 2024-01-25 23:10:54 +01:00
Veronica Berglyd Olsen
10012054be Remove some unused code 2024-01-25 23:07:10 +01:00
Veronica Berglyd Olsen
b6c9f1160f Add test coverage 2024-01-25 22:59:22 +01:00
Veronica Berglyd Olsen
483528b3b2 Modify some of the custom widgets after writing tests 2024-01-25 22:59:06 +01:00
Veronica Berglyd Olsen
4ef40f2c4d Remove old project details dialog 2024-01-25 21:30:53 +01:00
Veronica Berglyd Olsen
23713bb791 Add table of contents code to novel details panel 2024-01-25 21:25:43 +01:00
Veronica Berglyd Olsen
6b53a2665e Merge branch 'main' into fixes 2024-01-25 12:09:22 +01:00
Veronica Berglyd Olsen
6f5cbea95f Fix typo in documentation (#1664) 2024-01-25 12:07:07 +01:00
Reproog
09855730d7 Replace Misspelling 'Gustom' -> 'Custom' in File 'docs/source/int_customise.rst' 2024-01-25 12:02:00 +01:00
Veronica Berglyd Olsen
6622a7e8e0 Begin to add content to the novel details overview page 2024-01-24 19:26:48 +01:00
Veronica Berglyd Olsen
cc4d92f0f7 Improve novel selector widget and add to novel details dialog 2024-01-24 17:05:14 +01:00
Veronica Berglyd Olsen
a14e544e78 Merge branch 'dev' into project_details 2024-01-23 22:29:46 +01:00
Veronica Berglyd Olsen
269fa700b0 Change in-app version format and .deb package names (#1659) 2024-01-23 22:28:28 +01:00
Veronica Berglyd Olsen
bd45619e2f Modify Debian and Ubuntu packaging version format, and remove snapshots 2024-01-23 21:49:28 +01:00
Veronica Berglyd Olsen
97384ee4bd Update tests and clean up packaging util 2024-01-23 20:48:39 +01:00
Veronica Berglyd Olsen
415f1a1d1a Update build scripts to handle new version format 2024-01-23 19:57:27 +01:00
Veronica Berglyd Olsen
b33a3b480d Use short version format for app version 2024-01-23 19:54:19 +01:00
Veronica Berglyd Olsen
9f2c5379b7 Generalise the custom help label widget 2024-01-22 23:55:37 +01:00
Veronica Berglyd Olsen
f35722ab35 Merge branch 'dev' into project_details 2024-01-19 16:58:57 +01:00
Veronica Berglyd Olsen
8a8a218e6b Convert theme colours to Qt objects (#1656) 2024-01-19 16:58:12 +01:00
Veronica Berglyd Olsen
fe0098ebbc Update colour parsing tests 2024-01-19 16:51:27 +01:00
Veronica Berglyd Olsen
ca02bbf20d Fix slots order 2024-01-19 16:35:49 +01:00
Veronica Berglyd Olsen
e10140b1cd Fix spelling colour in highlighter and make a few improvements 2024-01-19 16:34:57 +01:00
Veronica Berglyd Olsen
b92112e933 Update tests 2024-01-19 16:13:29 +01:00
Veronica Berglyd Olsen
82c63723a4 Make all theme colours actual QColor objects 2024-01-19 16:13:12 +01:00
Veronica Berglyd Olsen
ce2ac9b1a1 Add a novel info dialog 2024-01-18 23:34:27 +01:00
Veronica Berglyd Olsen
97ea3ebc16 Drop the XML backup file 2024-01-16 16:14:10 +01:00
Veronica Berglyd Olsen
ae7c19f923 Add inactive tags filter to viewer panel (#1654) 2024-01-15 16:05:58 +01:00
Veronica Berglyd Olsen
3135bee47d Changes the option text 2024-01-15 16:02:02 +01:00
Veronica Berglyd Olsen
c15ffb0813 Update test coverage 2024-01-15 15:59:46 +01:00
Veronica Berglyd Olsen
a2a62f8b26 Allow hiding inactive tags in document viewer panel 2024-01-15 15:50:19 +01:00
Veronica Berglyd Olsen
ca4aa75880 Rename outdated function parameter in index class 2024-01-15 15:48:45 +01:00
Veronica Berglyd Olsen
427a910ec0 Remove redundant constant in preferences dialog 2024-01-13 18:59:48 +01:00
Veronica Berglyd Olsen
beb01d572f Rewrite Preferences dialog (#1652) 2024-01-13 18:44:36 +01:00
Veronica Berglyd Olsen
16461279cf Remove dependency of i18n files in preferences test 2024-01-13 18:38:34 +01:00
Veronica Berglyd Olsen
f40722d196 Merge branch 'dev' into preferences 2024-01-13 18:33:06 +01:00
Veronica Berglyd Olsen
34eb39e10d Add new test for preferences dialog 2024-01-13 18:29:21 +01:00
Veronica Berglyd Olsen
2cb772847e Update tests 2024-01-13 18:29:06 +01:00
Veronica Berglyd Olsen
7b5b82136f Update preferences dialog and quotes selection dialog 2024-01-13 18:28:41 +01:00
Veronica Berglyd Olsen
fa9d0f3503 Clean up docstrings in conftest 2024-01-11 09:23:05 +01:00
Veronica Berglyd Olsen
4afbd98d6f Add icons to preferences buttons 2024-01-11 09:17:46 +01:00
Veronica Berglyd Olsen
944e2455d5 Fix a bug with editor init on preferences update 2024-01-08 22:13:33 +01:00
Veronica Berglyd Olsen
2504965f8d Add more spacing in preferences layout 2024-01-08 22:06:04 +01:00
Veronica Berglyd Olsen
34fcbdd350 Fix a couple of bugs on the preference dialog 2024-01-08 21:48:51 +01:00
Veronica Berglyd Olsen
671d7130e1 Add search bar to preferences 2024-01-08 21:08:33 +01:00
Veronica Berglyd Olsen
1fbd50334d Complete the rewrite of the Preferences dialog 2024-01-08 20:49:40 +01:00
Veronica Berglyd Olsen
1ed3cea414 Simplify the custom switch widget 2024-01-08 19:14:36 +01:00
Veronica Berglyd Olsen
978a8145a8 Drop the setting to change word count interval 2024-01-08 19:13:58 +01:00
Veronica Berglyd Olsen
1482451e87 Create a scrollable config layout and start adding it to preferences 2024-01-08 19:12:39 +01:00
Veronica Berglyd Olsen
5c99e2186a Merge branch 'main' into dev 2024-01-05 00:27:32 +01:00
Veronica Berglyd Olsen
df690ceb36 Happy New Year 2024 2024-01-05 00:25:07 +01:00
Veronica Berglyd Olsen
10435945db Add a welcome dialog (#1647) 2023-12-31 17:01:18 +01:00
Veronica Berglyd Olsen
df95cd85e8 Add support for dark theme welcome window 2023-12-30 17:23:43 +01:00
Veronica Berglyd Olsen
05e9729c22 Add coverage of some missed lines 2023-12-30 16:52:24 +01:00
Veronica Berglyd Olsen
bc17305c4f Add tests for the welcome window 2023-12-30 16:33:03 +01:00
Veronica Berglyd Olsen
c3ea32a165 Add back in focus switch to ensure #1376 remains resolved 2023-12-30 00:01:12 +01:00
Veronica Berglyd Olsen
9660d82f9b Remove focus switch after creating new tree item (#1648) 2023-12-29 23:53:32 +01:00
Veronica Berglyd Olsen
7feb3ec2f9 Update project builder tests 2023-12-29 14:50:28 +01:00
Veronica Berglyd Olsen
25686e46a8 Fix broken tests 2023-12-29 14:12:46 +01:00
Veronica Berglyd Olsen
53228faaa3 Add a way to delete entries in the recent projects list 2023-12-29 13:41:10 +01:00
Veronica Berglyd Olsen
bbabc41ac2 Remove old open project dialog 2023-12-29 12:16:52 +01:00
Veronica Berglyd Olsen
18b3edbf87 Complete project list and open and browse buttons on welcome dialog 2023-12-28 23:11:11 +01:00
Veronica Berglyd Olsen
63fd7bf06a Add custom painting of project items in the project list 2023-12-22 20:26:34 +01:00
Veronica Berglyd Olsen
ba538920aa Fix sample project creation 2023-12-20 22:20:04 +01:00
Veronica Berglyd Olsen
8b6691c056 Remove the old project wizard 2023-12-20 22:00:52 +01:00
Veronica Berglyd Olsen
41b7495a06 Complete the create new project code path 2023-12-20 21:52:57 +01:00
Veronica Berglyd Olsen
a71d0d8cfe Add project fill options to new project page on welcome dialog 2023-12-20 20:21:51 +01:00
Veronica Berglyd Olsen
956abf3e8e Add project fill box 2023-12-19 20:26:40 +01:00
Veronica Berglyd Olsen
054d4f965e Added most of new project form 2023-12-19 19:31:30 +01:00
Veronica Berglyd Olsen
f26b405f42 Add new project page to welcome dialog 2023-12-19 17:30:11 +01:00
Veronica Berglyd Olsen
8a61d57ce4 Update title on welcome dialog 2023-12-19 17:29:33 +01:00
Veronica Berglyd Olsen
818fa2bf11 Merge branch 'dev' into welcome_window 2023-12-17 18:08:35 +01:00
Veronica Berglyd Olsen
856c14ce76 Bump dev branch to 2.3 alpha 1 2023-12-17 17:49:17 +01:00
Veronica Berglyd Olsen
f9089fd506 Merge branch 'main' into dev 2023-12-17 17:47:00 +01:00
Veronica Berglyd Olsen
904f954d4d Add framework for welcome dialog 2023-12-17 15:14:56 +01:00
Veronica Berglyd Olsen
356ecde88a Merge branch 'main' into dev 2023-12-04 10:46:58 +01:00
Veronica Berglyd Olsen
ded91bc3b0 Refactor Storage class (#1635) 2023-12-01 18:22:26 +01:00
Veronica Berglyd Olsen
6d769cb512 Make some minor improvements 2023-12-01 18:18:26 +01:00
Veronica Berglyd Olsen
ecaaffb029 Update tests for project class 2023-12-01 18:02:29 +01:00
Veronica Berglyd Olsen
8952bbab1d Clean up project tests 2023-12-01 17:45:25 +01:00
Veronica Berglyd Olsen
3fe2ee3058 Update tests for storage class 2023-12-01 17:28:56 +01:00
Veronica Berglyd Olsen
f2b35d798b Make some minor corrections 2023-11-30 22:53:52 +01:00
Veronica Berglyd Olsen
d11a8ee789 Remove unneeded storage enum 2023-11-30 22:39:46 +01:00
Veronica Berglyd Olsen
5278eb7895 Update tests 2023-11-30 22:30:12 +01:00
Veronica Berglyd Olsen
4f42407c23 Rewrite project open and creation in storage class 2023-11-30 22:29:54 +01:00
265 changed files with 29113 additions and 28509 deletions

View File

@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Python Setup
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
architecture: x64
@@ -18,7 +18,7 @@ jobs:
sudo apt install qttools5-dev-tools latexmk texlive texlive-latex-extra
- name: Checkout Source
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Packages (pip)
run: pip install -r docs/source/requirements.txt
@@ -27,7 +27,7 @@ jobs:
run: python pkgutils.py qtlrelease sample manual
- name: Upload Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: nw-assets
path: |
@@ -46,7 +46,7 @@ jobs:
linux-tag: ["manylinux_2_24_x86_64", "manylinux_2_28_x86_64"]
steps:
- name: Python Setup
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
architecture: x64
@@ -55,10 +55,10 @@ jobs:
run: pip install python-appimage
- name: Checkout Source
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Download Artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: nw-assets
path: novelwriter/assets
@@ -67,12 +67,10 @@ jobs:
run: python pkgutils.py build-appimage --linux-tag ${{ matrix.linux-tag }} --python-version ${{ matrix.python-version }}
- name: Upload Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: novelWriter-Packages
path: |
dist_appimage/novelWriter*.AppImage
dist_appimage/novelWriter*.AppImage.sha256
name: AppImage-${{ matrix.python-version }}-${{ matrix.linux-tag }}
path: dist_appimage
if-no-files-found: error
retention-days: 1
@@ -81,10 +79,10 @@ jobs:
runs-on: macos-12
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Download Artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: nw-assets
path: novelwriter/assets
@@ -93,11 +91,9 @@ jobs:
run: ./setup/macos/build.sh
- name: Upload DMG
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: novelWriter-Packages
path: |
dist_macos/novelWriter*.dmg
dist_macos/novelWriter*.dmg.sha256
name: MacOS-DMG
path: dist_macos
if-no-files-found: error
retention-days: 1

View File

@@ -15,14 +15,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Python Setup
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3
architecture: x64
- name: Checkout Source
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install flake8
run: pip install flake8
run: pip install flake8 flake8-pep585
- name: Syntax Check
run: |
flake8 --version

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Python Setup
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: x64
@@ -27,7 +27,7 @@ jobs:
sudo apt update
sudo apt install libenchant-2-dev qttools5-dev-tools aspell-en
- name: Checkout Source
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Dependencies (pip)
run: |
pip install -U -r requirements.txt -r tests/requirements.txt

View File

@@ -15,7 +15,7 @@ jobs:
runs-on: macos-latest
steps:
- name: Python Setup
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
architecture: x64
@@ -23,7 +23,7 @@ jobs:
run: |
brew install enchant
- name: Checkout Source
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Dependencies (pip)
run: |
pip install -U pyobjc -r requirements.txt -r tests/requirements.txt

View File

@@ -15,12 +15,12 @@ jobs:
runs-on: windows-latest
steps:
- name: Python Setup
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
architecture: x64
- name: Checkout Source
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Dependencies (pip)
run: |
pip install -U -r requirements.txt -r tests/requirements.txt

View File

@@ -1,5 +1,236 @@
# novelWriter Changelog
## Version 2.3.1 [2024-03-17]
### Release Notes
This is a patch release that fixes several issues with translations into other languages than the
default English, and adds completed translations for French.
### Detailed Changelog
**Internationalisation**
* Fix untranslated text on the "Project Word List" dialog. PR #1744. Issue #1746.
* Fix untranslated text on the dialog that pops up after an upgrade, PR #1754. Issue #1749.
* Fix error in Norwegian translation. PR #1744.
* Allow the translated text for adding chapter and scenes on the Welcome dialog to flow around the
number selector since the number is inserted into the sentence, and not all languages will split
the sentence around the number like is done in English. PR #1754. Issue #1750.
* French translation updated by Albert Aribaud (@aaribaud). PR #1760.
* Minor updates to other translations for the 2.3.1 fixes by other contributors. PR #1760.
**Other Changes**
* Bump the revision of the project file format to 1.5 Revision 3 from Revision 2. This should have
been done in the 2.3 release due to the addition of the Templates root folder type. PR #1748.
----
## Version 2.3 [2024-03-10]
### Release Notes
This release introduces a new Welcome dialog that replaces both the previous Open Project dialog
and the New Project Wizard. The Welcome dialog has received a friendly custom art design created by
Louis Durrant.
The Preferences, Project Settings, Project Details, and About dialogs have received completely new
designs and layouts, and the Manuscript Build Settings dialog has been updated to match.
Among new features is a new Templates root folder where the writer can store template documents to
be used when creating new project documents and notes. It is now also possible to include Point of
View and Focus character names in chapter titles in Manuscripts. A new feature to ignore text has
also been added. It behaves similarly to comments, but is never included in a manuscript even if
comments in the manuscript are enabled.
See the website for complete [Release Notes](https://novelwriter.io/releases/release_2_3.html).
### Detailed Changelog
**Bugfixes**
* Fix an issue where the Tags and References panel below the document viewer was not cleared if a
project was opened, closed, and a new project with no tags defined were opened again. PR #1720.
Issue #1718.
* Fixed an issue where multi-selecting documents in Trash would give the option to again move items
to Trash. The menu now properly offers the option to permanently delete the documents. PR #1728.
* Fixed an issue where multi-select for deletion would only process the item right-clicked, and not
all the selected items. PR #1728.
* Changed the error message that pops up when trying to open a project from the Welcome dialog that
no longer exists. The error message should no indicate that the project was not found, as opposed
to unreadable. PR #1740. Issue #1737.
**Improvements**
* The build tool no longer inserts a scene separator immediately after a partition heading, and
should now behave the same way as for chapters. If there is text before the first scene break,
the text flows continuously without a separator. PR #1716. Issue #1704.
* Added one new GUI theme named "Cyberpunk Night" by @alemvigh. Also added a matching "Cyberpunk
Night" document editor theme by @alemvigh, and a new Tango theme by @vkbo. PR #1738. Issue #1730.
* When the Welcome dialog fails to open a project, and there is not already a project open in the
app, the Welcome dialog appears again. PR #1740. Issue #1737.
**Internationalisation**
* Norwegian and US English translations updated by @vkbo. PR #1714.
* Japanese translation updated by @hebekeg. PR #1714.
* Italian translation updated by Lou Cyper (loucyper1). PR #1714.
* Dutch translation updated by Annelotte and Martijn van der Kleijn (mvdkleijn). PR #1714.
* Latin American Spanish translation updated by @tmarplatt. PR #1741.
* German translation updated by Myian (@HeyMyian). PR #1741.
**Other Changes**
* Removed the novelwriter-cli entry point that was in any case broken. PR #1734. Issue #1732.
----
## Version 2.3 RC 1 [2024-02-24]
### Release Notes
This is a release candidate of the next release version, and is intended for testing purposes.
Please be careful when using this version on live writing projects, and make sure you take frequent
backups.
Please check the changelog for an overview of changes. The full release notes will be added to the
final release.
### Detailed Changelog
**Improvements**
* Redesign the buttons on the new Welcome dialog so that they only show buttons related to the
visible page. Drop the additional buttons on the New Project page. Issue #1706.
PRs #1707 and #1709.
* Drop the Language setting on the Welcome dialog's New Project page. PR #1707.
* Hide the additional settings for Fresh Projects on the New Project page of the new Welcome
dialog. Issue #1705. PR #1707.
* Update the Templates root folder icon. PR #1709.
* Scene separators are now hidden after a new title in manuscript builds, also when there are no
chapters. Issue #1704. PR #1711.
* Scene and chapter counters are now reset when a novel title is encountered. PR #1711.
----
## Version 2.3 Beta 1 [2024-02-16]
### Release Notes
This is a beta release of the next release version, and is intended for testing purposes. Please be
careful when using this version on live writing projects, and make sure you take frequent backups.
Please check the changelog for an overview of changes. The full release notes will be added to the
final release.
### Detailed Changelog
**Major Features**
* A new Welcome dialog has been added. The dialog replaces the Open Project dialog and the New
Project Wizard. The Welcome dialog features artwork created by Louis Durrant, and a custom design
for the project list. New projects can be created by a form available from the same dialog, and
features a simplified set of options. Issue #1506. PRs #1647, #1681 and #1689.
* It is now possible to create a new project by copying the content of another project, or a Zip
file of a project, including a backup. This option is available from the New Project feature of
the Welcome dialog. Issue #841. PRs #1680 and #1684.
* The Preferences dialog has been completely redesigned. All options are now available in a single,
scrollable list with appropriate section headers. All sections are available as navigation
buttons along the side, and it is also possible to search for settings in a search box at the
top. The design matches that created for the Manuscript Build Settings dialog added in 2.1.
Issues #1603 and #1604. PR #1652.
* The Project Details dialog has been redesigned to match the other new dialogs. It has also been
modified to properly handle multiple novel folders. The novel selector is placed at the top of
the dialog, and affects all data in the tabs. The Novel Title info has been removed. PR #1665.
* The Manuscript Build Settings dialog has been updated to use the new config layout classes, which
are more flexible in terms of content flow. PR #1674.
* A new root folder type called "Templates" has been added. Any document added here will show up in
the Add Item menu in the Project Tree view under a "From Template" submenu. Selecting such an
entry will create a new document at the selected location in the project, and populate it with
the content of the template file. Issues #996 and #1125. PR #1688.
* The About novelWriter dialog has been simplified to only show some key information and the
credits text. A link to the releases page is available for checking release notes. Keeping the
release notes online means it is easier to update them, and make them more visually interesting
as the formatting of the dialog box is limited. PR #1695.
* The old Check for Updates dialog has been removed. Checking for new releases of novelWriter can
be done directly in the Welcome dialog or the About dialog by clicking "Check Now" next to the
"Latest Version" label. PR #1696.
**Minor Features**
* A new drop down menu in the References panel below the Document Viewer has an option to filter
out inactive notes in the various tag lists in the tabs on the panel. Issue #1653. PR #1654.
* The Novel Title fields, which no longer makes much sense after it was possible to add multiple
novel folders to a project, has been fully dropped. Issue #1655. PR #1669.
* The document header for ODT manuscript files can now be customised. Issue #1505. PR #1675.
* The Manuscript Build tool can now insert characters (Point of View or Focus) into chapter headers
and other headers. By default, it inserts the tag value, but the display name for a tag can be
set with a `|` character in the `@tag` definition if a different text is desired. Issue #1468.
PR #1677.
* A new modified comment format for the editor has been added. Instead of the regular comment using
`%`, this one uses `%~`. The only difference is that the latter will never be exported to a
manuscript at all, while regular comments can be exported when a setting is enabled. Issue #1075.
PR #1690.
* It is now possible to change a document's label from the first heading in the document by
right-clicking on it and selecting "Rename to heading". Issue #1443. PR #1692.
* The content of the Project Word List can now be exported and imported using plain text files.
Issue #1560. PR #1691.
* The content of the Outline View can now be exported to a CSV file to be opened in any spreadsheet
application. Issue #1507. PR #1697.
**Usability**
* A Create New submenu in the Project Tree context menu has been added, which give quick access to
the items at the top level of the Add Item menu. Issue #1519. PR #1679.
* When multiple paragraphs are selected in the editor, and any of the comment features are toggled,
or formatting is reset, the action is applied to all selected paragraphs, not just the first.
Issue #1042 and #1687. PR #1690.
**Packaging**
* The in-app version format is now identical to the version tag, and the format for Ubuntu
pre-release packages has been updated so that they are compatible with release packages. That is,
if you add both the release and pre-release repos from Launchpad, release packages will now
properly replace pre-release packages when running apt upgrade. PR #1659.
**Code Improvements**
* The Storage class has been refactored. It is the class that handles the project storage folder
for a novelWriter project. The refactoring is a step towards allowing single file storage for
projects as an alternative to project folders. Issue #977. PR #1635.
* All theme colours are now proper QColor objects from the start, which avoids the need to create
a large number of these where they are used. PR #1656.
* A nwProject.bak file is no longer kept in the project folder. It never really served any purpose.
The project file is still written to a temp file before the old file is replaced, which prevents
partial overwrites. PR #1670.
* Other minor code improvements in PRs #1693 and 1694.
----
## Version 2.2.1 [2024-01-27]
### Release Notes
This is a patch release that fixes an issue where the Project View would sometimes switch to the
Novel View when a new item was created. This patch also includes updated translations for German
and Chinese.
### Detailed Changelog
**Bugfixes**
* Fix a bug in the toggle for the tree view on the left would trigger each time a new project item
was created. Issue #1649. PR #1648.
* Fix an issue where multiple Manuscript and Writing Stats dialogs could be opened. PR #1671.
**Internationalisation**
* Updated German translation, by @HeyMyian. PR #1666.
* Updated Chinese translation, by @ruixuan658 and @longqzh. PR #1666.
----
## Version 2.2 [2023-12-17]
### Release Notes

View File

@@ -12,6 +12,10 @@
For other contributions, see the project's [Contributors](https://github.com/vkbo/novelWriter/graphs/contributors) page.
## Artwork
The artwork on the Welcome dialog was created by [Louis Durrant](https://louisdurrant.art).
## Translations
The default language is English (UK) with English (US) as an option. These are the original

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

@@ -5,9 +5,9 @@ novelWriter User Guide
| **Release Version:** |release|
| **Updated:** |today|
novelWriter is an open source plain text editor designed for writing novels assembled from many
smaller text documents. It uses a minimal formatting syntax inspired by Markdown, and adds a meta
data syntax for comments, synopsis, and cross-referencing. It is designed to be a simple text
novelWriter is an open source plain text editor designed for writing novels assembled from
individual text documents. It uses a minimal formatting syntax inspired by Markdown, and adds a
meta data syntax for comments, synopsis, and cross-referencing. It is designed to be a simple text
editor that allows for easy organisation of text and notes, using human readable text files as
storage for robustness.
@@ -23,13 +23,14 @@ See the :ref:`a_breakdown_storage` section for more details.
Any operating system that can run Python 3 and has the Qt 5 libraries should be able to run
novelWriter. It runs fine on Linux, Windows and MacOS, and users have tested it on other platforms
as well. novelWriter can also be run directly from the Python source, or installed from packages or
with pip. See :ref:`a_started` for more details.
as well. novelWriter can be run directly from the Python source, or installed from packages or with
pip. See :ref:`a_started` for more details.
**Useful Links**
* Website: https://novelwriter.io
* Documentation: https://docs.novelwriter.io
* Public Releases: https://releases.novelwriter.io
* Internationalisation: https://crowdin.com/project/novelwriter
* Source Code: https://github.com/vkbo/novelWriter
* Source Releases: https://github.com/vkbo/novelWriter/releases
@@ -66,7 +67,6 @@ with pip. See :ref:`a_started` for more details.
usage_format
usage_shortcuts
usage_typography
usage_projectformat
.. toctree::
:maxdepth: 1
@@ -80,7 +80,15 @@ with pip. See :ref:`a_started` for more details.
.. toctree::
:maxdepth: 1
:caption: Additional Topics
:caption: Additional Details
:hidden:
more_projectformat
more_counting
.. toctree::
:maxdepth: 1
:caption: Technical Topics
:hidden:
tech_locations

View File

@@ -36,7 +36,8 @@ and add dictionaries yourself.
A small tool to assist with this can be found under :guilabel:`Tools > Add Dictionaries`. It will
import spell checking dictionaries from Free Office or Libre Office extensions. The dictionaries
are then installed in the install location for the Enchant library.
are then installed in the install location for the Enchant library and should thus work for any
application that uses Enchant for spell checking.
**Manual Install**
@@ -96,7 +97,7 @@ set as ``name`` inside the file.
suitable one.
Gustom GUI and Icons Theme
Custom GUI and Icons Theme
--------------------------
A GUI theme ``.conf`` file consists of the following settings:
@@ -139,10 +140,10 @@ In the Main section you must at least define the ``name`` and ``icontheme`` sett
``typicons_light`` or ``typicons_dark``, or to an icon theme in your custom icons directory. The
setting must match the icon theme's folder name.
The Palette values correspond to the Qt enum values for QPalette::ColorRole, see the
The Palette values correspond to the Qt enum values for ``QPalette::ColorRole``, see the
`Qt documentation <https://doc.qt.io/qt-5.15/qpalette.html#ColorRole-enum>`_ for more details. The
colour values are RGB numbers on the format ``r, g, b`` where each is an integer from to 255.
Omitted values are not loaded and will use default values.
colour values are RGB numbers on the format ``r, g, b`` where each is an integer from ``0`` to
``255``. Omitted values are not loaded and will use default values.
Custom Syntax Theme
@@ -174,15 +175,20 @@ A syntax theme ``.conf`` file consists of the following settings:
shortcode = 0, 0, 0
keyword = 0, 0, 0
value = 0, 0, 0
optional = 0, 0, 0
spellcheckline = 0, 0, 0
errorline = 0, 0, 0
replacetag = 0, 0, 0
modifier = 0, 0, 0
In the Main section, you must define at least the ``name`` setting. The Syntax colour values are
RGB numbers of the format ``r, g, b`` where each is an integer from to 255. Omitted values default
to black, except ``background`` which defaults to white,
RGB(A) numbers of the format ``r, g, b, a`` where each is an integer ``0`` from to ``255``. The
fourth value is the alpha channel (transparency), which can be omitted.
Omitted syntax colours default to black, except ``background`` which defaults to white.
.. versionadded:: 2.2
The `shortcode` syntax colour entry was added, so you need to update your custom themes if you
made any before version 2.2.
The `shortcode` syntax colour entry was added.
.. versionadded:: 2.3
The `optional` syntax colour entry was added.

View File

@@ -50,7 +50,7 @@ Glossary
Headings
Each level of headings in :term:`Novel Documents` have a specific meaning in terms of the
structure of the story. That is, they determine what novelWriter considers a partition, a
chapter, a scene or a text section. For :term:`Project Notes`, the header levels don't
chapter, a scene or a text section. For :term:`Project Notes`, the heading levels don't
matter. For more details on headings in novel documents, see :ref:`a_struct_heads`.
Keyword

View File

@@ -25,7 +25,7 @@ Managing the Project
: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. See :ref:`a_ui_tree_split_merge` for more details.
can rearrange them here of you wish. See :ref:`a_ui_tree_split_merge` for more details.
Layout Tricks
@@ -42,7 +42,7 @@ Layout Tricks
in columns using the tab key, and it should look the same when viewed next to the editor.
This is most suitable for your notes, as the result in exported documents cannot be guaranteed
to match.
to match. Especially if you don't use the same font in your manuscript as in the editor.
Organising Your Text
@@ -56,7 +56,9 @@ Organising Your Text
If you add separate files for chapters and scenes, the chapter file is the perfect place to add
such text. Separating chapter and scene files also allows you to make scene files child
documents of the chapter (added in novelWriter 2.0).
documents of the chapter.
.. versionadded:: 2.0
.. dropdown:: Distinguishing Soft and Hard Scene Breaks
:animate: fade-in-slide-down
@@ -64,12 +66,15 @@ Organising Your Text
Depending on your writing style, you may need to separate between soft and hard scene breaks
within chapters. Like for instance if you switch point-of-view character often.
In such cases you may want to use the scene heading for hard scene breaks and section headings
for soft scene breaks. the :guilabel:`Build Manuscript` tool will let you add separate
In such cases you may want to use a scene heading for hard scene breaks and a section heading
for soft scene breaks. The :guilabel:`Build Manuscript` tool will let you add separate
formatting for the two when you generate your manuscript. You can for instance add the common
"``* * *``" for hard breaks and select to hide section breaks, which will just insert an empty
paragraph in their place. See :ref:`a_manuscript_settings` for more details.
Keep in mind that this is not what the section heading is intended for, so the app will not
understand the section heading as a scene, but it will be formatted correctly in the manuscript.
Other Tools
===========

View File

@@ -8,9 +8,18 @@ Key Features
.. _Markdown: https://en.wikipedia.org/wiki/Markdown
At its core, novelWriter is a multi-document plain text editor. It uses a markup syntax inspired by
Markdown_ to apply simple formatting to the text. It is designed for writing fiction, so the
formatting features available are limited to those relevant for this purpose. It is *not* suitable
for technical writing, and it is *not* a full-featured Markdown editor.
Markdown_ to apply simple formatting to the text. It also allows for some extended formatting codes
using a shortcode format. See :ref:`a_fmt_shortcodes` for more details.
.. admonition:: Limitations
novelWriter is designed for writing fiction, so the formatting features available are limited to
those relevant for this purpose. It is **not** suitable for technical writing, and it is **not**
a full-featured Markdown editor.
It is also not intended as a tool to organise research for writing, and therefore lacks
formatting features you may need for this purpose. The notes feature in novelWriter is mainly
intended for character profiles and plot outlines.
Your novel project is organised as a collection of separate plain text documents instead of a
single, large document. The idea is to make it easier to reorganise your project structure without
@@ -20,10 +29,10 @@ There are two kinds of documents in your project: :term:`Novel Documents` are do
part of your story. The other kind of documents are :term:`Project Notes`. These are intended for
your notes about your characters, your world building, and so on.
You can at any point split the individual documents by their headers up into multiple documents, or
merge multiple documents into single documents. This makes it easier to use variations of the
You can at any point split the individual documents by their headings up into multiple documents,
or merge multiple documents into single documents. This makes it easier to use variations of the
Snowflake_ method for writing. You can start by writing larger structure-focused documents, like
one per act for instance, and later effortlessly split these up into scenes by their headers.
one per act for instance, and later effortlessly split these up into chapters or scenes.
Below are some key features of novelWriter.
@@ -45,15 +54,15 @@ Below are some key features of novelWriter.
build the project into a manuscript, they are all glued together in the top-to-bottom order in
which they appear in the project tree. You can use as few text documents as you like, but
splitting the project up into chapters and scenes means you can easily reorder them using the
drag-and-drop feature of the project tree. You can also start out with a few documents and then
later split them into multiple documents based on their headers.
drag-and-drop feature of the project tree. You can also start out with fewer documents and then
later split them into multiple documents based on chapter and scene headings.
**Multi-novel project support**
As of novelWriter 2.0, you can have multiple Novel type root folders in a project. This allows
you to keep a series of individual novels with the same characters and world building in the
same project, and create manuscripts for them individually.
You can have multiple Novel type root folders in a project. This allows you to keep a series of
individual novels with the same characters and world building in the same project, and create
manuscripts for them individually.
**Keep track of your plot elements**
**Keep track of your story elements**
All notes in your project can be assigned a :term:`tag` that you can :term:`reference` from any
other document or note. In fact, you can add a new tag under each heading of a note if you need
to be able to reference specific sections of it.
@@ -69,10 +78,10 @@ Below are some key features of novelWriter.
**Get an overview of your story elements**
Under the document viewer panel you will find a series of tabs that shows the different story
elements you have created tags for. The tabs are sorted into Characters, Plots, etc, depending
on which categories you are using in your story. This panel can be hidden when you don't need it
to free up space.
on which categories you are using in your story. This panel can be hidden to free up space when
you don't need it.
**Building your manuscript**
**Assembling your manuscript**
Whether you want to assemble a manuscript, or export all your notes, or generate an outline of
your chapters and scenes with a synopsis, you can use the :guilabel:`Build Manuscript` tool to
do so. The tool lets you select what information you want to include in the generated document,

View File

@@ -11,9 +11,9 @@ Overview
:width: 220
novelWriter is built as a cross-platform application using `Python 3 <https://www.python.org/>`_ as
the programming language, and `Qt 5 <https://www.qt.io/>`_ for the user interface.
the programming language, and `Qt 5 <https://www.qt.io/>`_ framework for the user interface.
novelWriter is built for Linux first, and this is where it works best. However, it also runs fine
novelWriter is built for Linux first, so this is where it works best. However, it also runs fine
on Windows and MacOS due to the cross-platform framework it's built on. The author of the
application doesn't own a Mac, so on-going Mac support is dependent on user feedback and user
contributions.
@@ -22,7 +22,7 @@ Spell checking in novelWriter is provided by a third party library called
`Enchant <https://abiword.github.io/enchant/>`_. Please see the section on :ref:`a_custom_dict` for
how to install spell checking languages.
For install instructions, see :ref:`a_started`.
For install instructions for novelWriter, see :ref:`a_started`.
Using novelWriter
@@ -58,12 +58,6 @@ read on.
your language, and other special characters. If you use any symbols aside from these, their
intended use is explained here.
:ref:`a_prjfmt` – Optional
This chapter is more technical and has an overview of changes made to the way your project data
is stored. The format has changed a bit from time to time, and sometimes the changes require
that you make small modifications to your project. Everything you need to know is listed in this
chapter.
Organising Your Projects
========================
@@ -90,3 +84,11 @@ meta data for it to extract.
:ref:`a_manuscript` - Recommended Reading
This chapter explains how the :guilabel:`Manuscript Build` tool works, how you can control the
way chapter titles are formatted, and how scene and section breaks are handled.
Additional Details & Technical Topics
=====================================
The Additional Details and the Technical Topics sections contain more in-depth information about
how various bits of novelWriter works. This information is not essential to getting started using
novelWriter.

View File

@@ -6,7 +6,7 @@ Getting Started
.. _Enchant: https://abiword.github.io/enchant/
.. _GitHub: https://github.com/vkbo/novelWriter
.. _main website: https://novelwriter.io
.. _Downloads page: https://download.novelwriter.io
.. _PPA: https://launchpad.net/~vkbo/+archive/ubuntu/novelwriter
.. _Pre-Release PPA: https://launchpad.net/~vkbo/+archive/ubuntu/novelwriter-pre
.. _PyPi: https://pypi.org/project/novelWriter/
@@ -15,9 +15,10 @@ Getting Started
.. _AppImage: https://appimage.org/
Ready-made packages and installers for novelWriter are available for all major platforms, including
Linux, Windows and MacOS. See below for install instructions for each platform.
Linux, Windows and MacOS, from the `Downloads page`_. See below for install instructions for each
platform.
You can also install novelWriter from the Python Package Index (PyPi). See :ref:`a_started_pip`.
You can also install novelWriter from the Python Package Index (PyPi_). See :ref:`a_started_pip`.
Installing from PyPi does not set up icon launchers, so you will either have to do this yourself,
or start novelWriter from the command line.
@@ -32,7 +33,7 @@ Installing on Windows
=====================
You can install novelWriter with both Python and library dependencies embedded using the Windows
Installer (setup.exe) file from the `main website`_, or from the Releases_ page on GitHub_.
Installer (setup.exe) file from the `Downloads page`_, or from the Releases_ page on GitHub_.
Installing it should be straightforward.
If you have any issues, try uninstalling the previous version and making a fresh install. If you
@@ -51,8 +52,8 @@ multiple installations has been known to cause problems.
Installing on Linux
===================
A Debian package can be downloaded from the `main website`_, or from the Releases_ page on GitHub_.
This package should work on both Debian, Ubuntu and Linux Mint, at least.
A Debian package can be downloaded from the `Downloads page`_, or from the Releases_ page on
GitHub_. This package should work on both Debian, Ubuntu and Linux Mint, at least.
If you prefer, you can also add the novelWriter repository on Launchpad to your package manager.
@@ -82,7 +83,7 @@ Instead, run the following commands to add the repository and key:
.. code-block:: bash
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/novelwriter-ppa-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys F19F1FCE50043114
echo "deb [signed-by=/usr/share/keyrings/novelwriter-ppa-keyring.gpg] http://ppa.launchpad.net/vkbo/novelwriter/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/novelwriter.list
echo "deb [signed-by=/usr/share/keyrings/novelwriter-ppa-keyring.gpg] http://ppa.launchpad.net/vkbo/novelwriter/ubuntu noble main" | sudo tee /etc/apt/sources.list.d/novelwriter.list
Then run the update and install commands as for Ubuntu:
@@ -112,8 +113,8 @@ completely standalone images for the app that include the necessary environment
They can of course be run on any Linux distro, if you prefer this to native packages.
.. note::
novelWriter generally don't support Python versions that have reached end of life. If your Linux
distro still uses older Python versions and novelWriter won't run, you may want to try the
novelWriter generally doesn't support Python versions that have reached end of life. If your
Linux distro still uses older Python versions and novelWriter won't run, you may want to try the
AppImage instead.
@@ -123,14 +124,14 @@ Installing on MacOS
===================
You can install novelWriter with both its Python and library dependencies embedded using the DMG
application image file from the `main website`_, or from the Releases_ page on GitHub_. Installing
it should be straightforward.
application image file from the `Downloads page`_, or from the Releases_ page on GitHub_.
Installing it should be straightforward.
* Download the DMG file and open it. Then drag the novelWriter icon to the :guilabel:`Applications`
folder on the right. This will install it into your :guilabel:`Applications`.
* The first time you try to launch it, it will say that the bundle cannot be verified, simply press
the :guilabel:`Open` button to add an exception.
* If you are not presented with an :guilabel:`Open` button in the dialog launch the application
* If you are not presented with an :guilabel:`Open` button in the dialog, launch the application
again by right clicking on the application in Finder and selecting :guilabel:`Open` from the
context menu.
@@ -149,7 +150,7 @@ Installing from PyPi
====================
novelWriter is also available on the Python Package Index, or PyPi_. This install method works on
all supported operating systems.
all supported operating systems with a suitable Python environment.
To install from PyPi you must first have the ``python`` and ``pip`` commands available on your
system. You can download Python from `python.org`_. It is recommended that you install the latest

View File

@@ -0,0 +1,39 @@
.. _a_counting:
********************
Word and Text Counts
********************
This is an overview of how words and other counts of your text are performed. The counting rules
should be relatively standard, and are compared to LibreOffice Writer rules. The counts provided in
the app on the raw text are only meant to be approximate.
Text Word Counts and Stats
==========================
These are the rules for the main counts available for for each document in a project.
For all counts, the following rules apply.
#. Short (–) and long (—) dashes are considered word separators.
#. Any line starting with ``%`` or ``@`` is ignored.
#. Trailing white spaces are ignored, including line breaks.
#. Leading ``>`` and trailing ``<`` are ignored with any spaces next to them.
#. Valid shortcodes and other commands wrapped in brackets ``[]`` are ignored.
#. In-line Markdown syntax in text paragraphs is treated as part of the text.
After the above preparation of the text, the following counts are available.
**Character Count**
The character count is the sum of characters per line, including leading and in-text white space
characters, but excluding trailing white space characters. Shortcodes in the text are not
included, but Markdown codes are. Only headers and text are counted.
**Word Count**
The words count is the sum of blocks of continuous character per line separated by any number of
white space characters or dashes. Only headers and text are counted.
**Paragraph Count**
The paragraph count is the number of text blocks separated by one or more empty line. A line
consisting only of white spaces is considered empty.

View File

@@ -10,7 +10,7 @@ You can activate it from the sidebar, the :guilabel:`Tools` menu, or by pressing
.. versionadded:: 2.1
This tool is new for version 2.1. A simpler tool was used for earlier versions. The simpler tool
only allows you to define a single set of options for the build, but otherwise has much the same
only allows you to define a single set of options for the build, but otherwise had much the same
functionality.
@@ -73,7 +73,7 @@ Formatting Headings
The :guilabel:`Headings` page of the :guilabel:`Manuscript Build Settings` dialog allows you to set
how the headings in your :term:`Novel Documents` are formatted. By default, the title is just
copied as-is, indicated by the ``{Title}`` format. You can change this to for instance add chapter
numbers and scene numbers like shown int he figure above.
numbers and scene numbers, or insert character names, like shown in the figure above.
Clicking the edit button next to a format will copy the formatting string into the edit box where
it can be modified, and where a syntax highlighter will help indicate which parts are automatically
@@ -152,7 +152,7 @@ novelWriter Markup
Standard/Extended Markdown
The Markdown format comes in both Standard and Extended flavour. The *only* difference in terms
of novelWriter functionality is the support for strikethrough text, which is not supported by
of novelWriter functionality is the support for strike through text, which is not supported by
the Standard flavour.

View File

@@ -4,21 +4,25 @@
Novel Projects
**************
New projects can be created from the :guilabel:`Project` menu by selecting :guilabel:`New Project`.
This will open the :guilabel:`New Project Wizard` that will assist you in creating a bare bone
project suited to your needs.
New projects can be created from the :guilabel:`Project` menu by selecting
:guilabel:`Create or Open Project`. This will open the :guilabel:`Welcome` dialog, where you can
select the :guilabel:`New` button that will assist you in creating a new project.
A novelWriter project requires a dedicated folder for storing its files on the local file system.
If you're interested in the details, you can have a look at the chapter :ref:`a_storage`.
A list of recently opened projects is maintained, and displayed in the :guilabel:`Open Project`
A list of recently opened projects is maintained, and displayed in the :guilabel:`Welcome`
dialog. A project can be removed from this list by selecting it and pressing the :kbd:`Del` key or
by clicking the :guilabel:`Remove` button.
by right-clicking it and selecting the :guilabel:`Remove Project` option.
.. figure:: images/fig_welcome.jpg
The project list (left) and new project form (right) of the :guilabel:`Welcome` dialog.
Project-specific settings are available in :guilabel:`Project Settings` in the :guilabel:`Project`
menu. See further details below in the :ref:`a_proj_settings` section. Details about the project,
including word counts, and a table of contents with word and page counts, is available through the
:guilabel:`Project Details` dialog.
menu. See further details below in the :ref:`a_proj_settings` section. Details about the project's
novel text, including word counts, and a table of contents with word and page counts, is available
through the :guilabel:`Novel Details` dialog.
.. _a_proj_roots:
@@ -58,8 +62,9 @@ details, see the :ref:`a_references` chapter.
Character notes go in this root folder type. These are especially important if you want to use
the :guilabel:`Outline View` to see which character appears where, which part of the story is
told from a specific character's point-of-view, or focusing on a particular character's
storyline. Tags in this type of folder can be referenced using the ``@pov`` keyword for
point-of-view characters, ``@focus`` for a focus character, or the ``@char`` keyword for any
storyline. The character names can also be inserted into for instance chapter titles when you
create your manuscript. Tags in this type of folder can be referenced using the ``@pov`` keyword
for point-of-view characters, ``@focus`` for a focus character, or the ``@char`` keyword for any
other character present.
:guilabel:`Locations`
@@ -105,8 +110,8 @@ trash folder can then be deleted permanently, either individually, or by emptyin
the menu. Documents in the trash folder are removed from the :term:`project index` and cannot be
referenced.
A document or a folder can be deleted from the :guilabel:`Project` menu, or by pressing
:kbd:`Ctrl+Shift+Del`. Root folders can only be deleted when they are empty.
A document or a folder can be moved to trash from the :guilabel:`Project` menu, or by pressing
:kbd:`Ctrl+Shift+Del`. Root folders can only be removed when they are empty.
.. _a_proj_roots_out:
@@ -129,9 +134,9 @@ Recovered Documents
-------------------
If novelWriter crashes or otherwise exits without saving the project state, or if you're using a
file synchronisation tool that runs out of sync, there may be files in the project folder that
aren't tracked in the core project file. These files, when discovered, are recovered and added back
into the project.
file synchronisation tool that runs out of sync, there may be files in the project storage folder
that aren't tracked in the core project file. These files, when discovered, are recovered and added
back into the project.
The discovered files are scanned for metadata that give clues as to where the document may
previously have been located in the project. The project loading routine will try to put them back
@@ -152,10 +157,10 @@ Project Lockfile
----------------
To prevent lost documents caused by file conflicts when novelWriter projects are synchronised via
file synchronisation tools, a project lockfile is written to the project folder. If you try to open
a project which has such a file present, you will be presented with a warning, and some information
about where else novelWriter thinks the project is also open. You will be given the option to
ignore this warning, and continue opening the project at your own risk.
file synchronisation tools, a project lockfile is written to the project storage folder. If you try
to open a project which has such a file present, you will be presented with a warning, and some
information about where else novelWriter thinks the project is also open. You will be given the
option to ignore this warning, and continue opening the project at your own risk.
.. note::
If, for some reason, novelWriter crashes, the lock file may remain even if there are no other
@@ -208,6 +213,18 @@ converting, splitting, or merging items. See :ref:`a_ui_tree_split_merge` for mo
latter two.
Document Templates
------------------
If you wish to create template documents to be used when creating new project documents, like for
instance a character note template, you can add a :guilabel:`Templates` root folder to your
project. Any document added to this root folder will show up in the :guilabel:`Add Item` menu in
the project tree toolbar. When selected, a new document is created with its content copied from the
chosen template.
.. versionadded:: 2.3
.. _a_proj_files_counts:
Word Counts
@@ -227,6 +244,8 @@ the values in the project tree, which again depend on an up to date :term:`proje
counts seem wrong, a full project word recount can be initiated by rebuilding the project's index.
Either from the :guilabel:`Tools` menu, or by pressing :kbd:`F9`.
The rules for how the counts are made is covered in more detail in :ref:`a_counting`.
.. _a_proj_settings:
@@ -242,25 +261,23 @@ Settings Tab
The :guilabel:`Settings` tab holds the project name, title, and author settings.
The :guilabel:`Project Name` can be set to a different value than the :guilabel:`Novel Title`. The
difference between them is simply that the :guilabel:`Project Name` is used for the GUI (main
window title) and for generating backup files. The intention is that the :guilabel:`Project Name`
should remain unchanged throughout the project's lifetime, otherwise the name of exported files and
backup files may change too.
The :guilabel:`Project Name` can be edited here. It is used for the GUI (main window title) and for
generating backup files. So keep in mind that if you do change this setting, the backup file names
will change too.
The :guilabel:`Novel Title` and :guilabel:`Authors` settings are used when building the manuscript,
for some formats.
You can also change the :guilabel:`Authors` and :guilabel:`Project Language` setting. These are
only used when building the manuscript, for some formats.
If your project is in a different language than your main spell checking language is set to, you
can override the default setting here. You can also override the automatic backup setting. The
project language can also be changed from the :guilabel:`Tools` menu.
can override the default setting here. The project language can also be changed from the
:guilabel:`Tools` menu. You can also override the automatic backup setting if you wish.
Status and Importance Tabs
--------------------------
Each document or folder of type :guilabel:`Novel` can be given a *Status* label accompanied by a
coloured icon, and each document or folder of the remaining types can be given an *Importance*
Each document or folder of type :guilabel:`Novel` can be given a "Status" label accompanied by a
coloured icon, and each document or folder of the remaining types can be given an "Importance"
label.
These labels are there purely for your convenience, and you are not required to use them for any

View File

@@ -4,21 +4,21 @@
Tags and References
*******************
In novelWriter there are no forms or tables to fill in to define the characters, locations and
other elements of your story. Instead, you can mark your :term:`project notes` as representing
these story elements by creating a :term:`tag`. Whenever you want to link a piece of your story to
a note defining a story element, like a character, you create a :term:`reference` back to that tag.
You can also cross-link your project notes in the same way.
In novelWriter there are no forms or tables to fill in to define characters, locations or other
elements of your story. Instead, you create :term:`project notes` which you can mark as
representing these story elements by creating a :term:`tag`. Whenever you want to link a piece of
your story to a note defining a story element, like a character, you create a :term:`reference`
back to that tag. You can also cross-link your project notes in the same way.
This is perhaps one of the features that makes novelWriter different from other, similar
applications. It is therefore not always obvious to new users how this is supposed to work, so
this chapter hopes to explains in more detail how to use the tags and references system.
this chapter hopes to explain in more detail how to use this tags and references system.
.. tip::
If you find the Tags and Reference system difficult to follow just from reading this chapter,
you can create a new project in novelWriter and select to "Fill the project with example files"
in the :guilabel:`New Project Wizard`. The example project contains several examples of tags and
references.
you can create a new project in the :guilabel:`Welcome` dialog's New project form and select
"Create an example project" from the "Pre-fill project" option. The example project contains
several examples of tags and references.
.. _a_references_metadata:
@@ -31,14 +31,15 @@ documents, not the documents themselves. See :ref:`a_struct_heads` for more deta
metadata is also associated with headings, and not the documents directly.
If you split your project into separate documents for each scene, this distinction may not matter.
However, there are several benefits to using documents at a larger structural scale when starting
your project. For instance, it may make more sense to define all your scenes, and even chapters, in
a single document at first, or perhaps a document per act. You can later split these documents up
using the document split feature. See :ref:`a_ui_tree_split_merge` for more details.
However, there are several benefits to using documents at a larger structural scale when first
starting your project. For instance, it may make more sense to define all your scenes, and even
chapters, in a single document at first, or perhaps a document per act. You can later split these
documents up using the document split feature. See :ref:`a_ui_tree_split_merge` for more details.
The implication here is that you can treat each heading as an independent element of your notes
that can be referenced somewhere else. In order to make it possible to reference a header section,
you need to assign it a tag.
You can do the same with your notes. You can treat each heading as an independent element of your
notes that can be referenced somewhere else. That way you can collect all your minor or background
characters in a single note file, and still be able to reference them individually by separating
them with headings and assigning each a tag.
.. _a_references_tags:
@@ -47,43 +48,63 @@ How to Use Tags
===============
A "tag" in novelWriter is a word or phrase that you define as belonging to a heading. Tags are set
by using the ``@tags`` :term:`keyword`. The full format of a tag is ``@tag: tagname``, where
``tagname`` is an identifier of your choosing. You can only set *one* tag per heading, and the tag
has to be unique across all documents in the project.
by using the ``@tag`` :term:`keyword`.
.. versionadded:: 2.2
Tags are now case insensitive.
The basic format of a tag is ``@tag: tagName``.
After the tags have been defined, they can then be referenced in the novel documents, or
cross-referenced in other notes. they will also show up in the :guilabel:`Outline View` and in the
back-reference panel when a document is opened in the viewer.
An alternative format of a tag is ``@tag: tagName | displayName``.
``tagName`` (Required)
This is a unique identifier of your choosing. It is the value you use later for making
references back to this document, or section of the document.
``displayName`` (Optional)
This is an optional display name used for the tag. When you build your manuscript, you can for
instance insert the point of view character name directly into chapter headings. By default, the
``tagName`` value is used in such headings, but if you use a shortened format internally in your
project, you can use this to specify a more suitable format for your manuscript headings.
You can only set **one** tag per heading, and the tag has to be unique across **all** documents in
the project.
After a tag has been defined, it can be referenced in novel documents, or cross-referenced in other
notes. Tags will also show up in the :guilabel:`Outline View` and in the references panel under the
document viewer when a document is open in the viewer.
The syntax highlighter will indicate to you that the keyword is correctly used and that the tag is
allowed, that is, the tag is unique. Duplicate tags should be detected as long as the index is up
to date. An invalid tag should have a green wiggly line under it, and will not receive the syntax
colour that valid tags do.
to date. An invalid tag should have a green wiggly line under it, and will not receive the colour
that valid tags do.
The tag is the only part of these notes that novelWriter uses. The rest of the document content is
there for you to use in whatever way you wish. Of course, the content of the documents can be added
to the manuscript, or an outline document. If you want to compile a single document of all your
notes, you can do this from the :guilabel:`Manuscript Build` tool.
.. versionadded:: 2.2
Tags are no longer case sensitive. The tags are by default displayed with the capitalisation you
use when defining the tag, but you don't have to use the same capitalisation when referencing
it later.
.. versionadded:: 2.3
Tags can have an optional display name for manuscript builds.
Example of a heading with a tag for a character of the story:
.. code-block:: none
.. code-block:: md
# Jane Doe
# Character: Jane Doe
@tag: Jane
@tag: Jane | Jane Doe
Some information about the character Jane Doe.
When this is done in a document in a :term:`Root Folder` of type "Characters", the tag is
automatically treated as an available character in your project, and you will be able to reference
it in any of your other documents using the reference keywords for characters. It will also show up
in the Character tab in the Reference panel below the document viewer, and in the reference
auto-completer menu in the editor when you fill in references. See :ref:`a_ui_view` and
:ref:`a_references_completer`.
automatically treated as an available character in your project with the value "Jane", and you will
be able to reference it in any of your other documents using the reference keywords for characters.
It will also show up in the Character tab in the Reference panel below the document viewer, and in
the reference auto-completer menu in the editor when you fill in references. See :ref:`a_ui_view`
and :ref:`a_references_completer`.
It is the root folder type that defines what category of story elements the tag is indexed under.
See the :ref:`a_proj_roots` section for an overview of available root folder types. They are also
@@ -172,7 +193,7 @@ highlight that two notes are related.
Example of a novel document with references to characters and plots:
.. code-block:: none
.. code-block:: md
## Chapter 1

View File

@@ -7,10 +7,11 @@ Novel Structure
This chapter covers the structure of a novel project.
There are two different types of documents in a project, :guilabel:`Novel Documents` and
:guilabel:`Project Notes`. Novel documents can only live in a :guilabel:`Novel` type root folder.
You can also move them to :guilabel:`Archive` and :guilabel:`Trash` of course.
:guilabel:`Project Notes`. Active novel documents can only live in a :guilabel:`Novel` type root
folder. You can also move them to :guilabel:`Archive` and :guilabel:`Trash` of course, where they
become inactive.
The :guilabel:`Project Tree` can distinguish between the different header levels of the novel
The :guilabel:`Project Tree` can distinguish between the different heading levels of the novel
documents using coloured icons, and optionally add emphasis on the label, set in
:guilabel:`Preferences`.
@@ -27,47 +28,47 @@ Four levels of headings are supported, signified by the number of hashes (``#``)
title. See also the :ref:`a_fmt` section for more details about the markup syntax.
.. note::
The header levels are not only important when generating the manuscript, they are also used by
The heading levels are not only important when generating the manuscript, they are also used by
the indexer when building the outline tree in the :guilabel:`Outline View` as well as in the
:guilabel:`Novel Tree`. Each heading also starts a new region where new Tags and References
can be defined. See :ref:`a_references` for more details.
The syntax for the four basic header types, and the two special header types, is listed in section
The syntax for the four basic heading types, and the two special types, is listed in section
:ref:`a_fmt_head`. The meaning of the four levels for the structure of your novel is as follows:
**Header Level 1: Partition**
This header level signifies that the text refers to a top level partition. This is useful when
**Heading Level 1: Partition**
This heading level signifies that the text refers to a top level partition. This is useful when
you want to split the manuscript up into books, parts, or acts. These headings are not required.
The novel title itself should use the special header level ``#!`` covered in :ref:`a_fmt_head`.
The novel title itself should use the special heading level ``#!`` covered in :ref:`a_fmt_head`.
**Header Level 2: Chapter**
This header level signifies a chapter level partition. Each time you want to start a new
**Heading Level 2: Chapter**
This heading level signifies a chapter level partition. Each time you want to start a new
chapter, you must add such a heading. If you choose to split your manuscript up into one
document per scene, you need a single chapter document with just the heading. You can of course
also add a synopsis and reference keywords to the chapter document. If you want to open the
chapter with a quote or other introductory text that isn't part of a scene, this is also where
you'd put that text.
**Header Level 3: Scene**
This header level signifies a scene level partition. You must provide a title text, but the
**Heading Level 3: Scene**
This heading level signifies a scene level partition. You must provide a title text, but the
title text can be replaced with a scene separator or just skipped entirely when you build your
manuscript.
**Header Level 4: Section**
This header level signifies a sub-scene level partition, usually called a "section" in the
**Heading Level 4: Section**
This heading level signifies a sub-scene level partition, usually called a "section" in the
documentation and the user interface. These can be useful if you want to change references
mid-scene, like if you change the point-of-view character. You are free to use sections as you
wish, and you can filter them out of the final manuscript just like with scene titles.
Page breaks are automatically added before level 1 and 2 headers when you build your project to a
format that supports page breaks, or when you print the document directly from the
:guilabel:`Manuscript Build` tool. If you want page breaks in other places, you have to specify
them manually. See :ref:`a_fmt_break`.
Page breaks are automatically added before partition and chapter headings when you build your
project to a format that supports page breaks. If you want page breaks in other places, you have to
specify them manually. See :ref:`a_fmt_break`.
.. tip::
There are multiple options of how to process novel titles when building the manuscript. For
There are multiple options of how to process novel headings when building the manuscript. For
instance, chapter numbers can be applied automatically, and so can scene numbers if you want
them in a draft manuscript. See the :ref:`a_manuscript` page for more details.
them in a draft manuscript. You can also insert point-of-view character names in chapter titles.
See the :ref:`a_manuscript` page for more details.
.. _a_struct_heads_title:
@@ -76,17 +77,21 @@ Novel Title and Front Matter
----------------------------
It is recommended that you add a document at the very top of each Novel root folder with the novel
title as the first line. You should modify the level 1 header format code with an ``!`` in order to
render it as a document title that is excluded from any automatic Table of Content in a manuscript
build document, like so:
title as the first line. You should modify the level 1 heading format code with an ``!`` in order
to render it as a document title that is excluded from any automatic Table of Content in a
manuscript build document, like so:
``#! My Novel``
.. code-block:: md
#! My Novel
>> _by Jane Doe_ <<
The title is by default centred on the page. You can add more text to the page as you wish, like
for instance the author's name and details.
If you want an additional page of text after the title page, starting on a fresh page, you can add
``[NEW PAGE]`` on a line by itself, and continue the text after it. This will insert a page break
``[new page]`` on a line by itself, and continue the text after it. This will insert a page break
before the text. See also :ref:`a_fmt_break`.
@@ -96,15 +101,19 @@ Unnumbered Chapter Headings
---------------------------
If you use the automatic numbering feature for your chapters, but you want to keep some special
chapters separate from this, you cam add an ``!`` to the level 2 header formatting code to tell the
build tool to skip these chapters.
chapters separate from this, you can add an ``!`` to the level 2 heading formatting code to tell
the build tool to skip these chapters.
``##! Unnumbered Chapter Title``
.. code-block:: md
There is a separate formatting feature for such chapters in the :guilabel:`Manuscript Build` tool
as well. See the :ref:`a_manuscript` page for more details. When building a document of a format
that supports page breaks, also unnumbered chapters will have a page break added just like for
normal chapters.
##! Unnumbered Chapter Title
Chapter Text
There is a separate formatting feature for such chapter titles in the :guilabel:`Manuscript Build`
tool as well. See the :ref:`a_manuscript` page for more details. When building a document of a
format that supports page breaks, also unnumbered chapters will have a page break added just like
for normal chapters.
.. Note::
Previously, you could also disable the automatic numbering of a chapter by adding an ``*`` as

View File

@@ -33,7 +33,7 @@ itself. It is important to keep this file backed up, either through the built-in
your own backup solution.
The project XML file is indent-formatted, and is suitable for diff tools and version control since
most of the file will stay static, although a timesetamp is set in the meta section on line 2, and
most of the file will stay static, although a timestamp is set in the meta section on line 2, and
various meta data entries incremented, on each save.
.. only:: not html
@@ -91,11 +91,6 @@ If successful, the old data file is then removed, and the temporary file replace
that the previously saved data is only replaced when the new data has been successfully saved to
the storage medium.
For the project XML file, a ``.bak`` file is in addition kept, which will always contain the
previous version of the file, although when auto-save is enabled, they may have the same content.
If the opening of a project file fails, novelWriter will automatically try to open the ``.bak``
file instead.
Project Meta Data
=================

View File

@@ -10,7 +10,7 @@ How it Works
The main features of novelWriter are listed in the :ref:`a_intro` chapter. In this chapter, we go
into some more details on how they are implemented. This is intended as an overview. Later on in
this documentation, these features will be covered in more detail.
this documentation these features will be covered in more detail.
.. _a_breakdown_design:
@@ -23,6 +23,8 @@ at the same time provide useful features needed for writing a novel.
The main window does not have an editor toolbar like many other applications do. This reduces
clutter, and since the documents are formatted with style tags, it is more or less redundant.
Still, a small formatting toolbar can be popped out by clicking the three dots in the header of the
document editor to give quick access to standard formatting codes.
Most formatting features supported are available through convenient keyboard shortcuts. They are
also available in the main menu, so you don't have to look up formatting codes every time you need
@@ -31,7 +33,8 @@ them. For reference, a list of all shortcuts can be found in the :ref:`a_kb` cha
.. note::
novelWriter is not intended to be a full office type word processor. It doesn't support images,
links, tables, and other complex structures and objects often needed for such documents.
Formatting is limited to headers, emphasis, text alignment, and a few other simple features.
Formatting is limited to headings, in-line basic text formats, text alignment, and a few other
simple features.
On the left side of the main window, you will find a sidebar. This bar has buttons for the standard
views you can switch between, a quick link to the :guilabel:`Build Manuscript` tool, and a set of
@@ -54,18 +57,18 @@ When in :guilabel:`Project Tree View` mode, the main work area of the main windo
or optionally three, panels. The left-most panel contains the project tree and all the documents in
your project. The second panel is the document editor.
An optional third panel on the right contains a document viewer which can view any document in your
project independently of what is open in the document editor. This panel is not intended as a
preview window, although you can use it for this purpose if you wish as it will apply the
formatting tags you have specified. The main purpose of the viewer is for viewing your notes next
to your editor while you're writing.
An optional third panel on the right side contains a document viewer which can view any document in
your project independently of what is open in the document editor. This panel is not intended as a
preview window, although you can use it for this purpose if you wish if you need to check that the
formatting tags behave as you expected. The main purpose of the viewer is for viewing your notes
next to your editor while you're writing.
The editor also has a :guilabel:`Focus Mode` you can toggle either from the menu, from the icon in
the editor's header, or by pressing :kbd:`F8`. When :guilabel:`Focus Mode` is enabled, all the user
interface elements other than the document editor itself are hidden away.
Novel Tree and Editor View
Novel View and Editor View
--------------------------
.. figure:: images/fig_novel_tree_view.png
@@ -81,17 +84,17 @@ Each heading is indented according to the heading level. You can open and edit y
from this view as well. All headings contained in the currently open document should be highlighted
in the view to indicate which ones belong together in the same document.
If you have multiple Novel root folders, the header of the novel view becomes a dropdown box. You
can then switch between them by clicking the :guilabel:`Outline of ...` text. You can also click
the novel icon button next to it.
If you have multiple "Novel" type root folders, the header of the novel view becomes a dropdown
box. You can then switch between them by clicking the :guilabel:`Outline of ...` text. You can also
click the novel icon button next to it.
Generally, the novel view should update when you make changes to the novel structure, including
edits of the current document in the editor. The information is only updated when the automatic
save of the document is triggered, or you manually press :kbd:`Ctrl+S` to save changes. (You can
adjust the auto-save interval in :guilabel:`Preferences`.) You can also regenerate the whole novel
view by pressing the refresh button at the top of the side panel.
view by pressing the refresh button in the novel view header.
It is possible to show an optional third column in the novel view, The settings are available from
It is possible to show an optional third column in the novel view. The settings are available from
the menu button in the toolbar.
If you click the arrow icon to the right of each item, a tooltip will pop out showing you all the
@@ -123,12 +126,12 @@ neutral colours from :guilabel:`Preferences`. Other colour themes are also avail
can be contributed to novelWriter on GitHub.
Switching the GUI colour theme does not affect the colours of the editor and viewer. They have
separate colour themes called :guilabel:`Editor Themes`. They are separated because there are a lot
more options to choose from for the editor and viewer.
separate colour selectable from the "Document colour theme" setting in :guilabel:`Preferences`.
They are separated because there are a lot more options to choose from for the editor and viewer.
.. note::
If you switch to dark mode on the GUI, you should also switch editor theme to match, otherwise
icons may be hard to see in the editor and viewer.
If you switch between light and dark mode on the GUI, you should also switch editor theme to
match, otherwise icons may be hard to see in the editor and viewer.
.. _a_breakdown_project:
@@ -147,7 +150,7 @@ within those documents.
.. figure:: images/fig_header_levels.png
An illustration of how header levels correspond to the novel structure.
An illustration of how heading levels correspond to the novel structure.
The four heading levels (**H1** to **H4**) are treated as follows:
@@ -158,8 +161,8 @@ The four heading levels (**H1** to **H4**) are treated as follows:
The project tree will select an icon for the document based on the first heading in it.
This header level structure is only taken into account for :term:`novel documents`. For
:term:`project notes`, the header levels have no structural meaning, and you are free to use them
This heading level structure is only taken into account for :term:`novel documents`. For
:term:`project notes`, the heading levels have no structural meaning, and you are free to use them
however you want. See :ref:`a_struct` and :ref:`a_references` for more details.
.. versionadded:: 2.0
@@ -171,8 +174,8 @@ however you want. See :ref:`a_struct` and :ref:`a_references` for more details.
.. _a_breakdown_export:
Building the Manuscript
=======================
Building a Manuscript
=====================
The project can at any time be assembled into a range of different formats through the
:guilabel:`Build Manuscript` tool. Natively, novelWriter supports `Open Document`_, HTML5, and
@@ -217,8 +220,8 @@ Secondly, having multiple small files means it is very easy to synchronise them
with standard file synchronisation tools.
Thirdly, if you use version control software to track the changes to your project, the file formats
used for the files are well suited. Also the JSON documents have line breaks and indents, which
makes it easier to track them with version control software.
used for the files are well suited. All the JSON documents have line breaks and indents as well,
which makes it easier to track them with version control software.
.. note::
Since novelWriter has to keep track of a bunch of files and folders when a project is open, it

View File

@@ -6,8 +6,8 @@ Formatting Your Text
The novelWriter text editor is a plain text editor that uses formatting codes for setting meta data
values and allowing for some text formatting. The syntax is based on Markdown, but novelWriter is
*not* a Markdown editor. It supports basic formatting like emphasis (italic), strong importance
(bold) and strike through text, as well as four levels of headings. Form some further complex
**not** a Markdown editor. It supports basic formatting like emphasis (italic), strong importance
(bold) and strike through text, as well as four levels of headings. For some further complex
formatting needs, a set of shortcodes can be used.
In addition to formatting codes, novelWriter allows for comments, a synopsis tag, and a set of
@@ -30,7 +30,7 @@ dialogue in your text.
An example of the colour highlighting of references. "Bob" is not defined, and "@blabla" is not
a valid reference type.
When you use the commands to set tags and references, these also change colour. Correct commands
When you use the keywords to set tags and references, these also change colour. Correct keywords
have a distinct colour, and the references themselves will get a colour if they are valid. Invalid
references will get a squiggly error line underneath. The same applies to duplicate tags.
@@ -45,7 +45,7 @@ Headings
.. figure:: images/fig_header_levels.png
An illustration of how header levels correspond to the novel structure.
An illustration of how heading levels correspond to the novel structure.
Four levels of headings are allowed. For :term:`project notes`, they are free to be used as you see
fit. That is, novelWriter doesn't assign the different headings any particular meaning. However,
@@ -53,28 +53,28 @@ for :term:`novel documents` they indicate the structural level of the novel and
correctly to produce the intended result. See :ref:`a_struct_heads` for more details.
``# Title Text``
Heading level one. For novel documents, the header level indicates the start of a new partition.
Heading level one. For novel documents, the level indicates the start of a new partition.
``## Title Text``
Heading level two. For novel documents, the header level indicates the start of a new chapter.
Chapter numbers can be inserted automatically when building the manuscript.
Heading level two. For novel documents, the level indicates the start of a new chapter. Chapter
numbers can be inserted automatically when building the manuscript.
``### Title Text``
Heading level three. For novel documents, the header level indicates the start of a new scene.
Scene numbers or scene separators can be inserted automatically when building the manuscript,
so you can use the title field as a working title for your scenes if you wish.
Heading level three. For novel documents, the level indicates the start of a new scene. Scene
numbers or scene separators can be inserted automatically when building the manuscript, so you
can use the title field as a working title for your scenes if you wish.
``#### Title Text``
Heading level four. For novel documents, the header level indicates the start of a new section.
Section titles can be replaced by separators or ignored completely when building the manuscript.
Heading level four. For novel documents, the level indicates the start of a new section. Section
titles can be replaced by separators or ignored completely when building the manuscript.
For headers level one and two, adding a ``!`` modifies the behaviour of the heading:
For headings level one and two, adding a ``!`` modifies its meaning:
``#! Title Text``
This tells the build tool that the level one heading is intended to be used for the novel's
main title, like for instance on the front page. When building the manuscript, this will use a
different styling and will exclude the title from, for instance, a Table of Contents in Libre
Office.
This tells the build tool that the level one heading is intended to be used for the novel's or
notes folder's main title, like for instance on the front page. When building the manuscript,
this will use a different styling and will exclude the title from, for instance, a Table of
Contents in Libre Office.
``##! Title Text``
This tells the build tool to not assign a chapter number to this chapter title if automatic
@@ -99,10 +99,10 @@ In addition, the editor supports a few additional types of white spaces:
* A non-breaking space can be inserted with :kbd:`Ctrl+K`, :kbd:`Space`.
* Thin spaces are also supported, and can be inserted with :kbd:`Ctrl+K`, :kbd:`Shift+Space`.
* Non-breaking thin space can be inserted with :kbd:`Ctrl+K`, :kbd:`Ctrl+Space`.
* Non-breaking thin space can be inserted with :kbd:`Ctrl+K`, :kbd:`Ctrl+Space`.
These are all insert features, and the :guilabel:`Insert` menu has more. They are also listed
in :ref:`a_kb_ins`.
These are all insert features, and the :guilabel:`Insert` menu has more. The keyboard shortcuts for
them are also listed in :ref:`a_kb_ins`.
Non-breaking spaces are highlighted by the syntax highlighter with an alternate coloured
background, depending on the selected theme.
@@ -118,7 +118,7 @@ background, depending on the selected theme.
Text Emphasis
=============
A minimal set of text emphasis styles are supported for text paragraphs.
A minimal set of Markdown text emphasis styles are supported for text paragraphs.
``_text_``
The text is rendered as emphasised text (italicised).
@@ -141,7 +141,7 @@ In addition, the following rules apply:
tag itself. That is, ``**text**`` is valid, ``**text **`` is not.
2. More generally, the delimiters must be on the outer edge of words. That is, ``some **text in
bold** here`` is valid, ``some** text in bold** here`` is not.
3. If using both ``**`` and ``_`` to wrap the same text, the underscore must be the *inner*
3. If using both ``**`` and ``_`` to wrap the same text, the underscore must be the **inner**
wrapper. This is due to the underscore also being a valid word character, so if they are on the
outside, they violate rule 2.
4. Text emphasis does not span past line breaks. If you need to add emphasis to multiple lines or
@@ -214,9 +214,10 @@ indicate this by altering the colour of the word.
document of the whole project.
``%Short: text ...``
This is a short description comment. It is identical to the synopsis comment, but is intended to
be used for project notes. The text shows up in the Reference panel below the document viewer in
the last column labelled :guilabel:`Short Description`.
This is a short description comment. It is identical to the synopsis comment (they are
interchangeable), but is intended to be used for project notes. The text shows up in the
Reference panel below the document viewer in the last column labelled
:guilabel:`Short Description`.
.. note::
Only one comment can be flagged as a synopsis or short comment for each heading. If multiple
@@ -232,11 +233,11 @@ Tags and References
The document editor supports a set of keywords used for setting tags, and making references between
documents.
Tags use the command ``@tag:`` to define a tag. The tag can be set once per section defined by a
Tags use the keyword ``@tag:`` to define a tag. The tag can be set once per section defined by a
heading. Setting it multiple times under the same heading will just override the previous setting.
``@tag: value``
A tag command followed by the tag value, like for instance the name of a character.
A tag keyword followed by the tag value, like for instance the name of a character.
References can be set anywhere within a section, and are collected according to their category.
References are in the form:
@@ -282,7 +283,7 @@ Examples:
.. note::
The text editor will not show the alignment and indentation live. But the viewer will show them
when you open the document there. It will of course also be reflected in the document generated
from the build tool as long as the format supports paragraph alignment.
from the manuscript build tool as long as the format supports paragraph alignment.
.. _a_fmt_break:
@@ -290,37 +291,37 @@ Examples:
Vertical Space and Page Breaks
==============================
Adding more than one line break between paragraphs will *not* increase the space between those
Adding more than one line break between paragraphs will **not** increase the space between those
paragraphs when building the project. To add additional space between paragraphs, add the text
``[VSPACE]`` on a line of its own, and the build tool will insert a blank paragraph in its place.
``[vspace]`` on a line of its own, and the build tool will insert a blank paragraph in its place.
If you need multiple blank paragraphs just add a colon and a number to the above code. For
instance, writing ``[VSPACE:3]`` will insert three blank paragraphs.
instance, writing ``[vspace:3]`` will insert three blank paragraphs.
Normally, the build tool will insert a page break before all headers of level one and for all
headers of level two for novel documents, i.e. chapters, but not for project notes.
Normally, the manuscript build tool will insert a page break before all headings of level one and
for all headings of level two for novel documents, i.e. chapters, but not for project notes.
If you need to add a page break somewhere else, put the text ``[NEW PAGE]`` on a line by itself
If you need to add a page break somewhere else, put the text ``[new page]`` on a line by itself
before the text you wish to start on a new page.
If you want page breaks for scenes and sections, you must add them manually.
.. note::
The page break code is applied to the text that follows it. It adds a "page break before" mark
to the text when exporting to HTML or Open Document. This means that a ``[NEW PAGE]`` which has
to the text when exporting to HTML or Open Document. This means that a ``[new page]`` which has
no text following it, it will not result in a page break.
**Example:**
.. code-block:: markdown
.. code-block:: md
This is a text paragraph.
[VSPACE:2]
[vspace:2]
This is another text paragraph, but there will be two empty paragraphs
in-between them.
[NEWPAGE]
[new page]
This text will always start on a new page if the build format has pages.

View File

@@ -86,7 +86,7 @@ Splitting Documents
The :guilabel:`Split Document` dialog.
The :guilabel:`Split Document by Header` option will open a dialog that allows you to split the
The :guilabel:`Split Document by Heading` option will open a dialog that allows you to split the
selected document into multiple new documents based on the headings it contains. You can select at
which heading level the split is to be performed from the dropdown box. The list box will preview
which headings will be split into new documents.
@@ -94,7 +94,7 @@ which headings will be split into new documents.
You are given the option to create a folder for these new documents, and whether or not to create a
hierarchy of documents. That is, put sections under scenes, and scenes under chapters.
The source document *is not* deleted in the process, but you have the option to let the tool move
The source document **is not** deleted in the process, but you have the option to let the tool move
the source document to the :guilabel:`Trash` folder.
@@ -123,16 +123,16 @@ Document Importance and Status
------------------------------
Each document or folder in your project can have either a "Status" or "Importance" flag set. These
are flags that you control and define yourself. novelWriter doesn't do anything with them at all.
To modify the labels, go to their respective tabs in :guilabel:`Project Settings`.
are flags that you control and define yourself, and novelWriter doesn't use them for anything. To
modify the labels, go to their respective tabs in :guilabel:`Project Settings`.
The "Status" flag is intended to tag a :term:`novel document<novel documents>` as for instance a
draft or as completed, and the "Importance" flag is intended to tag character notes, or other
:term:`project notes`, as for instance a main, major, or minor character or story element.
Whether a document uses a "Status" or "Importance" flag depends on which :term:`root folder` it
lives in. If it's in a :guilabel:`Novel` folder, it uses the "Status" flag, otherwise it uses an
"Importance" flag. Some folders, like :guilabel:`Trash` and :guilabel:`Archive` allow both.
lives in. If it's in a Novel type folder, it uses the "Status" flag, otherwise it uses an
"Importance" flag.
.. _a_ui_tree_dnd:
@@ -155,32 +155,31 @@ interface framework novelWriter is built upon.
Documents and their folders can be rearranged freely within their root folders. If you move a Novel
document out of a Novel folder, it will be converted to a project note. Notes can be moved freely
between all root folders, but keep in mind that if you move a note into a :guilabel:`Novel` root
folder, its "Importance" setting will be switched with a "Status" setting. See
:ref:`a_ui_tree_status`. The old value will not be overwritten though, and should be restored if
you move it back at some point.
between all root folders, but keep in mind that if you move a note into a Novel type root folder,
its "Importance" setting will be switched with a "Status" setting. See :ref:`a_ui_tree_status`. The
old value will not be overwritten though, and should be restored if you move it back at some point.
Root folders in the project tree cannot be dragged and dropped at all. If you want to reorder them,
you can move them up or down with respect to each other from the arrow buttons at the top of the
project tree, or by pressing :kbd:`Ctrl+Shift+Up` or :kbd:`Ctrl+Shift+Down` when they are selected.
project tree, or by pressing :kbd:`Ctrl+Up` or :kbd:`Ctrl+Down` when they are selected.
.. _a_ui_tree_novel:
The Novel Tree
==============
The Novel Tree View
===================
.. figure:: images/fig_novel_tree_view.png
A screenshot of the Novel Tree View.
An alternative way to view the project structure is the novel tree. You can switch to this view by
selecting the :guilabel:`Novel Tree View` button in the sidebar. This view is a simplified version
of the view in the :guilabel:`Outline View`. It is convenient when you want to browse the structure
An alternative way to view the project structure is the novel view. You can switch to this view by
selecting the :guilabel:`Novel View` button in the sidebar. This view is a simplified version of
the view in the :guilabel:`Outline View`. It is convenient when you want to browse the structure
of the story itself rather than the document files.
.. note::
You cannot reorganise the entries in the novel tree, or add any new documents, as that would
You cannot reorganise the entries in the novel view, or add any new documents, as that would
imply restructuring the content of the document files themselves. Any such editing must be done
in the project tree. However, you can add new headings to existing documents, or change
references, which will be updated in this view when the document is saved.
@@ -188,17 +187,17 @@ of the story itself rather than the document files.
.. _a_ui_outline:
Project Outline View
====================
The Novel Outline View
======================
.. figure:: images/fig_outline_view.png
A screenshot of the Novel Outline View.
The project's :guilabel:`Outline View` is available as another view option from the sidebar. The
outline provides an overview of the novel structure, displaying a tree hierarchy of the elements of
the novel, that is, the level 1 to 4 headings representing partitions, chapters, scenes and
sections.
The project's :guilabel:`Novel Outline View` is available as another view option from the sidebar.
The outline provides an overview of the novel structure, displaying a tree hierarchy of the
elements of the novel, that is, the level 1 to 4 headings representing partitions, chapters, scenes
and sections.
The document containing the heading can also be displayed as a separate column, as well as the line
number where the heading is defined. Double-clicking an entry will open the corresponding document

View File

@@ -23,14 +23,14 @@ Main Window Shortcuts
":kbd:`F5`", "Open the :guilabel:`Build Manuscript` tool"
":kbd:`F6`", "Open the :guilabel:`Writing Statistics` tool"
":kbd:`F8`", "Toggle :guilabel:`Focus Mode`"
":kbd:`F9`", "Re-build the project index"
":kbd:`F9`", "Re-build the project's index"
":kbd:`F11`", "Toggle full screen mode"
":kbd:`Ctrl+,`", "Open the :guilabel:`Preferences` dialog"
":kbd:`Ctrl+E`", "Switch focus to the document editor"
":kbd:`Ctrl+T`", "Switch focus to the project/novel tree"
":kbd:`Ctrl+T`", "Switch or toggle focus for the project tree or novel view"
":kbd:`Ctrl+Q`", "Exit novelWriter"
":kbd:`Ctrl+Shift+,`", "Open the :guilabel:`Project Settings` dialog"
":kbd:`Ctrl+Shift+O`", "Open a project"
":kbd:`Ctrl+Shift+O`", "Open the Welcome dialog to open or create a project"
":kbd:`Ctrl+Shift+S`", "Save the current project"
":kbd:`Ctrl+Shift+T`", "Switch focus to the outline view"
":kbd:`Ctrl+Shift+W`", "Close the current project"
@@ -55,12 +55,11 @@ Project Tree Shortcuts
":kbd:`Ctrl+.`", "Open the context menu on the selected item"
":kbd:`Ctrl+L`", "Open the :guilabel:`Quick Links` menu"
":kbd:`Ctrl+N`", "Open the :guilabel:`Create New Item` menu"
":kbd:`Ctrl+O`", "Open selected document"
":kbd:`Ctrl+O`", "Open the selected document in the editor"
":kbd:`Ctrl+R`", "Open the selected document in the viewer"
":kbd:`Ctrl+Up`", "Move selected item one step up in the tree"
":kbd:`Ctrl+Down`", "Move selected item one step down in the tree"
":kbd:`Ctrl+Shift+Del`", "Move the selected item to Trash"
":kbd:`Ctrl+Shift+Z`", "Undo the last move of a project item, if possible"
.. _a_kb_editor:
@@ -92,21 +91,22 @@ Text Formatting Shortcuts
":kbd:`Ctrl+'`", "Wrap selected text, or word under cursor, in single quotes"
":kbd:`Ctrl+""`", "Wrap selected text, or word under cursor, in double quotes"
":kbd:`Ctrl+/`", "Toggle block format as comment"
":kbd:`Ctrl+0`", "Remove block formatting for block under cursor"
":kbd:`Ctrl+1`", "Change block format to header level 1"
":kbd:`Ctrl+2`", "Change block format to header level 2"
":kbd:`Ctrl+3`", "Change block format to header level 3"
":kbd:`Ctrl+4`", "Change block format to header level 4"
":kbd:`Ctrl+/`", "Toggle block format as comment for block under cursor, or selected text"
":kbd:`Ctrl+0`", "Remove block formatting for block under cursor, or selected text"
":kbd:`Ctrl+1`", "Change block format to heading level 1"
":kbd:`Ctrl+2`", "Change block format to heading level 2"
":kbd:`Ctrl+3`", "Change block format to heading level 3"
":kbd:`Ctrl+4`", "Change block format to heading level 4"
":kbd:`Ctrl+5`", "Change block alignment to left-aligned"
":kbd:`Ctrl+6`", "Change block alignment to centred"
":kbd:`Ctrl+7`", "Change block alignment to right-aligned"
":kbd:`Ctrl+8`", "Add a left margin to the block"
":kbd:`Ctrl+9`", "Add a right margin to the block"
":kbd:`Ctrl+B`", "Format selected text, or word under cursor, with strong emphasis (bold)"
":kbd:`Ctrl+D`", "Strike through selected text, or word under cursor"
":kbd:`Ctrl+D`", "Format selected text, or word under cursor, with strike through"
":kbd:`Ctrl+I`", "Format selected text, or word under cursor, with emphasis (italic)"
":kbd:`Ctrl+Shift+/`", "Remove block formatting for block under cursor"
":kbd:`Ctrl+Shift+/`", "Remove block formatting for block under cursor, or selected text"
":kbd:`Ctrl+Shift+D`", "Toggle block format as ignored text for block under cursor, or selected text"
Other Editor Shortcuts
@@ -115,7 +115,7 @@ Other Editor Shortcuts
.. csv-table::
:header: "Shortcut", "Description"
":kbd:`F7`", "Re-run the spell checker"
":kbd:`F7`", "Re-run the spell checker on the document"
":kbd:`Ctrl+.`", "Open the context menu at the current cursor location"
":kbd:`Ctrl+A`", "Select all text in the document"
":kbd:`Ctrl+C`", "Copy selected text to clipboard"
@@ -132,7 +132,6 @@ Other Editor Shortcuts
":kbd:`Ctrl+F7`", "Toggle spell checking"
":kbd:`Ctrl+Return`", "Open the tag or reference under the cursor in the viewer"
":kbd:`Ctrl+Shift+A`", "Select all text in the current paragraph"
":kbd:`Ctrl+Shift+I`", "Import text to the current document from a text file"
.. _a_kb_ins:

View File

@@ -42,13 +42,12 @@ the label and pressing :kbd:`Ctrl+Return`. You can also control-click them with
Editor Auto-Completer
---------------------
If you type the character ``@`` on a new line, a context menu will appear showing the different
available keywords. The list will shorten as you type. Once a keyword command has been selected or
typed, the editor may suggest further content based on your project content. See
:ref:`a_references_completer` for more details.
If you type the character ``@`` on a new line, a menu will appear showing the different available
keywords. The list will shorten as you type. Once a keyword command has been selected or typed, the
editor may suggest further content based on your project content. See :ref:`a_references_completer`
for more details.
.. versionadded:: 2.2
The auto-completer feature was added.
.. _a_ui_view:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ File History:
Created: 2018-09-22 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -37,14 +37,14 @@ from novelwriter.shared import SharedData
# ============
__package__ = "novelwriter"
__copyright__ = "Copyright 2018–2023, Veronica Berglyd Olsen"
__copyright__ = "Copyright 2018–2024, Veronica Berglyd Olsen"
__license__ = "GPLv3"
__author__ = "Veronica Berglyd Olsen"
__maintainer__ = "Veronica Berglyd Olsen"
__email__ = "code@vkbo.net"
__version__ = "2.2"
__hexversion__ = "0x020200f0"
__date__ = "2023-12-17"
__version__ = "2.3.1"
__hexversion__ = "0x020301f0"
__date__ = "2024-03-17"
__status__ = "Stable"
__domain__ = "novelwriter.io"
@@ -131,7 +131,7 @@ def main(sysArgs: list | None = None):
elif inOpt == "--debug":
CONFIG.isDebug = True
logLevel = logging.DEBUG
logFormat = "[{asctime:}] {filename:>17}:{lineno:<4d} {levelname:8} {message:}"
logFormat = "[{asctime:}] {filename:>18}:{lineno:<4d} {levelname:8} {message:}"
elif inOpt == "--style":
qtStyle = inArg
elif inOpt == "--config":

View File

@@ -1,5 +1,6 @@
{
"Synopsis": "Synopsis",
"Short Description": "Kurzbeschreibung",
"Comment": "Kommentar",
"Notes": "Notizen",
"Tag": "Schlagwort",

View File

@@ -1,7 +1,18 @@
{
"Synopsis": "Synopsis",
"Short Description": "Korte beschrijving",
"Comment": "Opmerking",
"Notes": "Notities",
"Tag": "Label",
"Point of View": "Perspectief",
"Focus": "Focus",
"Characters": "Personages",
"Plot": "Plot",
"Timeline": "Tijdslijn",
"Locations": "Locaties",
"Objects": "Objecten",
"Entities": "Entiteiten",
"Custom": "Aangepast",
"0": "nul",
"1": "één",
"2": "twee",

View File

@@ -1,7 +1,18 @@
{
"Synopsis": "Sinopse",
"Short Description": "Descrição breve",
"Comment": "Comentários",
"Notes": "Notas",
"Tag": "Etiqueta",
"Point of View": "Ponto de vista",
"Focus": "Foco",
"Characters": "Personagens",
"Plot": "Trama",
"Timeline": "Linha do tempo",
"Locations": "Lugares",
"Objects": "Objetos",
"Entities": "Entidades",
"Custom": "Outros",
"0": "Zero",
"1": "Um",
"2": "Dois",

View File

@@ -1,7 +1,18 @@
{
"Synopsis": "概要",
"Short Description": "简短描述",
"Comment": "注释",
"Notes": "笔记",
"Tag": "标签",
"Point of View": "视角",
"Focus": "聚焦",
"Characters": "角色",
"Plot": "情节",
"Timeline": "时间线",
"Locations": "地点",
"Objects": "物品",
"Entities": "条目",
"Custom": "自定义",
"0": "零",
"1": "一",
"2": "二",

View File

@@ -17,6 +17,7 @@ licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
[Map]
add = typ_plus.svg
add_document = typ_document-add.svg
alert_error = typ_delete-full.svg
alert_info = typ_lightbulb-full.svg
alert_question = typ_directions-full.svg
@@ -39,10 +40,12 @@ cls_none = typ_cancel.svg
cls_novel = typ_book.svg
cls_object = typ_key.svg
cls_plot = typ_puzzle.svg
cls_template = mixed_document-new.svg
cls_timeline = typ_calendar.svg
cls_trash = typ_trash.svg
cls_world = typ_location.svg
cross = typ_times.svg
document = typ_document.svg
down = typ_chevron-down.svg
edit = typ_pencil.svg
export = typ_export.svg
@@ -56,10 +59,14 @@ fmt_subscript = nw_tb-subscript.svg
fmt_superscript = nw_tb-superscript.svg
fmt_underline = nw_tb-underline.svg
forward = typ_chevron-right.svg
import = mixed_import.svg
list = typ_th-list.svg
maximise = typ_arrow-maximise.svg
menu = typ_th-dot-menu.svg
minimise = typ_arrow-minimise.svg
more = typ_th-dot-more.svg
noncheckable = mixed_input-none.svg
open = typ_folder.svg
panel = nw_panel.svg
proj_chapter = mixed_document-chapter.svg
proj_details = typ_th-list-grey.svg
@@ -83,6 +90,7 @@ search_regex = nw_search-regex.svg
search_replace = mixed_search-replace.svg
search_word = nw_search-word.svg
settings = typ_cog.svg
star = typ_star.svg
status_idle = typ_media-pause-grey.svg
status_lang = typ_globe-grey.svg
status_lines = typ_th-list-grey.svg

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m5.8898 3.4449c-0.67467 1e-7 -1.2225 0.5478-1.2225 1.2225v14.665c0 0.67466 0.5478 1.2225 1.2225 1.2225h12.22c0.67466 0 1.2225-0.5478 1.2225-1.2225v-11h-1.8326c-1.6854 0-3.0551-1.3696-3.0551-3.0551v-1.8326zm9.7775 0.50488v1.3277c0 1.0108 0.82184 1.8326 1.8326 1.8326h1.3277z" fill="#e5e5e5" fill-opacity=".5" stroke-linecap="round" stroke-width=".55"/>
<path d="m5.8898 1c-2.0216 0-3.6674 1.6458-3.6674 3.6674v14.665c0 2.0216 1.6458 3.6674 3.6674 3.6674h12.22c2.0216 0 3.6674-1.6458 3.6674-3.6674v-12.222c0-0.32511-0.12901-0.63512-0.35879-0.86367l-4.8877-4.8877c-0.22856-0.22978-0.53856-0.35879-0.86367-0.35879zm0 2.4449h8.5551v1.8326c0 1.6854 1.3696 3.0551 3.0551 3.0551h1.8326v11c0 0.67466-0.5478 1.2225-1.2225 1.2225h-12.22c-0.67467 0-1.2225-0.5478-1.2225-1.2225v-14.665c0-0.67467 0.5478-1.2225 1.2225-1.2225zm9.7775 0.50488 3.1604 3.1604h-1.3277c-1.0108 0-1.8326-0.82184-1.8326-1.8326z" fill="#aeaeae" stroke-width="1.2222"/>
<path d="m10.105 9.9584-3.785 0.4196c-0.13651 0.01653-0.25722 0.10777-0.30249 0.24644-0.045266 0.13867 0 0.28308 0.10059 0.37434 1.1252 1.0267 2.8158 2.5643 2.8158 2.5643-0.00143 0-0.46415 2.2367-0.77166 3.729-0.025865 0.13508 0.022992 0.27806 0.14083 0.36356 0.11711 0.0855 0.268 0.08694 0.38655 0.02012 1.3249-0.753 3.3094-1.8853 3.3094-1.8853l3.308 1.886c0.12071 0.0661 0.27159 0.06467 0.38871-0.02084 0.11783-0.0855 0.16669-0.22848 0.1401-0.36284l-0.7695-3.7297 2.8158-2.5622c0.10059-0.09412 0.14514-0.23854 0.10059-0.37649-0.04454-0.13794-0.16525-0.22919-0.30177-0.245-1.5146-0.16956-3.7857-0.42104-3.7857-0.42104l-1.5685-3.4703c-0.05892-0.1243-0.1825-0.21124-0.32764-0.21124-0.14514 0-0.26944 0.087654-0.32548 0.21124z" fill="#ffff84" stroke-width=".7185"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m3.1113 3.666c-0.61332 0-1.1094 0.49689-1.1094 1.1113v15.557h-0.0019531c0 0.61443 0.498 1.1094 1.1113 1.1094h15.557c0.61332 0 1.1113-0.49494 1.1113-1.1094v-8.2578c-0.61899 0.57364-1.3634 1.0131-2.252 1.2578-0.004058 2.0524-0.007162 4.0735 0.005859 5.8887h-13.311v-13.318c1.6116-0.00848 2.8992 0 4.4648 0 0.75712-0.75269 1.5907-1.5005 2.3418-2.2383h-7.918z" fill="#9c9"/>
<path d="m21.996 3.1106v-0.55556c-1.8789 2.8644-4 4.3922-6.6667 4.4444v-3.3333c0-0.61222-0.56778-1.1111-1.27-1.1111-0.40444 0-0.75 0.17556-0.98111 0.43444-2.1478 2.2544-6.6378 6.7878-6.6378 6.7878s4.49 4.5356 6.6389 6.8189c0.23111 0.22778 0.57556 0.40333 0.98 0.40333 0.70222 0 1.27-0.49667 1.27-1.1111v-3.3333c5.1778 0 6.6667-5.4122 6.6667-9.4444z" fill="#9c9" stroke-width="1.1111"/>
</svg>

After

Width:  |  Height:  |  Size: 912 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m15.667 12h-2.4444v-2.4444c0-0.67589-0.54633-1.2222-1.2222-1.2222s-1.2222 0.54633-1.2222 1.2222v2.4444h-2.4444c-0.67589 0-1.2222 0.54633-1.2222 1.2222s0.54633 1.2222 1.2222 1.2222h2.4444v2.4444c0 0.67589 0.54633 1.2222 1.2222 1.2222s1.2222-0.54633 1.2222-1.2222v-2.4444h2.4444c0.67589 0 1.2222-0.54633 1.2222-1.2222s-0.54633-1.2222-1.2222-1.2222zm5.753-5.753-4.8889-4.8889c-0.22856-0.22978-0.539-0.35811-0.86411-0.35811h-9.7778c-2.0216 0-3.6667 1.6451-3.6667 3.6667v14.667c0 2.0216 1.6451 3.6667 3.6667 3.6667h12.222c2.0216 0 3.6667-1.6451 3.6667-3.6667v-12.222c0-0.32511-0.12833-0.63556-0.35811-0.86411zm-2.5923 0.86411h-1.3273c-1.0108 0-1.8333-0.82256-1.8333-1.8333v-1.3273zm-0.71622 13.444h-12.222c-0.67467 0-1.2222-0.54756-1.2222-1.2222v-14.667c0-0.67467 0.54756-1.2222 1.2222-1.2222h8.5556v1.8333c0 1.6854 1.3701 3.0556 3.0556 3.0556h1.8333v11c0 0.67467-0.54756 1.2222-1.2222 1.2222z" fill="#aeaeae" stroke-width="1.2222"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m21.42 6.247-4.8889-4.8889c-0.22856-0.22978-0.539-0.35811-0.86411-0.35811h-9.7778c-2.0216 0-3.6667 1.6451-3.6667 3.6667v14.667c0 2.0216 1.6451 3.6667 3.6667 3.6667h12.222c2.0216 0 3.6667-1.6451 3.6667-3.6667v-12.222c0-0.32511-0.12833-0.63556-0.35811-0.86411zm-2.5923 0.86411h-1.3273c-1.0108 0-1.8333-0.82256-1.8333-1.8333v-1.3273zm-0.71622 13.444h-12.222c-0.67467 0-1.2222-0.54756-1.2222-1.2222v-14.667c0-0.67467 0.54756-1.2222 1.2222-1.2222h8.5556v1.8333c0 1.6854 1.3701 3.0556 3.0556 3.0556h1.8333v11c0 0.67467-0.54756 1.2222-1.2222 1.2222z" fill="#aeaeae" stroke-width="1.2222"/>
</svg>

After

Width:  |  Height:  |  Size: 737 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M 22,12 A 2.6315,2.6315 0 0 0 19.3686,9.3686 2.6315,2.6315 0 0 0 16.7372,12 2.6315,2.6315 0 0 0 19.3686,14.6314 2.6315,2.6315 0 0 0 22,12 Z m -7.3686,0 A 2.6315,2.6315 0 0 0 12,9.3686 2.6315,2.6315 0 0 0 9.3686,12 2.6315,2.6315 0 0 0 12,14.6314 2.6315,2.6315 0 0 0 14.6314,12 Z M 7.2628,12 A 2.6315,2.6315 0 0 0 4.6314,9.3686 2.6315,2.6315 0 0 0 2,12 2.6315,2.6315 0 0 0 4.6314,14.6314 2.6315,2.6315 0 0 0 7.2628,12 Z" fill="#aeaeae" stroke-width=".90909"/>
</svg>

After

Width:  |  Height:  |  Size: 612 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="#69c" stroke-width="1.0526">
<path d="m19.632 17.263h-7.3684c-1.1611 0-2.1053 0.94421-2.1053 2.1053s0.94421 2.1053 2.1053 2.1053h7.3684c1.1611 0 2.1053-0.94421 2.1053-2.1053s-0.94421-2.1053-2.1053-2.1053zm0-7.3684h-7.3684c-1.1611 0-2.1053 0.94421-2.1053 2.1053s0.94421 2.1053 2.1053 2.1053h7.3684c1.1611 0 2.1053-0.94421 2.1053-2.1053s-0.94421-2.1053-2.1053-2.1053zm0-7.3684h-7.3684c-1.1611 0-2.1053 0.94421-2.1053 2.1053 0 1.1611 0.94421 2.1053 2.1053 2.1053h7.3684c1.1611 0 2.1053-0.94421 2.1053-2.1053 0-1.1611-0.94421-2.1053-2.1053-2.1053z"/>
<circle cx="4.8947" cy="19.368" r="2.6316"/>
<circle cx="4.8947" cy="12" r="2.6316"/>
<circle cx="4.8947" cy="4.6316" r="2.6316"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 846 B

View File

@@ -17,6 +17,7 @@ licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
[Map]
add = typ_plus.svg
add_document = typ_document-add.svg
alert_error = typ_delete-full.svg
alert_info = typ_lightbulb-full.svg
alert_question = typ_directions-full.svg
@@ -39,10 +40,12 @@ cls_none = typ_cancel.svg
cls_novel = typ_book.svg
cls_object = typ_key.svg
cls_plot = typ_puzzle.svg
cls_template = mixed_document-new.svg
cls_timeline = typ_calendar.svg
cls_trash = typ_trash.svg
cls_world = typ_location.svg
cross = typ_times.svg
document = typ_document.svg
down = typ_chevron-down.svg
edit = typ_pencil.svg
export = typ_export.svg
@@ -56,10 +59,14 @@ fmt_subscript = nw_tb-subscript.svg
fmt_superscript = nw_tb-superscript.svg
fmt_underline = nw_tb-underline.svg
forward = typ_chevron-right.svg
import = mixed_import.svg
list = typ_th-list.svg
maximise = typ_arrow-maximise.svg
menu = typ_th-dot-menu.svg
minimise = typ_arrow-minimise.svg
more = typ_th-dot-more.svg
noncheckable = mixed_input-none.svg
open = typ_folder.svg
panel = nw_panel.svg
proj_chapter = mixed_document-chapter.svg
proj_details = typ_th-list-grey.svg
@@ -83,6 +90,7 @@ search_regex = nw_search-regex.svg
search_replace = mixed_search-replace.svg
search_word = nw_search-word.svg
settings = typ_cog.svg
star = typ_star.svg
status_idle = typ_media-pause-grey.svg
status_lang = typ_globe-grey.svg
status_lines = typ_th-list-grey.svg

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m5.8898 3.4449c-0.67467 1e-7 -1.2225 0.5478-1.2225 1.2225v14.665c0 0.67466 0.5478 1.2225 1.2225 1.2225h12.22c0.67466 0 1.2225-0.5478 1.2225-1.2225v-11h-1.8326c-1.6854 0-3.0551-1.3696-3.0551-3.0551v-1.8326zm9.7775 0.50488v1.3277c0 1.0108 0.82184 1.8326 1.8326 1.8326h1.3277z" fill="#e5e5e5" stroke-linecap="round" stroke-width=".55"/>
<path d="m5.8898 1c-2.0216 0-3.6674 1.6458-3.6674 3.6674v14.665c0 2.0216 1.6458 3.6674 3.6674 3.6674h12.22c2.0216 0 3.6674-1.6458 3.6674-3.6674v-12.222c0-0.32511-0.12901-0.63512-0.35879-0.86367l-4.8877-4.8877c-0.22856-0.22978-0.53856-0.35879-0.86367-0.35879zm0 2.4449h8.5551v1.8326c0 1.6854 1.3696 3.0551 3.0551 3.0551h1.8326v11c0 0.67466-0.5478 1.2225-1.2225 1.2225h-12.22c-0.67467 0-1.2225-0.5478-1.2225-1.2225v-14.665c0-0.67467 0.5478-1.2225 1.2225-1.2225zm9.7775 0.50488 3.1604 3.1604h-1.3277c-1.0108 0-1.8326-0.82184-1.8326-1.8326z" fill="#333" stroke-width="1.2222"/>
<path d="m10.105 9.9584-3.785 0.4196c-0.13651 0.01653-0.25722 0.10777-0.30249 0.24644-0.04526 0.13867 0 0.28308 0.10059 0.37434 1.1252 1.0267 2.8158 2.5643 2.8158 2.5643-0.0014 0-0.46415 2.2367-0.77166 3.729-0.02587 0.13508 0.02299 0.27806 0.14082 0.36356 0.11711 0.0855 0.268 0.08694 0.38655 0.02012 1.3249-0.753 3.3094-1.8853 3.3094-1.8853l3.308 1.886c0.12071 0.0661 0.27159 0.06467 0.38871-0.02084 0.11783-0.0855 0.16669-0.22848 0.1401-0.36284l-0.7695-3.7297 2.8158-2.5622c0.10059-0.09412 0.14514-0.23854 0.10059-0.37649-0.04454-0.13795-0.16525-0.2292-0.30177-0.24501-1.5146-0.16956-3.7857-0.42103-3.7857-0.42103l-1.5685-3.4703c-0.05892-0.1243-0.1825-0.21124-0.32764-0.21124-0.14514 0-0.26944 0.087654-0.32548 0.21124z" fill="#eab700" stroke-width=".7185"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m3.1113 3.666c-0.61332 0-1.1094 0.49689-1.1094 1.1113v15.557h-0.0019531c0 0.61443 0.498 1.1094 1.1113 1.1094h15.557c0.61332 0 1.1113-0.49494 1.1113-1.1094v-8.2578c-0.61899 0.57364-1.3634 1.0131-2.252 1.2578-0.004058 2.0524-0.007162 4.0735 0.005859 5.8887h-13.311v-13.318c1.6116-0.00848 2.8992 0 4.4648 0 0.75712-0.75269 1.5907-1.5005 2.3418-2.2383h-7.918z" fill="#718c00"/>
<path d="m21.996 3.1106v-0.55556c-1.8789 2.8644-4 4.3922-6.6667 4.4444v-3.3333c0-0.61222-0.56778-1.1111-1.27-1.1111-0.40444 0-0.75 0.17556-0.98111 0.43444-2.1478 2.2544-6.6378 6.7878-6.6378 6.7878s4.49 4.5356 6.6389 6.8189c0.23111 0.22778 0.57556 0.40333 0.98 0.40333 0.70222 0 1.27-0.49667 1.27-1.1111v-3.3333c5.1778 0 6.6667-5.4122 6.6667-9.4444z" fill="#718c00" stroke-width="1.1111"/>
</svg>

After

Width:  |  Height:  |  Size: 918 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m15.667 12h-2.4444v-2.4444c0-0.67589-0.54633-1.2222-1.2222-1.2222s-1.2222 0.54633-1.2222 1.2222v2.4444h-2.4444c-0.67589 0-1.2222 0.54633-1.2222 1.2222s0.54633 1.2222 1.2222 1.2222h2.4444v2.4444c0 0.67589 0.54633 1.2222 1.2222 1.2222s1.2222-0.54633 1.2222-1.2222v-2.4444h2.4444c0.67589 0 1.2222-0.54633 1.2222-1.2222s-0.54633-1.2222-1.2222-1.2222zm5.753-5.753-4.8889-4.8889c-0.22856-0.22978-0.539-0.35811-0.86411-0.35811h-9.7778c-2.0216 0-3.6667 1.6451-3.6667 3.6667v14.667c0 2.0216 1.6451 3.6667 3.6667 3.6667h12.222c2.0216 0 3.6667-1.6451 3.6667-3.6667v-12.222c0-0.32511-0.12833-0.63556-0.35811-0.86411zm-2.5923 0.86411h-1.3273c-1.0108 0-1.8333-0.82256-1.8333-1.8333v-1.3273zm-0.71622 13.444h-12.222c-0.67467 0-1.2222-0.54756-1.2222-1.2222v-14.667c0-0.67467 0.54756-1.2222 1.2222-1.2222h8.5556v1.8333c0 1.6854 1.3701 3.0556 3.0556 3.0556h1.8333v11c0 0.67467-0.54756 1.2222-1.2222 1.2222z" fill-opacity=".78039" stroke-width="1.2222"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m21.42 6.247-4.8889-4.8889c-0.22856-0.22978-0.539-0.35811-0.86411-0.35811h-9.7778c-2.0216 0-3.6667 1.6451-3.6667 3.6667v14.667c0 2.0216 1.6451 3.6667 3.6667 3.6667h12.222c2.0216 0 3.6667-1.6451 3.6667-3.6667v-12.222c0-0.32511-0.12833-0.63556-0.35811-0.86411zm-2.5923 0.86411h-1.3273c-1.0108 0-1.8333-0.82256-1.8333-1.8333v-1.3273zm-0.71622 13.444h-12.222c-0.67467 0-1.2222-0.54756-1.2222-1.2222v-14.667c0-0.67467 0.54756-1.2222 1.2222-1.2222h8.5556v1.8333c0 1.6854 1.3701 3.0556 3.0556 3.0556h1.8333v11c0 0.67467-0.54756 1.2222-1.2222 1.2222z" fill-opacity=".78039" stroke-width="1.2222"/>
</svg>

After

Width:  |  Height:  |  Size: 744 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M 22,12 A 2.6315,2.6315 0 0 0 19.3686,9.3686 2.6315,2.6315 0 0 0 16.7372,12 2.6315,2.6315 0 0 0 19.3686,14.6314 2.6315,2.6315 0 0 0 22,12 Z m -7.3686,0 A 2.6315,2.6315 0 0 0 12,9.3686 2.6315,2.6315 0 0 0 9.3686,12 2.6315,2.6315 0 0 0 12,14.6314 2.6315,2.6315 0 0 0 14.6314,12 Z M 7.2628,12 A 2.6315,2.6315 0 0 0 4.6314,9.3686 2.6315,2.6315 0 0 0 2,12 2.6315,2.6315 0 0 0 4.6314,14.6314 2.6315,2.6315 0 0 0 7.2628,12 Z" fill-opacity=".78039" stroke-width=".90909"/>
</svg>

After

Width:  |  Height:  |  Size: 619 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="#4271ae" stroke-width="1.0526">
<path d="m19.632 17.263h-7.3684c-1.1611 0-2.1053 0.94421-2.1053 2.1053s0.94421 2.1053 2.1053 2.1053h7.3684c1.1611 0 2.1053-0.94421 2.1053-2.1053s-0.94421-2.1053-2.1053-2.1053zm0-7.3684h-7.3684c-1.1611 0-2.1053 0.94421-2.1053 2.1053s0.94421 2.1053 2.1053 2.1053h7.3684c1.1611 0 2.1053-0.94421 2.1053-2.1053s-0.94421-2.1053-2.1053-2.1053zm0-7.3684h-7.3684c-1.1611 0-2.1053 0.94421-2.1053 2.1053 0 1.1611 0.94421 2.1053 2.1053 2.1053h7.3684c1.1611 0 2.1053-0.94421 2.1053-2.1053 0-1.1611-0.94421-2.1053-2.1053-2.1053z"/>
<circle cx="4.8947" cy="19.368" r="2.6316"/>
<circle cx="4.8947" cy="12" r="2.6316"/>
<circle cx="4.8947" cy="4.6316" r="2.6316"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 849 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -0,0 +1,26 @@
[Main]
name = Cyberpunk Night
author = Anders Lemvigh
url = https://github.com/alemvigh
license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
[Syntax]
background = 0, 0, 0
text = 150, 150, 150
link = 77, 077, 255
headertext = 255, 255, 255
headertag = 50, 0, 180
emphasis = 0, 255, 255
straightquotes = 7, 27, 219
doublequotes = 0, 255, 0
singlequotes = 0, 140, 255
hidden = 77, 77, 100
shortcode = 255, 255, 0
keyword = 255, 100, 255
value = 255, 150, 10
spellcheckline = 242, 72, 23
errorline = 186, 218, 4
replacetag = 0, 0, 180
modifier = 144, 142, 176
optional = 180, 180, 180

View File

@@ -20,6 +20,7 @@ hidden = 150, 150, 150
shortcode = 0, 155, 200
keyword = 200, 46, 0
value = 184, 200, 0
optional = 0, 155, 200
spellcheckline = 200, 46, 0
errorline = 46, 200, 0
replacetag = 0, 184, 46

View File

@@ -20,6 +20,7 @@ hidden = 100, 100, 100
shortcode = 0, 100, 0
keyword = 200, 50, 50
value = 50, 150, 50
optional = 0, 100, 0
spellcheckline = 200, 0, 0
errorline = 0, 150, 0
replacetag = 0, 150, 0

View File

@@ -20,6 +20,7 @@ hidden = 150, 150, 150
shortcode = 225, 225, 225
keyword = 225, 225, 225
value = 200, 200, 200
optional = 225, 225, 225
spellcheckline = 200, 46, 0
errorline = 46, 200, 0
replacetag = 225, 225, 225

View File

@@ -20,6 +20,7 @@ hidden = 100, 100, 100
shortcode = 0, 0, 0
keyword = 0, 0, 0
value = 20, 20, 20
optional = 0, 0, 0
spellcheckline = 200, 0, 0
errorline = 0, 150, 0
replacetag = 0, 0, 0

View File

@@ -40,6 +40,7 @@ hidden = 152, 159, 177
shortcode = 40, 142, 215
keyword = 222, 61, 58
value = 150, 74, 193
optional = 40, 142, 215
spellcheckline = 222, 61, 58
errorline = 8, 145, 106
replacetag = 42, 162, 152

View File

@@ -40,6 +40,7 @@ hidden = 99, 119, 119
shortcode = 130, 170, 255
keyword = 247, 140, 108
value = 199, 146, 234
optional = 130, 170, 255
spellcheckline = 247, 140, 108
errorline = 173, 219, 103
replacetag = 127, 219, 202

View File

@@ -20,6 +20,7 @@ hidden = 147, 161, 161
shortcode = 147, 161, 161
keyword = 133, 153, 0
value = 203, 75, 22
optional = 147, 161, 161
spellcheckline = 203, 75, 22
errorline = 220, 50, 47
replacetag = 133, 153, 0

View File

@@ -20,6 +20,7 @@ hidden = 88, 110, 117
shortcode = 88, 110, 117
keyword = 133, 153, 0
value = 203, 75, 22
optional = 88, 110, 117
spellcheckline = 203, 75, 22
errorline = 220, 50, 47
replacetag = 133, 153, 0

View File

@@ -0,0 +1,23 @@
[Main]
name = Tango
author = Veronica Berglyd Olsen (adaptation)
[Syntax]
background = 48, 48, 47
text = 238, 238, 236
link = 115, 159, 207
headertext = 115, 159, 207
headertag = 52, 101, 164
emphasis = 196, 160, 0
straightquotes = 239, 41, 41
doublequotes = 138, 226, 52
singlequotes = 252, 233, 79
hidden = 143, 143, 141
shortcode = 115, 159, 207
keyword = 239, 41, 41
value = 173, 127, 168
optional = 115, 159, 207
spellcheckline = 239, 41, 41
errorline = 138, 226, 52
replacetag = 51, 226, 226
modifier = 196, 160, 0

View File

@@ -40,6 +40,7 @@ hidden = 142, 144, 140
shortcode = 66, 113, 174
keyword = 240, 40, 41
value = 137, 89, 168
optional = 66, 113, 174
spellcheckline = 240, 40, 41
errorline = 113, 140, 0
replacetag = 62, 153, 159

View File

@@ -40,6 +40,7 @@ hidden = 150, 152, 150
shortcode = 129, 162, 190
keyword = 204, 102, 102
value = 178, 148, 187
optional = 129, 162, 190
spellcheckline = 204, 102, 102
errorline = 181, 189, 104
replacetag = 138, 190, 183

View File

@@ -40,6 +40,7 @@ hidden = 114, 133, 183
shortcode = 187, 218, 255
keyword = 255, 157, 164
value = 235, 187, 255
optional = 187, 218, 255
spellcheckline = 255, 157, 164
errorline = 209, 241, 169
replacetag = 153, 255, 255

View File

@@ -40,6 +40,7 @@ hidden = 150, 152, 150
shortcode = 122, 166, 218
keyword = 213, 78, 83
value = 195, 151, 216
optional = 122, 166, 218
spellcheckline = 213, 78, 83
errorline = 185, 202, 74
replacetag = 112, 192, 177

View File

@@ -40,6 +40,7 @@ hidden = 153, 153, 153
shortcode = 102, 153, 204
keyword = 242, 119, 122
value = 204, 153, 204
optional = 102, 153, 204
spellcheckline = 242, 119, 122
errorline = 153, 204, 153
replacetag = 102, 204, 204

View File

@@ -2,8 +2,6 @@
<html>
<body>
<h2>Credits</h2>
<h3>Main Developer</h3>
<p>Veronica Berglyd Olsen (<a href="https://github.com/vkbo">@vkbo</a>)</p>
@@ -17,6 +15,10 @@
<p>For other contributions, see the project's
<a href="https://github.com/vkbo/novelWriter/graphs/contributors">Contributors</a> page.</p>
<h3>Artwork</h3>
<p>The artwork on the Welcome dialog was created by <a href="https://louisdurrant.art">Louis Durrant</a>.</p>
<h3>Translations</h3>
<p>The default language is English (UK) with English (US) as an option. These are the original

View File

@@ -1,641 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>GNU General Public License v3.0 - GNU Project - Free Software Foundation (FSF)</title>
<link rel="alternate" type="application/rdf+xml"
href="http://www.gnu.org/licenses/gpl-3.0.rdf" />
</head>
<body>
<h3 style="text-align: center;">GNU GENERAL PUBLIC LICENSE</h3>
<p style="text-align: center;">Version 3, 29 June 2007</p>
<p>Copyright &copy; 2007 Free Software Foundation, Inc.
&lt;<a href="https://fsf.org/">https://fsf.org/</a>&gt;</p><p>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.</p>
<h3><a name="preamble"></a>Preamble</h3>
<p>The GNU General Public License is a free, copyleft license for
software and other kinds of works.</p>
<p>The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.</p>
<p>When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.</p>
<p>To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.</p>
<p>For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.</p>
<p>Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.</p>
<p>For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.</p>
<p>Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.</p>
<p>Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.</p>
<p>The precise terms and conditions for copying, distribution and
modification follow.</p>
<h3><a name="terms"></a>TERMS AND CONDITIONS</h3>
<h4><a name="section0"></a>0. Definitions.</h4>
<p>&ldquo;This License&rdquo; refers to version 3 of the GNU General Public License.</p>
<p>&ldquo;Copyright&rdquo; also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.</p>
<p>&ldquo;The Program&rdquo; refers to any copyrightable work licensed under this
License. Each licensee is addressed as &ldquo;you&rdquo;. &ldquo;Licensees&rdquo; and
&ldquo;recipients&rdquo; may be individuals or organizations.</p>
<p>To &ldquo;modify&rdquo; a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a &ldquo;modified version&rdquo; of the
earlier work or a work &ldquo;based on&rdquo; the earlier work.</p>
<p>A &ldquo;covered work&rdquo; means either the unmodified Program or a work based
on the Program.</p>
<p>To &ldquo;propagate&rdquo; a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.</p>
<p>To &ldquo;convey&rdquo; a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.</p>
<p>An interactive user interface displays &ldquo;Appropriate Legal Notices&rdquo;
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.</p>
<h4><a name="section1"></a>1. Source Code.</h4>
<p>The &ldquo;source code&rdquo; for a work means the preferred form of the work
for making modifications to it. &ldquo;Object code&rdquo; means any non-source
form of a work.</p>
<p>A &ldquo;Standard Interface&rdquo; means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.</p>
<p>The &ldquo;System Libraries&rdquo; of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
&ldquo;Major Component&rdquo;, in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.</p>
<p>The &ldquo;Corresponding Source&rdquo; for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.</p>
<p>The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.</p>
<p>The Corresponding Source for a work in source code form is that
same work.</p>
<h4><a name="section2"></a>2. Basic Permissions.</h4>
<p>All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.</p>
<p>You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.</p>
<p>Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.</p>
<h4><a name="section3"></a>3. Protecting Users' Legal Rights From Anti-Circumvention Law.</h4>
<p>No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.</p>
<p>When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.</p>
<h4><a name="section4"></a>4. Conveying Verbatim Copies.</h4>
<p>You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.</p>
<p>You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.</p>
<h4><a name="section5"></a>5. Conveying Modified Source Versions.</h4>
<p>You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:</p>
<ul>
<li>a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.</li>
<li>b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
&ldquo;keep intact all notices&rdquo;.</li>
<li>c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.</li>
<li>d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.</li>
</ul>
<p>A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
&ldquo;aggregate&rdquo; if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.</p>
<h4><a name="section6"></a>6. Conveying Non-Source Forms.</h4>
<p>You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:</p>
<ul>
<li>a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.</li>
<li>b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.</li>
<li>c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.</li>
<li>d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.</li>
<li>e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.</li>
</ul>
<p>A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.</p>
<p>A &ldquo;User Product&rdquo; is either (1) a &ldquo;consumer product&rdquo;, which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, &ldquo;normally used&rdquo; refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.</p>
<p>&ldquo;Installation Information&rdquo; for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.</p>
<p>If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).</p>
<p>The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.</p>
<p>Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.</p>
<h4><a name="section7"></a>7. Additional Terms.</h4>
<p>&ldquo;Additional permissions&rdquo; are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.</p>
<p>When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.</p>
<p>Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:</p>
<ul>
<li>a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or</li>
<li>b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or</li>
<li>c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or</li>
<li>d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or</li>
<li>e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or</li>
<li>f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.</li>
</ul>
<p>All other non-permissive additional terms are considered &ldquo;further
restrictions&rdquo; within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.</p>
<p>If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.</p>
<p>Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.</p>
<h4><a name="section8"></a>8. Termination.</h4>
<p>You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).</p>
<p>However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.</p>
<p>Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.</p>
<p>Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.</p>
<h4><a name="section9"></a>9. Acceptance Not Required for Having Copies.</h4>
<p>You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.</p>
<h4><a name="section10"></a>10. Automatic Licensing of Downstream Recipients.</h4>
<p>Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.</p>
<p>An &ldquo;entity transaction&rdquo; is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.</p>
<p>You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.</p>
<h4><a name="section11"></a>11. Patents.</h4>
<p>A &ldquo;contributor&rdquo; is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's &ldquo;contributor version&rdquo;.</p>
<p>A contributor's &ldquo;essential patent claims&rdquo; are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, &ldquo;control&rdquo; includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.</p>
<p>Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.</p>
<p>In the following three paragraphs, a &ldquo;patent license&rdquo; is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To &ldquo;grant&rdquo; such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.</p>
<p>If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. &ldquo;Knowingly relying&rdquo; means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.</p>
<p>If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.</p>
<p>A patent license is &ldquo;discriminatory&rdquo; if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.</p>
<p>Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.</p>
<h4><a name="section12"></a>12. No Surrender of Others' Freedom.</h4>
<p>If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.</p>
<h4><a name="section13"></a>13. Use with the GNU Affero General Public License.</h4>
<p>Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.</p>
<h4><a name="section14"></a>14. Revised Versions of this License.</h4>
<p>The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.</p>
<p>Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License &ldquo;or any later version&rdquo; applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.</p>
<p>If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.</p>
<p>Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.</p>
<h4><a name="section15"></a>15. Disclaimer of Warranty.</h4>
<p>THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &ldquo;AS IS&rdquo; WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</p>
<h4><a name="section16"></a>16. Limitation of Liability.</h4>
<p>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.</p>
<h4><a name="section17"></a>17. Interpretation of Sections 15 and 16.</h4>
<p>If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.</p>
<p>END OF TERMS AND CONDITIONS</p>
</body></html>

View File

@@ -1,50 +0,0 @@
<!DOCTYPE html public "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<body>
<h2>Release Notes for 2.2</h2>
<p><i>Released on 17 December 2023</i></p>
<p>This release comes with a number of new features. These are some highlights.</p>
<p>In addition to the common Markdown style formatting for bold, italic and strike through, a set
of new shortcodes have been added. The shortcodes are far more flexible than the Markdown style
syntax, and can be used for more complex formatting cases. Like when you need to add multiple,
overlapping formats, or add emphasis to just a part of a word. The shortcodes also allow for
underline, subscript and superscript, which the Markdown syntax does not. The new formats are
available in the "Format" menu, and in a new toolbar in the editor that can be enabled by clicking
the three dots in the top–left corner. The shortcode format was chosen because it can later be
extended to include other requested features as well. Please have a look at the documentation for
more details about the new shortcodes.</p>
<p>The Tags and References system has been improved. The tags themselves are no longer case
sensitive when you use them in references, but they are still displayed as you typed them in the
tag definition when they are displayed in the user interface. Starting to type the '@' symbol in
the text editor, on a new line, will now open an auto-completer menu which will display available
options. It may not display all of your tags if you have a lot of them, but starting to type more
characters will filter the list down further.</p>
<p>You can now automatically create a note file for a new tag that you have added to a reference
list in a document, but is not yet defined in a project note. So, for instance, if you come up with
a new character while writing, and add a new tag to your '@char' references, you can right-click
the new tag and create a new note for that entry directly. In addition, it is now also possible to
right-click a heading in an open document and set the item label in the project tree to match the
heading.</p>
<p>In addition to the changes in the editor, the "References" panel below the document viewer has
also been completely redesigned. It now shows all the references to the document you are viewing as
a list, with a lot more details than before. In addition, tabs in the panel will appear to show all
the tags you have defined in your notes, sorted as one tab per category. Like for instance
Characters, Locations, Objects, etc. You can also give each note a short description comment on the
same format as the summary comments for chapters and scenes. The short description comment can be
added from the "Insert" menu under "Special Comments".</p>
<p>The last major change in this release is the new multi-select feature in the project tree. You
can now select multiple documents and folders using the mouse while pressing 'Ctrl' or 'Shift'. By
right-clicking the selected items, you can perform a limited set of operations on all of them, like
changing active status, and the status or importance labels. You can also drag and drop multiple
items under the condition that all the selected items are in the same folder, at the same level.
This restriction is in place due to limitations in the framework novelWriter is based on. But this
should help in cases where multiple documents need to be moved in and out of folders or between
folders. Note that adding the multi-select feature meant that the undo feature of the project tree
had to be removed. It may be added back later.</p>
<p><i>See also the <a href="https://github.com/vkbo/novelWriter/releases">Releases</a> page.</i></p>
</body>
</html>

View File

@@ -0,0 +1,29 @@
[Main]
name = Cyberpunk Night
description = A taste of the future 80s
author = Anders Lemvigh
url = https://github.com/alemvigh
license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
icontheme = typicons_dark
[Palette]
window = 0, 0, 0
windowtext = 150, 150, 150
base = 0, 0, 0
alternatebase = 30, 20, 45
text = 150, 150, 150
tooltipbase = 40, 20, 70
tooltiptext = 255, 255, 255
button = 5, 0, 10
buttontext = 150, 150, 150
brighttext = 255, 255, 255
highlight = 50, 30, 80
highlightedtext = 255, 255, 255
link = 77, 77, 255
linkvisited = 50, 0, 80
[GUI]
statusnone = 50, 50, 50
statussaved = 77, 255, 77
statusunsaved = 255, 77, 77

View File

@@ -21,8 +21,8 @@ buttontext = 204, 204, 204
brighttext = 62, 62, 62
highlight = 44, 152, 247
highlightedtext = 255, 255, 255
link = 44, 152, 247
linkvisited = 44, 152, 247
link = 102, 153, 204
linkvisited = 102, 153, 204
[GUI]
helptext = 164, 164, 164

View File

@@ -21,8 +21,8 @@ buttontext = 0, 0, 0
brighttext = 255, 255, 255
highlight = 48, 135, 198
highlightedtext = 255, 255, 255
link = 0, 84, 255
linkvisited = 0, 84, 255
link = 66, 113, 174
linkvisited = 66, 113, 174
[GUI]
helptext = 92, 92, 92

View File

@@ -6,7 +6,7 @@ File History:
Created: 2019-05-12 [0.1.0]
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -29,7 +29,7 @@ import logging
import unicodedata
import xml.etree.ElementTree as ET
from typing import Any, Literal
from typing import TYPE_CHECKING, Any, Literal
from pathlib import Path
from datetime import datetime
from configparser import ConfigParser
@@ -41,14 +41,17 @@ from PyQt5.QtCore import QCoreApplication, QUrl
from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
from novelwriter.error import logException
from novelwriter.constants import nwConst, nwUnicode
from novelwriter.constants import nwConst, nwLabels, nwUnicode, trConst
if TYPE_CHECKING: # pragma: no cover
from typing import TypeGuard # Requires Python 3.10
logger = logging.getLogger(__name__)
# =============================================================================================== #
##
# Checker Functions
# =============================================================================================== #
##
def checkStringNone(value: Any, default: str | None) -> str | None:
"""Check if a variable is a string or a None."""
@@ -104,15 +107,6 @@ def checkBool(value: Any, default: bool) -> bool:
return default
def checkHandle(value, default, allowNone=False):
"""Check if a value is a handle."""
if allowNone and (value is None or value == "None"):
return None
if isHandle(value):
return str(value)
return default
def checkUuid(value: Any, default: str) -> str:
"""Try to process a value as an UUID, or return a default."""
try:
@@ -131,11 +125,11 @@ def checkPath(value: Any, default: Path) -> Path:
return default
# =============================================================================================== #
##
# Validator Functions
# =============================================================================================== #
##
def isHandle(value: Any) -> bool:
def isHandle(value: Any) -> TypeGuard[str]:
"""Check if a string is a valid novelWriter handle.
Note: This is case sensitive. Must be lower case!
"""
@@ -149,7 +143,7 @@ def isHandle(value: Any) -> bool:
return True
def isTitleTag(value: Any) -> bool:
def isTitleTag(value: Any) -> TypeGuard[str]:
"""Check if a string is a valid title tag string."""
if not isinstance(value, str):
return False
@@ -163,19 +157,19 @@ def isTitleTag(value: Any) -> bool:
return True
def isItemClass(value: str) -> bool:
def isItemClass(value: Any) -> TypeGuard[str]:
"""Check if a string is a valid nwItemClass identifier."""
return value in nwItemClass.__members__
return isinstance(value, str) and value in nwItemClass.__members__
def isItemType(value: str) -> bool:
def isItemType(value: Any) -> TypeGuard[str]:
"""Check if a string is a valid nwItemType identifier."""
return value in nwItemType.__members__
return isinstance(value, str) and value in nwItemType.__members__
def isItemLayout(value: str) -> bool:
def isItemLayout(value: Any) -> TypeGuard[str]:
"""Check if a string is a valid nwItemLayout identifier."""
return value in nwItemLayout.__members__
return isinstance(value, str) and value in nwItemLayout.__members__
def hexToInt(value: Any, default: int = 0) -> int:
@@ -189,8 +183,7 @@ def hexToInt(value: Any, default: int = 0) -> int:
def minmax(value: int, minVal: int, maxVal: int) -> int:
"""Make sure an integer is between min and max value (inclusive).
"""
"""Check that an value is between min and max value (inclusive)."""
return min(maxVal, max(minVal, value))
@@ -204,26 +197,26 @@ def checkIntTuple(value: int, valid: tuple | list | set, default: int) -> int:
return default
# =============================================================================================== #
##
# Formatting Functions
# =============================================================================================== #
##
def formatInt(value: int) -> str:
"""Formats an integer with k, M, G etc."""
if not isinstance(value, int):
return "ERR"
theVal = float(value)
if theVal > 1000.0:
fVal = float(value)
if fVal > 1000.0:
for pF in ["k", "M", "G", "T", "P", "E"]:
theVal /= 1000.0
if theVal < 1000.0:
if theVal < 10.0:
return f"{theVal:4.2f}{nwUnicode.U_THSP}{pF}"
elif theVal < 100.0:
return f"{theVal:4.1f}{nwUnicode.U_THSP}{pF}"
fVal /= 1000.0
if fVal < 1000.0:
if fVal < 10.0:
return f"{fVal:4.2f}{nwUnicode.U_THSP}{pF}"
elif fVal < 100.0:
return f"{fVal:4.1f}{nwUnicode.U_THSP}{pF}"
else:
return f"{theVal:3.0f}{nwUnicode.U_THSP}{pF}"
return f"{fVal:3.0f}{nwUnicode.U_THSP}{pF}"
return str(value)
@@ -250,9 +243,27 @@ def formatTime(t: int) -> str:
return "ERROR"
# =============================================================================================== #
def formatVersion(value: str) -> str:
"""Format a version number into a more human readable form."""
return value.lower().replace("a", " Alpha ").replace("b", " Beta ").replace("rc", " RC ")
def formatFileFilter(extensions: list[str | tuple[str, str]]) -> str:
"""Format a list of extensions, or extension + label pairs into a
QFileDialog extensions filter.
"""
result = []
for ext in extensions:
if isinstance(ext, str):
result.append(f"{trConst(nwLabels.FILE_FILTERS.get(ext))} ({ext})")
elif isinstance(ext, tuple) and len(ext) == 2:
result.append(f"{ext[0]} ({ext[1]})")
return ";;".join(result)
##
# String Functions
# =============================================================================================== #
##
def simplified(text: str) -> str:
"""Take a string and strip leading and trailing whitespaces, and
@@ -270,22 +281,22 @@ def transferCase(source: str, target: str) -> str:
"""Transfers the case of the source word to the target word. This
will consider all upper or lower, and first char capitalisation.
"""
theResult = target
result = target
if not isinstance(source, str) or not isinstance(target, str):
return theResult
return result
if len(target) < 1 or len(source) < 1:
return theResult
return result
if source.istitle():
theResult = target.title()
result = target.title()
if source.isupper():
theResult = target.upper()
result = target.upper()
elif source.islower():
theResult = target.lower()
result = target.lower()
return theResult
return result
def fuzzyTime(seconds: int) -> str:
@@ -371,9 +382,9 @@ def numberToRoman(value: int, toLower: bool = False) -> str:
return roman.lower() if toLower else roman
# =============================================================================================== #
##
# Encoder Functions
# =============================================================================================== #
##
def jsonEncode(data: dict | list | tuple, n: int = 0, nmax: int = 0) -> str:
"""Encode a dictionary, list or tuple as a json object or array, and
@@ -463,9 +474,9 @@ def xmlIndent(tree: ET.Element | ET.ElementTree) -> None:
return
# =============================================================================================== #
##
# File and File System Functions
# =============================================================================================== #
##
def readTextFile(path: str | Path) -> str:
"""Read the content of a text file in a robust manner."""
@@ -507,9 +518,9 @@ def openExternalPath(path: Path) -> bool:
return False
# =============================================================================================== #
##
# Classes
# =============================================================================================== #
##
class NWConfigParser(ConfigParser):
"""Common: Adapted Config Parser

View File

@@ -7,7 +7,7 @@ Created: 2018-09-22 [0.0.1] Config
Created: 2022-11-09 [2.0rc2] RecentProjects
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -110,8 +110,8 @@ class Config:
# Size Settings
self._mainWinSize = [1200, 650] # Last size of the main GUI window
self._welcomeSize = [800, 550] # Last size of the welcome window
self._prefsWinSize = [700, 615] # Last size of the Preferences dialog
self._projLoadCols = [280, 60, 160] # Last columns widths of the Project Load dialog
self._mainPanePos = [300, 800] # Last position of the main window splitter
self._viewPanePos = [500, 150] # Last position of the document viewer splitter
self._outlnPanePos = [500, 150] # Last position of the outline panel splitter
@@ -150,9 +150,6 @@ class Config:
self.autoScrollPos = 30 # Start point for typewriter-like scrolling
self.scrollPastEnd = True # Scroll past end of document, and centre cursor
self.wordCountTimer = 5.0 # Interval for word count update in seconds
self.incNotesWCount = True # The status bar word count includes notes
self.highlightQuotes = True # Highlight text in quotes
self.allowOpenSQuote = False # Allow open-ended single quotes
self.allowOpenDQuote = True # Allow open-ended double quotes
@@ -160,6 +157,7 @@ class Config:
self.stopWhenIdle = True # Stop the status bar clock when the user is idle
self.userIdleTime = 300 # Time of inactivity to consider user idle
self.incNotesWCount = True # The status bar word count includes notes
# User-Selected Symbol Settings
self.fmtApostrophe = nwUnicode.U_RSQUO
@@ -250,12 +248,12 @@ class Config:
return [int(x*self.guiScale) for x in self._mainWinSize]
@property
def preferencesWinSize(self) -> list[int]:
return [int(x*self.guiScale) for x in self._prefsWinSize]
def welcomeWinSize(self) -> list[int]:
return [int(x*self.guiScale) for x in self._welcomeSize]
@property
def projLoadColWidths(self) -> list[int]:
return [int(x*self.guiScale) for x in self._projLoadCols]
def preferencesWinSize(self) -> list[int]:
return [int(x*self.guiScale) for x in self._prefsWinSize]
@property
def mainPanePos(self) -> list[int]:
@@ -306,17 +304,18 @@ class Config:
self._mainWinSize[1] = height
return
def setWelcomeWinSize(self, width: int, height: int) -> None:
"""Set the size of the Preferences dialog window."""
self._welcomeSize[0] = int(width/self.guiScale)
self._welcomeSize[1] = int(height/self.guiScale)
return
def setPreferencesWinSize(self, width: int, height: int) -> None:
"""Set the size of the Preferences dialog window."""
self._prefsWinSize[0] = int(width/self.guiScale)
self._prefsWinSize[1] = int(height/self.guiScale)
return
def setProjLoadColWidths(self, widths: list[int]) -> None:
"""Set the column widths of the Load Project dialog."""
self._projLoadCols = [int(x/self.guiScale) for x in widths]
return
def setMainPanePos(self, pos: list[int]) -> None:
"""Set the position of the main GUI splitter."""
self._mainPanePos = [int(x/self.guiScale) for x in pos]
@@ -410,10 +409,10 @@ class Config:
"""Compile and return error messages from the initialisation of
the Config class, and clear the error buffer.
"""
errMessage = "<br>".join(self._errData)
message = "<br>".join(self._errData)
self._hasError = False
self._errData = []
return errMessage
return message
def listLanguages(self, lngSet: int) -> list[tuple[str, str]]:
"""List localisation files in the i18n folder. The default GUI
@@ -545,8 +544,8 @@ class Config:
# Sizes
sec = "Sizes"
self._mainWinSize = conf.rdIntList(sec, "mainwindow", self._mainWinSize)
self._welcomeSize = conf.rdIntList(sec, "welcome", self._welcomeSize)
self._prefsWinSize = conf.rdIntList(sec, "preferences", self._prefsWinSize)
self._projLoadCols = conf.rdIntList(sec, "projloadcols", self._projLoadCols)
self._mainPanePos = conf.rdIntList(sec, "mainpane", self._mainPanePos)
self._viewPanePos = conf.rdIntList(sec, "viewpane", self._viewPanePos)
self._outlnPanePos = conf.rdIntList(sec, "outlinepane", self._outlnPanePos)
@@ -590,7 +589,6 @@ class Config:
self.showTabsNSpaces = conf.rdBool(sec, "showtabsnspaces", self.showTabsNSpaces)
self.showLineEndings = conf.rdBool(sec, "showlineendings", self.showLineEndings)
self.showMultiSpaces = conf.rdBool(sec, "showmultispaces", self.showMultiSpaces)
self.wordCountTimer = conf.rdFlt(sec, "wordcounttimer", self.wordCountTimer)
self.incNotesWCount = conf.rdBool(sec, "incnoteswcount", self.incNotesWCount)
self.showFullPath = conf.rdBool(sec, "showfullpath", self.showFullPath)
self.highlightQuotes = conf.rdBool(sec, "highlightquotes", self.highlightQuotes)
@@ -635,7 +633,7 @@ class Config:
conf = NWConfigParser()
conf["Meta"] = {
"timestamp": formatTimeStamp(time()),
"timestamp": formatTimeStamp(time()),
}
conf["Main"] = {
@@ -651,12 +649,12 @@ class Config:
}
conf["Sizes"] = {
"mainwindow": self._packList(self._mainWinSize),
"preferences": self._packList(self._prefsWinSize),
"projloadcols": self._packList(self._projLoadCols),
"mainpane": self._packList(self._mainPanePos),
"viewpane": self._packList(self._viewPanePos),
"outlinepane": self._packList(self._outlnPanePos),
"mainwindow": self._packList(self._mainWinSize),
"welcome": self._packList(self._welcomeSize),
"preferences": self._packList(self._prefsWinSize),
"mainpane": self._packList(self._mainPanePos),
"viewpane": self._packList(self._viewPanePos),
"outlinepane": self._packList(self._outlnPanePos),
}
conf["Project"] = {
@@ -697,7 +695,6 @@ class Config:
"showtabsnspaces": str(self.showTabsNSpaces),
"showlineendings": str(self.showLineEndings),
"showmultispaces": str(self.showMultiSpaces),
"wordcounttimer": str(self.wordCountTimer),
"incnoteswcount": str(self.incNotesWCount),
"showfullpath": str(self.showFullPath),
"highlightquotes": str(self.highlightQuotes),
@@ -774,22 +771,20 @@ class RecentProjects:
self._data = {}
cacheFile = self._conf.dataPath(nwFiles.RECENT_FILE)
if not cacheFile.is_file():
return True
try:
with open(cacheFile, mode="r", encoding="utf-8") as inFile:
theData = json.load(inFile)
for projPath, theEntry in theData.items():
self._data[projPath] = {
"title": theEntry.get("title", ""),
"words": theEntry.get("words", 0),
"time": theEntry.get("time", 0),
}
except Exception:
logger.error("Could not load recent project cache")
logException()
return False
if cacheFile.is_file():
try:
with open(cacheFile, mode="r", encoding="utf-8") as inFile:
data = json.load(inFile)
for path, entry in data.items():
self._data[path] = {
"title": entry.get("title", ""),
"words": entry.get("words", 0),
"time": entry.get("time", 0),
}
except Exception:
logger.error("Could not load recent project cache")
logException()
return False
return True

View File

@@ -6,7 +6,7 @@ File History:
Created: 2019-04-28 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -43,12 +43,12 @@ class nwConst:
FMT_DSTAMP = "%Y-%m-%d" # Date only format
# URLs
URL_WEB = "https://novelwriter.io"
URL_DOCS = "https://docs.novelwriter.io"
URL_CODE = "https://github.com/vkbo/novelWriter"
URL_REPORT = "https://github.com/vkbo/novelWriter/issues"
URL_HELP = "https://github.com/vkbo/novelWriter/discussions"
URL_RELEASE = "https://github.com/vkbo/novelWriter/releases/latest"
URL_WEB = "https://novelwriter.io"
URL_DOCS = "https://docs.novelwriter.io"
URL_RELEASES = "https://releases.novelwriter.io"
URL_CODE = "https://github.com/vkbo/novelWriter"
URL_REPORT = "https://github.com/vkbo/novelWriter/issues"
URL_HELP = "https://github.com/vkbo/novelWriter/discussions"
# Requests
USER_AGENT = "Mozilla/5.0 (compatible; novelWriter (Python))"
@@ -56,6 +56,9 @@ class nwConst:
# Gui Settings
STATUS_MSG_TIMEOUT = 15000 # milliseconds
# Dialogs
DLG_FINISHED = 2
# END Class nwConst
@@ -107,7 +110,6 @@ class nwFiles:
# Project Root Files
PROJ_FILE = "nwProject.nwx"
PROJ_BACKUP = "nwProject.bak"
PROJ_LOCK = "nwProject.lock"
TOC_TXT = "ToC.txt"
@@ -184,6 +186,7 @@ class nwLabels:
nwItemClass.ENTITY: QT_TRANSLATE_NOOP("Constant", "Entities"),
nwItemClass.CUSTOM: QT_TRANSLATE_NOOP("Constant", "Custom"),
nwItemClass.ARCHIVE: QT_TRANSLATE_NOOP("Constant", "Archive"),
nwItemClass.TEMPLATE: QT_TRANSLATE_NOOP("Constant", "Templates"),
nwItemClass.TRASH: QT_TRANSLATE_NOOP("Constant", "Trash"),
}
CLASS_ICON = {
@@ -197,6 +200,7 @@ class nwLabels:
nwItemClass.ENTITY: "cls_entity",
nwItemClass.CUSTOM: "cls_custom",
nwItemClass.ARCHIVE: "cls_archive",
nwItemClass.TEMPLATE: "cls_template",
nwItemClass.TRASH: "cls_trash",
}
LAYOUT_NAME = {
@@ -266,6 +270,13 @@ class nwLabels:
nwBuildFmt.J_HTML: ".json",
nwBuildFmt.J_NWD: ".json",
}
FILE_FILTERS = {
"*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"),
"*.md": QT_TRANSLATE_NOOP("Constant", "Markdown files"),
"*.nwd": QT_TRANSLATE_NOOP("Constant", "novelWriter files"),
"*.csv": QT_TRANSLATE_NOOP("Constant", "CSV files"),
"*": QT_TRANSLATE_NOOP("Constant", "All files"),
}
UNIT_NAME = {
"mm": QT_TRANSLATE_NOOP("Constant", "Millimetres"),
"cm": QT_TRANSLATE_NOOP("Constant", "Centimetres"),
@@ -298,16 +309,27 @@ class nwLabels:
class nwHeadFmt:
BR = "{BR}"
TITLE = "{Title}"
CH_NUM = "{Chapter}"
CH_WORD = "{Chapter:Word}"
CH_ROMU = "{Chapter:URoman}"
CH_ROML = "{Chapter:LRoman}"
SC_NUM = "{Scene}"
SC_ABS = "{Scene:Abs}"
BR = "{BR}"
TITLE = "{Title}"
CH_NUM = "{Chapter}"
CH_WORD = "{Chapter:Word}"
CH_ROMU = "{Chapter:URoman}"
CH_ROML = "{Chapter:LRoman}"
SC_NUM = "{Scene}"
SC_ABS = "{Scene:Abs}"
CHAR_POV = "{Char:POV}"
CHAR_FOCUS = "{Char:Focus}"
ALL = [TITLE, CH_NUM, CH_WORD, CH_ROMU, CH_ROML, SC_NUM, SC_ABS]
PAGE_HEADERS = [
TITLE, CH_NUM, CH_WORD, CH_ROMU, CH_ROML, SC_NUM, SC_ABS,
CHAR_POV, CHAR_FOCUS
]
# ODT Document Page Header
ODT_PROJECT = "{Project}"
ODT_AUTHOR = "{Author}"
ODT_PAGE = "{Page}"
ODT_AUTO = "{Project} / {Author} / {Page}"
# END Class nwHeadFmt

View File

@@ -7,7 +7,7 @@ Created: 2023-02-14 [2.1b1] BuildSettings
Created: 2023-05-22 [2.1b1] BuildCollection
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -29,8 +29,8 @@ import uuid
import logging
from enum import Enum
from typing import Iterable
from pathlib import Path
from collections.abc import Iterable
from PyQt5.QtCore import QT_TRANSLATE_NOOP, QCoreApplication
@@ -79,6 +79,8 @@ SETTINGS_TEMPLATE = {
"format.leftMargin": (float, 2.0),
"format.rightMargin": (float, 2.0),
"odt.addColours": (bool, True),
"odt.pageHeader": (str, nwHeadFmt.ODT_AUTO),
"odt.pageCountOffset": (int, 0),
"html.addStyles": (bool, True),
}
@@ -125,6 +127,8 @@ SETTINGS_LABELS = {
"odt": QT_TRANSLATE_NOOP("Builds", "Open Document (.odt)"),
"odt.addColours": QT_TRANSLATE_NOOP("Builds", "Add Highlight Colours"),
"odt.pageHeader": QT_TRANSLATE_NOOP("Builds", "Page Header"),
"odt.pageCountOffset": QT_TRANSLATE_NOOP("Builds", "Page Counter Offset"),
"html": QT_TRANSLATE_NOOP("Builds", "HTML (.html)"),
"html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"),
@@ -235,16 +239,12 @@ class BuildSettings:
def getInt(self, key: str) -> int:
"""Type safe value access for integers."""
value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1])
if isinstance(value, (int, float)):
return int(value)
return 0
return int(value) if isinstance(value, (int, float)) else 0
def getFloat(self, key: str) -> float:
"""Type safe value access for floats."""
value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1])
if isinstance(value, (int, float)):
return float(value)
return 0.0
return float(value) if isinstance(value, (int, float)) else 0.0
##
# Setters

View File

@@ -9,7 +9,7 @@ Created: 2022-11-03 [2.0rc2] ProjectBuilder
Created: 2023-07-20 [2.1b1] DocDuplicator
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -29,16 +29,19 @@ from __future__ import annotations
import shutil
import logging
from typing import Iterable
from pathlib import Path
from functools import partial
from zipfile import ZipFile, is_zipfile
from collections.abc import Iterable
from PyQt5.QtCore import QCoreApplication
from novelwriter import CONFIG, SHARED
from novelwriter.common import minmax, simplified
from novelwriter.constants import nwItemClass
from novelwriter.common import isHandle, minmax, simplified
from novelwriter.constants import nwFiles, nwItemClass
from novelwriter.core.item import NWItem
from novelwriter.core.project import NWProject
from novelwriter.core.storage import NWStorageCreate
logger = logging.getLogger(__name__)
@@ -277,28 +280,25 @@ class DocDuplicator:
"""Run through a list of items, duplicate them, and copy the
text content if they are documents.
"""
if not items:
return
nHandle = items[0]
hMap: dict[str, str | None] = {t: None for t in items}
for tHandle in items:
newItem = self._project.tree.duplicate(tHandle)
if newItem is None:
return
hMap[tHandle] = newItem.itemHandle
if newItem.itemParent in hMap:
newItem.setParent(hMap[newItem.itemParent])
self._project.tree.updateItemData(newItem.itemHandle)
if newItem.isFileType():
oldDoc = self._project.storage.getDocument(tHandle)
newDoc = self._project.storage.getDocument(newItem.itemHandle)
if newDoc.fileExists():
if items:
nHandle = items[0]
hMap: dict[str, str | None] = {t: None for t in items}
for tHandle in items:
newItem = self._project.tree.duplicate(tHandle)
if newItem is None:
return
newDoc.writeDocument(oldDoc.readDocument() or "")
yield newItem.itemHandle, nHandle
nHandle = None
hMap[tHandle] = newItem.itemHandle
if newItem.itemParent in hMap:
newItem.setParent(hMap[newItem.itemParent])
self._project.tree.updateItemData(newItem.itemHandle)
if newItem.isFileType():
oldDoc = self._project.storage.getDocument(tHandle)
newDoc = self._project.storage.getDocument(newItem.itemHandle)
if newDoc.fileExists():
return
newDoc.writeDocument(oldDoc.readDocument() or "")
yield newItem.itemHandle, nHandle
nHandle = None
return
# END Class DocDuplicator
@@ -310,64 +310,72 @@ class ProjectBuilder:
"""
def __init__(self) -> None:
self.tr = partial(QCoreApplication.translate, "NWProject")
self._path = None
self.tr = partial(QCoreApplication.translate, "ProjectBuilder")
return
@property
def projPath(self) -> Path | None:
"""The path of the newly created project."""
return self._path
##
# Methods
##
def buildProject(self, data: dict) -> bool:
"""Build a project from a data dictionary of specifications
provided by the wizard.
"""
if not isinstance(data, dict):
logger.error("Invalid call to newProject function")
return False
"""Build or copy a project from a data dictionary."""
if isinstance(data, dict):
path = data.get("path", None) or None
if isinstance(path, (str, Path)):
self._path = Path(path).resolve()
if data.get("sample", False):
return self._extractSampleProject(self._path)
elif data.get("template"):
return self._copyProject(self._path, data)
else:
return self._buildAndPopulate(self._path, data)
SHARED.error("A project path is required.")
return False
popMinimal = data.get("popMinimal", True)
popCustom = data.get("popCustom", False)
popSample = data.get("popSample", False)
# Check if we're extracting the sample project. This is handled
# differently as it isn't actually a new project, so we forward
# this to another function and return here.
if popSample:
return self._extractSampleProject(data)
projPath = data.get("projPath", None)
if projPath is None:
logger.error("No project path set for the new project")
return False
##
# Internal Functions
##
def _buildAndPopulate(self, path: Path, data: dict) -> bool:
"""Build a blank project from a data dictionary."""
project = NWProject()
if not project.storage.openProjectInPlace(projPath, newProject=True):
status = project.storage.createNewProject(path)
if status == NWStorageCreate.NOT_EMPTY:
SHARED.error(self.tr(
"The target folder is not empty. "
"Please choose another folder."
))
return False
elif status == NWStorageCreate.OS_ERROR:
SHARED.error(self.tr(
"An error occurred while trying to create the project."
), exc=project.storage.exc)
return False
self._path = project.storage.storagePath
lblNewProject = self.tr("New Project")
lblNewChapter = self.tr("New Chapter")
lblNewScene = self.tr("New Scene")
lblTitlePage = self.tr("Title Page")
lblByAuthors = self.tr("By")
# Settings
projName = data.get("projName", lblNewProject)
projTitle = data.get("projTitle", lblNewProject)
projAuthor = data.get("projAuthor", "")
projLang = data.get("projLang", "en_GB")
project.data.setUuid(None)
project.data.setName(projName)
project.data.setTitle(projTitle)
project.data.setAuthor(projAuthor)
project.data.setLanguage(projLang)
project.data.setName(data.get("name", lblNewProject))
project.data.setAuthor(data.get("author", ""))
project.data.setLanguage(CONFIG.guiLocale)
project.setDefaultStatusImport()
project.session.startSession()
# Add Root Folders
hNovelRoot = project.newRoot(nwItemClass.NOVEL)
hTitlePage = project.newFile(lblTitlePage, hNovelRoot)
novelTitle = project.data.title if project.data.title else project.data.name
novelTitle = project.data.name
titlePage = f"#! {novelTitle}\n\n"
if project.data.author:
@@ -376,116 +384,148 @@ class ProjectBuilder:
aDoc = project.storage.getDocument(hTitlePage)
aDoc.writeDocument(titlePage)
if popMinimal:
# Creating a minimal project with a few root folders and a
# single chapter with a single scene.
hChapter = project.newFile(lblNewChapter, hNovelRoot)
aDoc = project.storage.getDocument(hChapter)
aDoc.writeDocument(f"## {lblNewChapter}\n\n")
# Create a project structure based on selected root folders
# and a number of chapters and scenes selected in the
# wizard's custom page.
if hChapter:
hScene = project.newFile(lblNewScene, hChapter)
aDoc = project.storage.getDocument(hScene)
aDoc.writeDocument(f"### {lblNewScene}\n\n")
# Create chapters and scenes
numChapters = data.get("chapters", 0)
numScenes = data.get("scenes", 0)
project.newRoot(nwItemClass.PLOT)
project.newRoot(nwItemClass.CHARACTER)
project.newRoot(nwItemClass.WORLD)
project.newRoot(nwItemClass.ARCHIVE)
chSynop = self.tr("Summary of the chapter.")
scSynop = self.tr("Summary of the scene.")
bfNote = self.tr("A short description.")
project.saveProject()
project.closeProject()
# Create chapters
if numChapters > 0:
for ch in range(numChapters):
chTitle = self.tr("Chapter {0}").format(f"{ch+1:d}")
cHandle = project.newFile(chTitle, hNovelRoot)
aDoc = project.storage.getDocument(cHandle)
aDoc.writeDocument(f"## {chTitle}\n\n%Synopsis: {chSynop}\n\n")
elif popCustom:
# Create a project structure based on selected root folders
# and a number of chapters and scenes selected in the
# wizard's custom page.
# Create chapter scenes
if numScenes > 0 and cHandle:
for sc in range(numScenes):
scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}")
sHandle = project.newFile(scTitle, cHandle)
aDoc = project.storage.getDocument(sHandle)
aDoc.writeDocument(f"### {scTitle}\n\n%Synopsis: {scSynop}\n\n")
# Create chapters and scenes
numChapters = data.get("numChapters", 0)
numScenes = data.get("numScenes", 0)
# Create scenes (no chapters)
elif numScenes > 0:
for sc in range(numScenes):
scTitle = self.tr("Scene {0}").format(f"{sc+1:d}")
sHandle = project.newFile(scTitle, hNovelRoot)
aDoc = project.storage.getDocument(sHandle)
aDoc.writeDocument(f"### {scTitle}\n\n%Synopsis: {scSynop}\n\n")
chSynop = self.tr("Summary of the chapter.")
scSynop = self.tr("Summary of the scene.")
bfNote = self.tr("A short description.")
# Create notes folders
noteTitles = {
nwItemClass.PLOT: self.tr("Main Plot"),
nwItemClass.CHARACTER: self.tr("Protagonist"),
nwItemClass.WORLD: self.tr("Main Location"),
}
# Create chapters
if numChapters > 0:
for ch in range(numChapters):
chTitle = self.tr("Chapter {0}").format(f"{ch+1:d}")
cHandle = project.newFile(chTitle, hNovelRoot)
aDoc = project.storage.getDocument(cHandle)
aDoc.writeDocument(f"## {chTitle}\n\n% Synopsis: {chSynop}\n\n")
addNotes = data.get("notes", False)
for newRoot in data.get("roots", []):
if newRoot in nwItemClass:
rHandle = project.newRoot(newRoot)
if addNotes:
aHandle = project.newFile(noteTitles[newRoot], rHandle)
ntTag = simplified(noteTitles[newRoot]).replace(" ", "")
aDoc = project.storage.getDocument(aHandle)
aDoc.writeDocument(
f"# {noteTitles[newRoot]}\n\n"
f"@tag: {ntTag}\n\n"
f"%Short: {bfNote}\n\n"
)
# Create chapter scenes
if numScenes > 0 and cHandle:
for sc in range(numScenes):
scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}")
sHandle = project.newFile(scTitle, cHandle)
aDoc = project.storage.getDocument(sHandle)
aDoc.writeDocument(f"### {scTitle}\n\n% Synopsis: {scSynop}\n\n")
# Also add the archive and trash folders
project.newRoot(nwItemClass.ARCHIVE)
project.trashFolder()
# Create scenes (no chapters)
elif numScenes > 0:
for sc in range(numScenes):
scTitle = self.tr("Scene {0}").format(f"{sc+1:d}")
sHandle = project.newFile(scTitle, hNovelRoot)
aDoc = project.storage.getDocument(sHandle)
aDoc.writeDocument(f"### {scTitle}\n\n% Synopsis: {scSynop}\n\n")
# Create notes folders
noteTitles = {
nwItemClass.PLOT: self.tr("Main Plot"),
nwItemClass.CHARACTER: self.tr("Protagonist"),
nwItemClass.WORLD: self.tr("Main Location"),
}
addNotes = data.get("addNotes", False)
for newRoot in data.get("addRoots", []):
if newRoot in nwItemClass:
rHandle = project.newRoot(newRoot)
if addNotes:
aHandle = project.newFile(noteTitles[newRoot], rHandle)
ntTag = simplified(noteTitles[newRoot]).replace(" ", "")
aDoc = project.storage.getDocument(aHandle)
aDoc.writeDocument(
f"# {noteTitles[newRoot]}\n\n"
f"@tag: {ntTag}\n\n"
f"% Short: {bfNote}\n\n"
)
# Also add the archive and trash folders
project.newRoot(nwItemClass.ARCHIVE)
project.trashFolder()
project.saveProject()
project.closeProject()
project.saveProject()
project.closeProject()
return True
##
# Internal Functions
##
def _copyProject(self, path: Path, data: dict) -> bool:
"""Copy an existing project content, but not the meta data, and
update new settings.
"""
source = data.get("template")
if not (isinstance(source, Path) and source.is_file()
and (source.name == nwFiles.PROJ_FILE or is_zipfile(source))):
logger.error("Could not access source project: %s", source)
return False
def _extractSampleProject(self, data: dict) -> bool:
logger.info("Copying project: %s", source)
if path.exists():
SHARED.error(self.tr(
"The target folder already exists. "
"Please choose another folder."
))
return False
# Begin copying
srcPath = source.parent
dstPath = path.resolve()
srcCont = srcPath / "content"
dstCont = dstPath / "content"
try:
dstPath.mkdir(exist_ok=True)
dstCont.mkdir(exist_ok=True)
if is_zipfile(source):
with ZipFile(source) as zipObj:
for member in zipObj.namelist():
if member == nwFiles.PROJ_FILE:
zipObj.extract(member, dstPath)
elif member.startswith("content") and member.endswith(".nwd"):
zipObj.extract(member, dstPath)
else:
shutil.copy2(srcPath / nwFiles.PROJ_FILE, dstPath)
for item in srcCont.iterdir():
if item.is_file() and item.suffix == ".nwd" and isHandle(item.stem):
shutil.copy2(item, dstCont)
except Exception as exc:
SHARED.error(self.tr("Could not copy project files."), exc=exc)
return False
# Open the copied project and update settings
project = NWProject()
project.openProject(dstPath)
project.data.setUuid("") # Creates a fresh uuid
project.data.setName(data.get("name", "None"))
project.data.setAuthor(data.get("author", ""))
project.data.setSpellCheck(True)
project.data.setSpellLang(None)
project.data.setDoBackup(True)
project.data.setSaveCount(0)
project.data.setAutoCount(0)
project.data.setEditTime(0)
project.saveProject()
project.closeProject()
return True
def _extractSampleProject(self, path: Path) -> bool:
"""Make a copy of the sample project by extracting the
sample.zip file to the new path.
"""
projPath = data.get("projPath", None)
if projPath is None:
logger.error("No project path set for the example project")
if path.exists():
SHARED.error(self.tr(
"The target folder already exists. "
"Please choose another folder."
))
return False
pkgSample = CONFIG.assetPath("sample.zip")
if pkgSample.is_file():
if (sample := CONFIG.assetPath("sample.zip")).is_file():
try:
shutil.unpack_archive(pkgSample, projPath)
shutil.unpack_archive(sample, path)
except Exception as exc:
SHARED.error(self.tr(
"Failed to create a new example project."
), exc=exc)
SHARED.error(self.tr("Failed to create a new example project."), exc=exc)
return False
else:
SHARED.error(self.tr(
"Failed to create a new example project. "

View File

@@ -6,7 +6,7 @@ File History:
Created: 2022-12-01 [2.1b1] NWBuildDocument
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -25,8 +25,8 @@ from __future__ import annotations
import logging
from typing import Iterable
from pathlib import Path
from collections.abc import Iterable
from PyQt5.QtGui import QFont, QFontInfo
@@ -248,8 +248,8 @@ class NWBuildDocument:
def _setupBuild(self, bldObj: Tokenizer) -> dict:
"""Configure the build object."""
# Get Settings
textFont = self._build.getStr("format.textFont")
textSize = self._build.getInt("format.textSize")
textFont = self._build.getStr("format.textFont")
textSize = self._build.getInt("format.textSize")
fontFamily = textFont or CONFIG.textFont
bldFont = QFont(fontFamily, textSize)
@@ -284,6 +284,9 @@ class NWBuildDocument:
if isinstance(bldObj, ToOdt):
bldObj.setColourHeaders(self._build.getBool("odt.addColours"))
bldObj.setLanguage(self._project.data.language)
bldObj.setHeaderFormat(
self._build.getStr("odt.pageHeader"), self._build.getInt("odt.pageCountOffset")
)
scale = nwLabels.UNIT_SCALE.get(self._build.getStr("format.pageUnit"), 1.0)
pW, pH = nwLabels.PAPER_SIZE.get(self._build.getStr("format.pageSize"), (-1.0, -1.0))

View File

@@ -6,7 +6,7 @@ File History:
Created: 2018-09-29 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -52,7 +52,7 @@ class NWDocument:
def __init__(self, project: NWProject, tHandle: str | None) -> None:
self._project = project
self._project = project
self._item = None # The currently open item
self._handle = None # The handle of the currently open item
@@ -284,12 +284,12 @@ class NWDocument:
"""Parse the document meta tag and return the name, parent,
class and layout meta values.
"""
theName = self._docMeta.get("name", "")
theParent = self._docMeta.get("parent", None)
theClass = self._docMeta.get("class", None)
theLayout = self._docMeta.get("layout", None)
name = self._docMeta.get("name", "")
parent = self._docMeta.get("parent", None)
itemClass = self._docMeta.get("class", None)
itemLayout = self._docMeta.get("layout", None)
return theName, theParent, theClass, theLayout
return name, parent, itemClass, itemLayout
def getError(self) -> str:
"""Return the last recorded exception."""

View File

@@ -11,7 +11,7 @@ Created: 2022-05-29 [2.0rc1] TagsIndex
Created: 2022-05-29 [2.0rc1] ItemIndex
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -32,8 +32,9 @@ import json
import logging
from time import time
from typing import TYPE_CHECKING, ItemsView, Iterable, Iterator
from typing import TYPE_CHECKING
from pathlib import Path
from collections.abc import ItemsView, Iterable, Iterator
from novelwriter import SHARED
from novelwriter.enum import nwComment, nwItemClass, nwItemType, nwItemLayout
@@ -122,8 +123,8 @@ class NWIndex:
for nwItem in self._project.tree:
if nwItem.isFileType():
tHandle = nwItem.itemHandle
theDoc = self._project.storage.getDocument(tHandle)
self.scanText(tHandle, theDoc.readDocument() or "", blockSignal=True)
doc = self._project.storage.getDocument(tHandle)
self.scanText(tHandle, doc.readDocument() or "", blockSignal=True)
self._indexBroken = False
SHARED.indexSignalProxy({"event": "buildIndex"})
return
@@ -148,8 +149,8 @@ class NWIndex:
"""
if tHandle and self._project.tree.checkType(tHandle, nwItemType.FILE):
logger.debug("Re-indexing item '%s'", tHandle)
theDoc = self._project.storage.getDocument(tHandle)
self.scanText(tHandle, theDoc.readDocument() or "")
doc = self._project.storage.getDocument(tHandle)
self.scanText(tHandle, doc.readDocument() or "")
return True
return False
@@ -420,10 +421,10 @@ class NWIndex:
return
if tBits[0] == nwKeyWords.TAG_KEY:
tagName = tBits[1]
self._tagsIndex.add(tagName, tHandle, sTitle, itemClass)
self._itemIndex.setHeadingTag(tHandle, sTitle, tagName)
tags[tagName.lower()] = True
tagKey, displayName = self.parseValue(tBits[1])
self._tagsIndex.add(tagKey, displayName, tHandle, sTitle, itemClass.name)
self._itemIndex.setHeadingTag(tHandle, sTitle, tagKey)
tags[tagKey.lower()] = True
else:
self._itemIndex.addHeadingRef(tHandle, sTitle, tBits[1:], tBits[0])
@@ -471,10 +472,8 @@ class NWIndex:
return True, tBits, tPos
def checkThese(self, tBits: list[str], nwItem: NWItem) -> list[bool]:
"""Check the tags against the index to see if they are valid
tags. This is needed for syntax highlighting.
"""
def checkThese(self, tBits: list[str], tHandle: str) -> list[bool]:
"""Check tags against the index to see if they are valid."""
nBits = len(tBits)
isGood = [False]*nBits
if nBits == 0:
@@ -487,20 +486,27 @@ class NWIndex:
# For a tag, only the first value is accepted, the rest are ignored
if tBits[0] == nwKeyWords.TAG_KEY and nBits > 1:
if tBits[1] in self._tagsIndex:
isGood[1] = self._tagsIndex.tagHandle(tBits[1]) == nwItem.itemHandle
check, _ = self.parseValue(tBits[1])
if check in self._tagsIndex:
isGood[1] = self._tagsIndex.tagHandle(check) == tHandle
else:
isGood[1] = True
return isGood
# If we're still here, we check that the references exist
# Class references cannot have the | symbol in them
refKey = nwKeyWords.KEY_CLASS[tBits[0]].name
for n in range(1, nBits):
if tBits[n] in self._tagsIndex:
isGood[n] = self._tagsIndex.tagClass(tBits[n]) == refKey
if (aBit := tBits[n]) in self._tagsIndex:
isGood[n] = self._tagsIndex.tagClass(aBit) == refKey and "|" not in aBit
return isGood
def parseValue(self, text: str) -> tuple[str, str]:
"""Parse a single value into a name and display part."""
name, _, display = text.partition("|")
return name.rstrip(), display.lstrip()
##
# Extract Data
##
@@ -517,28 +523,31 @@ class NWIndex:
return None
def novelStructure(
self, rootHandle: str | None = None, skipExcl: bool = True
self, rootHandle: str | None = None, activeOnly: bool = True
) -> Iterator[tuple[str, str, str, IndexHeading]]:
"""Iterate over all titles in the novel, in the correct order as
they appear in the tree view and in the respective document
files, but skipping all note files.
"""
structure = self._itemIndex.iterNovelStructure(rHandle=rootHandle, skipExcl=skipExcl)
structure = self._itemIndex.iterNovelStructure(rHandle=rootHandle, activeOnly=activeOnly)
for tHandle, sTitle, hItem in structure:
yield f"{tHandle}:{sTitle}", tHandle, sTitle, hItem
return
def getNovelWordCount(self, skipExcl: bool = True) -> int:
"""Count the number of words in the novel project."""
wCount = 0
for _, _, hItem in self._itemIndex.iterNovelStructure(skipExcl=skipExcl):
wCount += hItem.wordCount
return wCount
def getNovelWordCount(self, rootHandle: str | None = None, activeOnly: bool = True) -> int:
"""Count the number of words in one or all novel roots."""
return sum(hItem.wordCount for _, _, hItem in self._itemIndex.iterNovelStructure(
rHandle=rootHandle, activeOnly=activeOnly
))
def getNovelTitleCounts(self, skipExcl: bool = True) -> list[int]:
"""Count the number of titles in the novel project."""
def getNovelTitleCounts(
self, rootHandle: str | None = None, activeOnly: bool = True
) -> list[int]:
"""Count the number of titles in one or all novel roots."""
hCount = [0, 0, 0, 0, 0]
for _, _, hItem in self._itemIndex.iterNovelStructure(skipExcl=skipExcl):
for _, _, hItem in self._itemIndex.iterNovelStructure(
rHandle=rootHandle, activeOnly=activeOnly
):
iLevel = nwHeaders.H_LEVEL.get(hItem.level, 0)
hCount[iLevel] += 1
return hCount
@@ -551,14 +560,14 @@ class NWIndex:
return 0
def getTableOfContents(
self, rHandle: str | None, maxDepth: int, skipExcl: bool = True
self, rHandle: str | None, maxDepth: int, activeOnly: bool = True
) -> list[tuple[str, int, str, int]]:
"""Generate a table of contents up to a maximum depth."""
tOrder = []
tData = {}
pKey = None
for tHandle, sTitle, hItem in self._itemIndex.iterNovelStructure(
rHandle=rHandle, skipExcl=skipExcl
rHandle=rHandle, activeOnly=activeOnly
):
tKey = f"{tHandle}:{sTitle}"
iLevel = nwHeaders.H_LEVEL.get(hItem.level, 0)
@@ -612,9 +621,18 @@ class NWIndex:
for refType in refTypes:
if refType in tRefs:
tRefs[refType].append(self._tagsIndex.tagName(aTag))
return tRefs
def getReferenceForHeader(self, tHandle: str, nHead: int, keyClass: str) -> list[str]:
"""Get the display names for a tags class for insertion into a
heading by one of the build classes.
"""
if iItem := self._itemIndex[tHandle]:
if hItem := iItem[f"T{nHead:04d}"]:
hRefs = [k for k, v in hItem.references.items() if keyClass in v]
return [self._tagsIndex.tagDisplay(k) for k in hRefs]
return []
def getBackReferenceList(self, tHandle: str) -> dict[str, tuple[str, IndexHeading]]:
"""Build a dict of files referring back to our file."""
if tHandle is None or tHandle not in self._itemIndex:
@@ -646,12 +664,15 @@ class NWIndex:
"""Return all tags based on itemClass."""
return self._tagsIndex.filterTagNames(itemClass.name)
def getTagsData(self) -> Iterator[tuple[str, str, str, IndexItem | None, IndexHeading | None]]:
def getTagsData(
self, activeOnly: bool = True
) -> Iterator[tuple[str, str, str, IndexItem | None, IndexHeading | None]]:
"""Return all known tags."""
for tag, data in self._tagsIndex.items():
iItem = self._itemIndex[data.get("handle")]
hItem = None if iItem is None else iItem[data.get("heading")]
yield tag, data.get("name", ""), data.get("class", ""), iItem, hItem
if not activeOnly or (iItem and iItem.item.isActive):
yield tag, data.get("name", ""), data.get("class", ""), iItem, hItem
return
def getSingleTag(self, tagKey: str) -> tuple[str, str, IndexItem | None, IndexHeading | None]:
@@ -709,17 +730,26 @@ class TagsIndex:
"""Return a dictionary view of all tags."""
return self._tags.items()
def add(self, tagKey: str, tHandle: str, sTitle: str, itemClass: nwItemClass) -> None:
def add(self, tagKey: str, displayName: str, tHandle: str,
sTitle: str, className: str) -> None:
"""Add a key to the index and set all values."""
self._tags[tagKey.lower()] = {
"name": tagKey, "handle": tHandle, "heading": sTitle, "class": itemClass.name
"name": tagKey,
"display": displayName or tagKey,
"handle": tHandle,
"heading": sTitle,
"class": className,
}
return
def tagName(self, tagKey: str) -> str:
"""Get the display name of a given tag."""
"""Get the name of a given tag."""
return self._tags.get(tagKey.lower(), {}).get("name", "")
def tagDisplay(self, tagKey: str) -> str:
"""Get the display name of a given tag."""
return self._tags.get(tagKey.lower(), {}).get("display", "")
def tagHandle(self, tagKey: str) -> str | None:
"""Get the handle of a given tag."""
return self._tags.get(tagKey.lower(), {}).get("handle", None)
@@ -754,27 +784,30 @@ class TagsIndex:
if not isinstance(data, dict):
raise ValueError("tagsIndex is not a dict")
for tagKey, tagData in data.items():
if not isinstance(tagKey, str):
raise ValueError("tagsIndex keys must be a strings")
if "name" not in tagData:
raise KeyError("A tagIndex item is missing a name entry")
if "handle" not in tagData:
raise KeyError("A tagIndex item is missing a handle entry")
if "heading" not in tagData:
raise KeyError("A tagIndex item is missing a heading entry")
if "class" not in tagData:
raise KeyError("A tagIndex item is missing a class entry")
if tagData["name"].lower() != tagKey:
raise ValueError("tagsIndex name must match key")
if not isHandle(tagData["handle"]):
for key, entry in data.items():
if not isinstance(key, str):
raise ValueError("tagsIndex keys must be a string")
if not isinstance(entry, dict):
raise ValueError("tagsIndex entry is not a dict")
name = entry.get("name")
display = entry.get("display")
handle = entry.get("handle")
heading = entry.get("heading")
className = entry.get("class")
if not isinstance(name, str):
raise ValueError("tagsIndex name is not a string")
if not isinstance(display, str):
raise ValueError("tagsIndex display is not a string")
if not isHandle(handle):
raise ValueError("tagsIndex handle must be a handle")
if not isTitleTag(tagData["heading"]):
if not isTitleTag(heading):
raise ValueError("tagsIndex heading must be a title tag")
if not isItemClass(tagData["class"]):
if not isItemClass(className):
raise ValueError("tagsIndex handle must be an nwItemClass")
self._tags = data
self.add(name, display, handle, heading, className)
return
@@ -848,7 +881,7 @@ class ItemIndex:
return
def iterNovelStructure(
self, rHandle: str | None = None, skipExcl: bool = False
self, rHandle: str | None = None, activeOnly: bool = False
) -> Iterable[tuple[str, str, IndexHeading]]:
"""Iterate over all items and headers in the novel structure for
a given root handle, or for all if root handle is None.
@@ -856,7 +889,7 @@ class ItemIndex:
for tItem in self._project.tree:
if tItem.isNoteLayout():
continue
if skipExcl and not tItem.isActive:
if activeOnly and not tItem.isActive:
continue
tHandle = tItem.itemHandle
@@ -1159,7 +1192,7 @@ class IndexHeading:
return self._tag
@property
def references(self) -> dict:
def references(self) -> dict[str, set[str]]:
return self._refs
##

View File

@@ -6,7 +6,7 @@ File History:
Created: 2018-10-27 [0.0.1] NWItem
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -334,15 +334,33 @@ class NWItem:
def isNovelLike(self) -> bool:
"""Check if the item is of a novel-like class."""
return self._class in (nwItemClass.NOVEL, nwItemClass.ARCHIVE)
return self._class in (
nwItemClass.NOVEL,
nwItemClass.ARCHIVE,
nwItemClass.TEMPLATE,
)
def isTemplateFile(self) -> bool:
"""Check if the item is a template file."""
return self._type == nwItemType.FILE and self._class == nwItemClass.TEMPLATE
def documentAllowed(self) -> bool:
"""Check if the item is allowed to be of document layout."""
return self._class in (nwItemClass.NOVEL, nwItemClass.ARCHIVE, nwItemClass.TRASH)
return self._class in (
nwItemClass.NOVEL,
nwItemClass.ARCHIVE,
nwItemClass.TEMPLATE,
nwItemClass.TRASH,
)
def isInactiveClass(self) -> bool:
"""Check if the item is in an inactive class."""
return self._class in (nwItemClass.NO_CLASS, nwItemClass.ARCHIVE, nwItemClass.TRASH)
return self._class in (
nwItemClass.NO_CLASS,
nwItemClass.ARCHIVE,
nwItemClass.TEMPLATE,
nwItemClass.TRASH,
)
def isRootType(self) -> bool:
"""Check if item is a root item."""

View File

@@ -7,7 +7,7 @@ Created: 2019-10-21 [0.3.1] OptionState
Rewritten: 2020-02-19 [0.4.5] OptionState
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
Copyright 2018–2024, 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
@@ -42,7 +42,7 @@ logger = logging.getLogger(__name__)
NWEnum = TypeVar("NWEnum", bound=Enum)
VALID_MAP = {
VALID_MAP: dict[str, set[str]] = {
"GuiWritingStats": {
"winWidth", "winHeight", "widthCol0", "widthCol1", "widthCol2",
"widthCol3", "sortCol", "sortOrder", "incNovel", "incNotes",
@@ -53,10 +53,6 @@ VALID_MAP = {
"GuiProjectSettings": {
"winWidth", "winHeight", "replaceColW", "statusColW", "importColW",
},
"GuiProjectDetails": {
"winWidth", "winHeight", "widthCol0", "widthCol1", "widthCol2",
"widthCol3", "widthCol4", "wordsPerPage", "countFrom", "clearDouble",
},
"GuiWordList": {"winWidth", "winHeight"},
"GuiNovelView": {"lastCol", "lastColSize"},
"GuiBuildSettings": {
@@ -70,8 +66,13 @@ VALID_MAP = {
"winWidth", "winHeight", "fmtWidth", "sumWidth",
},
"GuiDocViewerPanel": {
"colWidths",
}
"colWidths", "hideInactive",
},
"GuiNovelDetails": {
"winWidth", "winHeight", "widthCol0", "widthCol1", "widthCol2",
"widthCol3", "widthCol4", "wordsPerPage", "countFrom", "clearDouble",
"novelRoot",
},
}

Some files were not shown because too many files have changed in this diff Show More