@@ -6,13 +6,25 @@
|
||||
|
||||
novelWriter is a markdown-like text editor designed fro writing novels and larger projects of many smaller plain text documents.
|
||||
|
||||
It is under initial development, and not all planned features are included, but it is perfectly usable in the current state.
|
||||
The documentation is available here: [novelwriter.readthedocs.io](https://novelwriter.readthedocs.io/).
|
||||
|
||||
### Note
|
||||
|
||||
The application is under initial development, and not all planned features are included.
|
||||
The core functionality is, however, in place and has been used for a while by the author and collaborators.
|
||||
|
||||
New features are being added regularly, until the core toolset is complete.
|
||||
When all planned initial features are in place, a release 1.0 will be made.
|
||||
Until then, novelWriter is in a pre-release alpha state, and should be considered experimental.
|
||||
If you do use it for real projects, please run backups frequently to avoid data losses.
|
||||
There is a built in backup feature that can pack the entire project into a zip file on close.
|
||||
Please check the documentation for further details.
|
||||
|
||||
## Implementation
|
||||
|
||||
The application is written in Python3 using Qt5 via PyQt5.
|
||||
It is developed on Linux, but it should in principle work fine on other operating systems as well as long as dependencies are met.
|
||||
|
||||
The documentation is available here: [novelwriter.readthedocs.io](https://novelwriter.readthedocs.io/).
|
||||
|
||||
The application can be started from the source folder with the command:
|
||||
```
|
||||
./novelWriter.py
|
||||
@@ -22,7 +34,7 @@ It also takes a few parameters for debugging and such, which can be listed with
|
||||
|
||||
There are no launcher icons yet.
|
||||
Consult your operating system documentation for how to make those.
|
||||
I will add those later, and would appreciate any assistance from people working on Windows and MacOS as I don't use either of those operating systems.
|
||||
These will be added at some point, and I would appreciate any assistance from people working on Windows and MacOS as I don't use either of those operating systems.
|
||||
|
||||
## Dependencies
|
||||
|
||||
@@ -38,6 +50,7 @@ These are optional, but recommended:
|
||||
* `python3-enchant` for spell checking
|
||||
* `python3-pycountry` for translating language codes to language names
|
||||
* `python3-latexcodec` for escaping unicode characters in LaTeX export
|
||||
* `python3-pandoc` for additional exports to Word, Open Office, eBooks, etc.
|
||||
|
||||
Alternatively, the packages can be installed with `pip` by running
|
||||
```
|
||||
@@ -53,13 +66,15 @@ python3 -m pip install lxml
|
||||
python3 -m pip install pyenchant
|
||||
python3 -m pip install pycountry
|
||||
python3 -m pip install latexcodec
|
||||
python3 -m pip install pypandoc
|
||||
```
|
||||
This may be necessary on Windows, as `pyenchant` may cause problems.
|
||||
On Windows,`pyenchant` may cause problems.
|
||||
I'm looking for a good alternative for spell checking.
|
||||
|
||||
Note: On Windows, make sure Python3 is in your PATH if you want to launch novelWriter from command line.
|
||||
You can also right click the `novelWriter.py` file, create a shortcut.
|
||||
Then right click again, select "Properties" and change the target to your python executable and `novelWriter.py`.
|
||||
You can also right click the `novelWriter.py` file, create a shortcut, then right click again, select "Properties" and change the target to your python executable and `novelWriter.py`.
|
||||
|
||||
It should look something like this:
|
||||
```
|
||||
C:\...\AppData\Local\Programs\Python\Python38\python.exe novelWriter.py
|
||||
```
|
||||
|
||||
@@ -105,3 +105,11 @@ def splitVersionNumber(vString):
|
||||
vInt = vMajor*10000 + vMinor*100 + vPatch
|
||||
|
||||
return [vMajor, vMinor, vPatch, vInt]
|
||||
|
||||
def packageRefURL(packName):
|
||||
from nw.constants import nwDependencies
|
||||
if packName in nwDependencies.PACKS.keys():
|
||||
return "<a href=\"%s\">%s</a>" % (
|
||||
nwDependencies.PACKS[packName]["site"], packName
|
||||
)
|
||||
return packName
|
||||
|
||||
+2
-2
@@ -74,11 +74,11 @@ class Config:
|
||||
## Text Editor
|
||||
self.textFont = None
|
||||
self.textSize = 12
|
||||
self.textFixedW = True
|
||||
self.textFixedW = False
|
||||
self.textWidth = 600
|
||||
self.textMargin = 40
|
||||
self.tabWidth = 40
|
||||
self.doJustify = True
|
||||
self.doJustify = False
|
||||
self.autoSelect = True
|
||||
self.doReplace = True
|
||||
self.doReplaceSQuote = True
|
||||
|
||||
@@ -80,6 +80,42 @@ class nwLabels():
|
||||
|
||||
# END Class nwLabels
|
||||
|
||||
class nwDependencies():
|
||||
"""Python package dependencies and their reference links.
|
||||
"""
|
||||
PACKS = {
|
||||
"pyqt5" : {
|
||||
"site" : "",
|
||||
"docs" : "",
|
||||
},
|
||||
"appdirs" : {
|
||||
"site" : "",
|
||||
"docs" : "",
|
||||
},
|
||||
"lxml" : {
|
||||
"site" : "",
|
||||
"docs" : "",
|
||||
},
|
||||
"pyenchant" : {
|
||||
"site" : "",
|
||||
"docs" : "",
|
||||
},
|
||||
"pycountry" : {
|
||||
"site" : "",
|
||||
"docs" : "",
|
||||
},
|
||||
"latexcodec" : {
|
||||
"site" : "https://pypi.org/project/latexcodec/",
|
||||
"docs" : "https://latexcodec.readthedocs.io/en/latest/",
|
||||
},
|
||||
"pypandoc" : {
|
||||
"site" : "https://pypi.org/project/pypandoc/",
|
||||
"docs" : "https://pypi.org/project/pypandoc/",
|
||||
},
|
||||
}
|
||||
|
||||
# END Class nwDependencies
|
||||
|
||||
class nwQuotes():
|
||||
"""Allowed quotation marks.
|
||||
Source: https://en.wikipedia.org/wiki/Quotation_mark
|
||||
|
||||
+9
-4
@@ -31,6 +31,7 @@ from nw.convert.file.html import HtmlFile
|
||||
from nw.convert.file.markdown import MarkdownFile
|
||||
from nw.convert.file.latex import LaTeXFile
|
||||
from nw.convert.file.concat import ConcatFile
|
||||
from nw.common import packageRefURL
|
||||
from nw.constants import nwFiles
|
||||
from nw.enum import nwItemType, nwAlert
|
||||
|
||||
@@ -191,9 +192,11 @@ class GuiExport(QDialog):
|
||||
# Check that encoding was successful
|
||||
if outFile.texCodecFail:
|
||||
self.theParent.makeAlert((
|
||||
"Failed to escape unicode characters while writing LaTeX file. "
|
||||
"The genrated .tex file may not build properly. "
|
||||
"Make sure the python package 'latexcodec' is installed and working."
|
||||
"Failed to escape unicode characters while writing LaTeX file. The generated "
|
||||
".tex file may not build properly. Make sure the python package '{package:s}' "
|
||||
"is installed and working."
|
||||
).format(
|
||||
package = packageRefURL("latexcodec")
|
||||
), nwAlert.WARN)
|
||||
|
||||
if eFormat != GuiExportMain.FMT_PDOC:
|
||||
@@ -227,8 +230,10 @@ class GuiExport(QDialog):
|
||||
import pypandoc
|
||||
except:
|
||||
self.theParent.makeAlert((
|
||||
"Could not load the 'pypandoc' package. "
|
||||
"Could not load the '{package:s}' package. "
|
||||
"Make sure it is installed, and try again."
|
||||
).format(
|
||||
package = packageRefURL("pypandoc")
|
||||
), nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
|
||||
+8
-8
@@ -76,7 +76,7 @@ class GuiMainMenu(QMenuBar):
|
||||
for n in range(len(self.mainConf.recentList)):
|
||||
recentProject = self.mainConf.recentList[n]
|
||||
if recentProject == "": continue
|
||||
menuItem = QAction("%d: %s" % (n,recentProject), self.projMenu)
|
||||
menuItem = QAction("%s" % recentProject, self.projMenu)
|
||||
menuItem.triggered.connect(lambda menuItem, n=n : self.openRecentProject(menuItem, n))
|
||||
self.recentMenu.addAction(menuItem)
|
||||
return
|
||||
@@ -216,13 +216,13 @@ class GuiMainMenu(QMenuBar):
|
||||
# Project > New Root
|
||||
rootMenu = self.projMenu.addMenu("Create Root Folder")
|
||||
self.rootItems = {}
|
||||
self.rootItems[nwItemClass.NOVEL] = QAction("Novel Root", rootMenu)
|
||||
self.rootItems[nwItemClass.PLOT] = QAction("Plot Root", rootMenu)
|
||||
self.rootItems[nwItemClass.CHARACTER] = QAction("Character Root", rootMenu)
|
||||
self.rootItems[nwItemClass.WORLD] = QAction("Location Root", rootMenu)
|
||||
self.rootItems[nwItemClass.TIMELINE] = QAction("Timeline Root", rootMenu)
|
||||
self.rootItems[nwItemClass.OBJECT] = QAction("Object Root", rootMenu)
|
||||
self.rootItems[nwItemClass.CUSTOM] = QAction("Custom Root", rootMenu)
|
||||
self.rootItems[nwItemClass.NOVEL] = QAction("Novel Root", rootMenu)
|
||||
self.rootItems[nwItemClass.PLOT] = QAction("Plot Root", rootMenu)
|
||||
self.rootItems[nwItemClass.CHARACTER] = QAction("Character Root", rootMenu)
|
||||
self.rootItems[nwItemClass.WORLD] = QAction("Location Root", rootMenu)
|
||||
self.rootItems[nwItemClass.TIMELINE] = QAction("Timeline Root", rootMenu)
|
||||
self.rootItems[nwItemClass.OBJECT] = QAction("Object Root", rootMenu)
|
||||
self.rootItems[nwItemClass.CUSTOM] = QAction("Custom Root", rootMenu)
|
||||
nCount = 0
|
||||
for itemClass in self.rootItems.keys():
|
||||
nCount += 1 # This forces the lambdas to be unique
|
||||
|
||||
@@ -4,3 +4,4 @@ lxml
|
||||
pyenchant
|
||||
pycountry
|
||||
latexcodec
|
||||
pypandoc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Main]
|
||||
timestamp = 2019-06-27 20:26:43
|
||||
timestamp = 2019-10-29 10:40:19
|
||||
theme = default
|
||||
syntax = default_light
|
||||
|
||||
@@ -16,11 +16,11 @@ autosavedoc = 30
|
||||
[Editor]
|
||||
textfont = None
|
||||
textsize = 12
|
||||
fixedwidth = True
|
||||
fixedwidth = False
|
||||
width = 600
|
||||
margin = 40
|
||||
tabwidth = 40
|
||||
justify = True
|
||||
justify = False
|
||||
autoselect = True
|
||||
autoreplace = True
|
||||
repsquotes = True
|
||||
|
||||
Reference in New Issue
Block a user