@@ -0,0 +1,598 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>novelWriter Help</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>novelWriter Help</h1>
|
||||
|
||||
<a name="Content"></a>
|
||||
<h3>Content:</h3>
|
||||
<ul>
|
||||
<li><a href="#Intro">1. Introduction</a></li>
|
||||
<li><a href="#Proj">2. Novel Projects</a></li>
|
||||
<ul>
|
||||
<li><a href="#Proj_Structure">2.1 Project Structure</a></li>
|
||||
<li><a href="#Proj_Settings">2.2 Project Settings</a></li>
|
||||
<li><a href="#Proj_Documents">2.3 Writing Files</a></li>
|
||||
</ul>
|
||||
<li><a href="#Novel">3. Novel Structure</a></li>
|
||||
<ul>
|
||||
<li><a href="#Novel_Headings">3.1 Importance of Headings</a></li>
|
||||
<li><a href="#Novel_Refs">3.2 Tag References</a></li>
|
||||
<li><a href="#Novel_Files">3.3 Novel File Layout</a></li>
|
||||
</ul>
|
||||
<li><a href="#Notes">4. Supporting Files (Notes)</a></li>
|
||||
<ul>
|
||||
<li><a href="#Notes_Tags">4.1 File Tags</a></li>
|
||||
</ul>
|
||||
<li><a href="#GUI">5. User Interface</a></li>
|
||||
<ul>
|
||||
<li><a href="#GUI_Markdown">5.1 Markdown Format</a></li>
|
||||
<li><a href="#GUI_Shortcuts">5.2 Keyboard Shortcuts</a></li>
|
||||
</ul>
|
||||
<li><a href="#Code">6. Technical Information</a></li>
|
||||
<ul>
|
||||
<li><a href="#Code_Project">6.1 How Data is Stored</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<a name="Intro"></a>
|
||||
<h2>1. Introduction</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<a name="Proj"></a>
|
||||
<h2>2. Novel Projects</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>A novelWriter project requires a dedicated folder for storing its files. See the
|
||||
<a href="#Code">Technical Information</a> section for further details.</p>
|
||||
<p>A new project can be created from the Project menu by selecting <mark>Project > New
|
||||
Project</mark>. A list of recently opened projects is also maintained and can be selected
|
||||
from the menu.</p>
|
||||
<p>The project specific settings are available in <mark>Project > Project Settings</mark>. See
|
||||
further details below.</p>
|
||||
|
||||
<a name="Proj_Structure"></a>
|
||||
<h3>2.1 Project Structure</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>Projects are structured into a set of root folders in the left side tree view panel.</p>
|
||||
<p>The core novel files go into a root folder of type <mark>Novel</mark>. Other supporting files
|
||||
go into root folders of types <mark>Plot</mark>, <mark>Characters</mark>,
|
||||
<mark>Locations</mark>, <mark>Timeline</mark>, <mark>Objects</mark> or <mark>Custom</mark>.
|
||||
These other root folder types are intended for your notes on the various elements of your
|
||||
story. Using these are of course entirely optional.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><mark>Novel</mark></td>
|
||||
<td>The root folder of all text that goes into the final novel. This class of files have
|
||||
other rules and features than other files in the project. See the
|
||||
<a href="#Novel">Novel Structure</a> section for more details.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Plot</mark></td>
|
||||
<td>This is the root folder where main plots can be outlined. It is optional, but adding
|
||||
at least dummy files can be useful in order to generate the timeline view.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Characters</mark></td>
|
||||
<td>Character files go in this root folder. These are especially important if one wants
|
||||
to use the timeline view to see which character appears where and which part of the
|
||||
story is told from a specific character's point-of-view.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Locations</mark></td>
|
||||
<td>Location is for various scene locations that one wants to track in the timeline
|
||||
view if that applies to the story.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Timeline</mark></td>
|
||||
<td>If the story jumps in time within the same plot, this class of files can be used to
|
||||
track this.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Objects</mark></td>
|
||||
<td>Important objects in the story can be tracked here, and connected to the timeline as
|
||||
well.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Custom</mark></td>
|
||||
<td>the custom root folder can be used for tracking anything else not covered by the
|
||||
above options.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Deleted files will be moved into a special <mark>TRASH</mark> root folder. Currently, these
|
||||
files cannot be permanently deleted from the project.</p>
|
||||
|
||||
<h4>Orphaned Documents</h4>
|
||||
<p>In the event the editor crashes or otherwise exits without saving the project state, files
|
||||
that have been added to the project tree and are saved to disk will appear in a special
|
||||
"Orphaned Items" root folder next time the application is started. These orphaned files will
|
||||
not have any meta data associated with them, so the title and other information has to be
|
||||
set again, and the files moved back to the correct location in the project.</p>
|
||||
|
||||
<h4>Using Project Folders</h4>
|
||||
<p>Folders, aside from root folders, have no structural significance to the project. They are
|
||||
there purely as a way for the user to organise the files in meaningful sections and to be
|
||||
able to close them in the tree view. When processing the files in the novel, the folders are
|
||||
ignored.</p>
|
||||
|
||||
<a name="Proj_Settings"></a>
|
||||
<h3>2.2 Project Settings</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>The project settings can be accessed from the <mark>Project > Project Settings</mark> menu
|
||||
entry. This will open a dialog box.</p>
|
||||
|
||||
<h4>Settings Tab</h4>
|
||||
<p>The Settings tab holds the project title and author settings. <em>Working Title</em> can be
|
||||
set to a different title than the <em>Book Title</em>. The difference between them is simply
|
||||
that the Working Title is used for the GUI (main window title) and when the export features
|
||||
are added can optionally be printed to the cover sheet. The Book Title, on the other hand,
|
||||
will only be printed to the title page on export.</p>
|
||||
<p>The <em>Book Authors</em> text box takes one author per line. The line breaks matter in that
|
||||
this is converted to a list for later correct formatting.</p>
|
||||
|
||||
<h4>Status Tab</h4>
|
||||
<p>Each file of type <mark>NOVEL</mark> can be given a status level, signified by a coloured
|
||||
icon. These are purely there for the user's convenience, and you are not required to use
|
||||
them for any other feature to work. The intention is to use this list to set what stage of
|
||||
writing you are on, although you can in principle make them whatever you want.</p>
|
||||
<p>Note that status levels currently in use by a file cannot be deleted.</p>
|
||||
|
||||
<h4>Importance Tab</h4>
|
||||
<p>Each file of types <mark>PLOT</mark>, <mark>CHARACTER</mark>, <mark>WORLD</mark>,
|
||||
<mark>TIMELINE</mark>, <mark>OBJECT</mark> or <mark>CUSTOM</mark> can be given an importance
|
||||
level, signified by a coloured icon like for status level. These are also purely there for
|
||||
the user's convenience, and you are not required to use them for any other feature to work.
|
||||
The intention is to use this list to set how important the character, plot element, or
|
||||
otherwise, is for the story. Again, these can in principle be used for whatever you want.
|
||||
<p>Note that importance levels currently in use by a file cannot be deleted.</p>
|
||||
|
||||
<h4>Auto-Replace Tab</h4>
|
||||
<p>A set of automatically replaced keywords can be added in this tab. The keywords in the left
|
||||
column wile be replaced by the text in the right column when documents are opened in the
|
||||
viewer. This will also be applied to exports when the feature is added.</p>
|
||||
<p>Note that a keyword cannot contain any spaces. The angle brackets are dded by default, and
|
||||
when used in the text are a part of the keyword to be replaced. This is to ensure that parts
|
||||
of the text isn't unintentionally replaced by the content of the list.</p>
|
||||
|
||||
<a name="Proj_Documents"></a>
|
||||
<h2>2.3 Writing Files</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>New document files can be created from the Document menu, or by pressing <mark>Ctrl+N</mark>
|
||||
while in the tree view pane. This will create a new, empty file, and open the item settings
|
||||
dialog where the filename and various other settings can be set. This dialog can also be
|
||||
opened again later from either the menu, <mark>Project > Edit item</mark>, or by pressing
|
||||
<mark>Ctrl+E</mark> or <mark>F2</mark> with the item selected.</p>
|
||||
<p>The different classes of documents have some restrictions.</p>
|
||||
|
||||
<a name="Novel"></a>
|
||||
<h2>3. Novel Structure</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>This section concerns files under the <mark>Novel</mark> type root folder. There are some
|
||||
restrictions and features that only applies to these type of files.</p>
|
||||
|
||||
<a name="Novel_Headings"></a>
|
||||
<h3>3.1 Importance of Headings</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>Subfolders under root folders have no impact on the structure of the novel itself. The
|
||||
structure is instead dictated by the heading level. Four levels of headings are supported,
|
||||
signified by the number of hashes preceding the title. See the
|
||||
<a href="#GUI_Markdown">Markdown</a> section.</p>
|
||||
<p>The header levels are not only important when generating the exported novel file, but is also
|
||||
used by the indexer and timeline view. Each heading starts a new region where new References
|
||||
to tags can be set, and will show up as a new row in the timeline view.</p>
|
||||
<p>The different header levels are interpreted as specific section types of the novel.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><mark># Header1</mark></td>
|
||||
<td>Header level 1 signifies that the text refers to either the novel title or the
|
||||
name of a top level partition.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>## Header2</mark></td>
|
||||
<td>Header level 2 signifies a chapter level partition.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>### Header3</mark></td>
|
||||
<td>Header level 3 signifies a scene level partition.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>#### Header4</mark></td>
|
||||
<td>Header level 4 signifies a sub-scene level partition.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="Novel_Refs"></a>
|
||||
<h3>3.2 Tag References</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>Each section started by a heading can contain references to tags set in the supporting files
|
||||
of the project. See the <a href="#Notes_Tags">File Tags</a> section.</p>
|
||||
<p>The references are gathered by the indexer and used to generate the timeline view of how the
|
||||
different parts of the novel are connected.</p>
|
||||
<p>References are set as keyword and a list of corresponding tags. The valid keywords are listed
|
||||
below. The format of such a line is <mark>@keyword: value1, [value2] ... [valueN]</mark>.
|
||||
Note that not all keywords allow multiple values.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><mark>@pov</mark></td>
|
||||
<td>The point-of-view character for the current section. The target must be a note tag
|
||||
in the character root folder. Only one value is accepted. further values are
|
||||
ignored.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>@char</mark></td>
|
||||
<td>Other characters in the current section. The target must be a note tag in the
|
||||
character root folder. Multiple values are allowed. This should not include the
|
||||
point-of-view character.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>@plot</mark></td>
|
||||
<td>The plot timelines touched by the current section. The target must be a note tag in
|
||||
the plot root folder. Multiple values are allowed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>@time</mark></td>
|
||||
<td>The timelines touched by the current section. The target must be a note tag in the
|
||||
timeline root folder. Multiple values are allowed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>@location</mark></td>
|
||||
<td>The location the current section takes place in. The target must be a note tag in
|
||||
the locations root folder. Multiple values are allowed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>@object</mark></td>
|
||||
<td>Objects present in the current section. The target must be a note tag in the object
|
||||
root folder. Multiple values are allowed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>@custom</mark></td>
|
||||
<td>Custom references in the current section. The target must be a note tag in the
|
||||
custom root folder. Multiple values are allowed.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>the syntax highlighter will alert the user that only the correct keywords are used, and that
|
||||
the tags referenced exist. If the index of defined tags is out of date, press
|
||||
<mark>F9</mark> to regenerate it, or select <mark>Tools > Rebuild Indices</mark> from the
|
||||
menu. In general, the index for a file is regenerated when a file is saved, so this
|
||||
shouldn't normally be necessary.</p>
|
||||
|
||||
<a name="Novel_Files"></a>
|
||||
<h3>3.3 Novel File Layout</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>Files that exist under the <mark>NOVEL</mark> type root folder can have a number of layouts
|
||||
set. See overview below. These layouts are currently not used for any internal feature, but
|
||||
when the export feature is added they will be important in determining how the different
|
||||
sections of the novel is formatted.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><mark>Title Page</mark></td>
|
||||
<td>The title page layout. The title should be formatted as a heading level one.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Book</mark></td>
|
||||
<td>In principle, the entire novel can be contained in a single file. In that case, use
|
||||
the Book layout on this file. The internal structure is then controlled by the
|
||||
heading levels.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Plain Page</mark></td>
|
||||
<td>A plain page is just that, It is not included into content and the heading levels
|
||||
are ignored.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Partition</mark></td>
|
||||
<td>A partition can be used to split a the novel into parts. Use a level one heading for
|
||||
this.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Chapter</mark></td>
|
||||
<td>Signifies the start of a new chapter. If the text itself is contained in scene
|
||||
files, these files should only contain the title and tag references for characters,
|
||||
plot, etc. The heading for chapters should be level two.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Un-Numbered</mark></td>
|
||||
<td>Same as Chapter, but when exporting the files and automatic chapter numbering is
|
||||
enabled, this file will not receive a number.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Scene</mark></td>
|
||||
<td>A scene file. This file should have a header of level three. Further sections can
|
||||
have headers of level four. These will not impact the overall structure, but will
|
||||
allow for setting new characters and plot references in parts of a scene if such
|
||||
granularity is needed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Note</mark></td>
|
||||
<td>A generic file that is ignored when the novel is exported. These layout is allowed
|
||||
within the Novel root folder, and is the only layout allowed for a file outside the
|
||||
Novel root folder.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="Notes"></a>
|
||||
<h2>4. Supporting Files (Notes)</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>Supporting files, or notes, are any files stored in root folders that are not the Novel root
|
||||
folder. These files are intended for summaries and outlines of the various plot elements,
|
||||
characters, locations, and so on, of the novel. These are no required, but making at least
|
||||
minimal files for each such element makes it possible to use the timeline view feature to
|
||||
see how each element intersects with each section of the novel itself.</p>
|
||||
|
||||
<a name="Notes_Tags"></a>
|
||||
<h2>4.1 File Tags</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>Each note file can have a tag associated with it, The format of a tag is
|
||||
<mark>@tag: tagname</mark>, where tagname is a unique identifier. tags can then be
|
||||
referenced in the novel files and will then show up as dots in the timeline view.</p>
|
||||
<p>The syntax highlighter will alert the user that the keyword is correctly used and that the
|
||||
tag is allowed. Duplicate tags should be detected as long as the index is up to date.</p>
|
||||
<p>The tag is the only part of these files that the application used. The rest of the file is
|
||||
there for the writer to use in whatever way they wish.</p>
|
||||
|
||||
<a name="GUI"></a>
|
||||
<h2>5. User Interface</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>The user interface is kept as simple as possible to avoid distractions. The main window
|
||||
contains a tree vew pane with the entire structure of the project, and a small details panel
|
||||
below it to display additional information.</p>
|
||||
<p>Editing a document can be done by either double-clicking on it, or hitting the return key
|
||||
when the item is selected. This will open the source editor which uses a simplified markdown
|
||||
format described in the section below.</p>
|
||||
<p>The document can also be viewed as html with all the comments and commands stripped out. To
|
||||
view a document, simply press <mark>Ctrl+R</mark> or select a file and go to <mark>Document
|
||||
> View Document</mark> in the menu. The document viewed does not need to be the same
|
||||
document currently being edited.</p>
|
||||
|
||||
<a name="GUI_Markdown"></a>
|
||||
<h3>5.1 Markdown Format</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>the document editor uses a simplified markdown format. That is, it supports basic formatting
|
||||
like bold, italics and underline, as well as four levels of headings. The formats are listed
|
||||
below.</p>
|
||||
<p>In addition to these standard markdown features, the editor also allows for comments, that is
|
||||
text that is ignored by the word counter and not exported or seen in the document viewer.
|
||||
The editor also has a minimal set of commands used for setting tags and references between
|
||||
files.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><mark># Title</mark></td>
|
||||
<td>Heading level one. The space after the # is mandatory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>## Title</mark></td>
|
||||
<td>Heading level two. The space after the # is mandatory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>### Title</mark></td>
|
||||
<td>Heading level three. The space after the # is mandatory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>#### Title</mark></td>
|
||||
<td>Heading level four. The space after the # is mandatory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>**text**</mark></td>
|
||||
<td>The text is renderred as bold text.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>_text_</mark></td>
|
||||
<td>The text is renderred as italics text.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>__text__</mark></td>
|
||||
<td>The text is renderred as underlined text.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>% text...</mark></td>
|
||||
<td>A comment. The text is not exported, seen in viewer, or counted towards word counts.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>@command: value</mark></td>
|
||||
<td>A command followed by a value, or a comma separated list of values.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="GUI_Shortcuts"></a>
|
||||
<h3>5.2 Keyboard Shortcuts</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>All features are available as keyboard shortcuts. These are as following:</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+O</mark></td>
|
||||
<td>Open a project.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+S</mark></td>
|
||||
<td>Save the current project.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+W</mark></td>
|
||||
<td>Close the current project.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+,</mark></td>
|
||||
<td>Change project settings.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+N</mark></td>
|
||||
<td>Create new folder.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+E, F2</mark></td>
|
||||
<td>If in tree view, edit a document or folder settings.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Del</mark></td>
|
||||
<td>If in tree view, move a document to trash, or delete a folder.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Q</mark></td>
|
||||
<td>Exit novelWriter.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+N</mark></td>
|
||||
<td>Create new document.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+O</mark></td>
|
||||
<td>Open selected document.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Return</mark></td>
|
||||
<td>If in tree view, open a document for editing.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+S</mark></td>
|
||||
<td>Save the current document in the editor.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+W</mark></td>
|
||||
<td>Close the current document in the editor.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+R</mark></td>
|
||||
<td>If in tree view, open a document for viewing. If in editor pane, open current document for viewing.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+R</mark></td>
|
||||
<td>Close the document view pane.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Z</mark></td>
|
||||
<td>Undo latest changes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Y</mark></td>
|
||||
<td>Redo latest undo.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+C</mark></td>
|
||||
<td>Copy selected text to clipboard.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+X</mark></td>
|
||||
<td>Cut selected text to clipboard.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+V</mark></td>
|
||||
<td>Paste text from clipboard to cursor position.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+A</mark></td>
|
||||
<td>Select all text in document.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+A</mark></td>
|
||||
<td>Select all text in current paragraph.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+1</mark></td>
|
||||
<td>Switch focus to tree view pane.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+2</mark></td>
|
||||
<td>Switch focus to document editor pane.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+3</mark></td>
|
||||
<td>Switch focus to document viewer pane.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+T</mark></td>
|
||||
<td>Show project timeline.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+B</mark></td>
|
||||
<td>Format selected text, or word under cursor, as bold.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+I</mark></td>
|
||||
<td>Format selected text, or word under cursor, as italic.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+U</mark></td>
|
||||
<td>Format selected text, or word under cursor, as underline.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+D</mark></td>
|
||||
<td>Wrap selected text, or word under cursor, in double quotes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+D</mark></td>
|
||||
<td>Wrap selected text, or word under cursor, in single quotes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+Up</mark></td>
|
||||
<td>Move item one step up in the tree view.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+Shift+Down</mark></td>
|
||||
<td>Move item one step down in the tree view.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+F7</mark></td>
|
||||
<td>Toggle spell checking.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>F7</mark></td>
|
||||
<td>Re-run spell checker.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>Ctrl+.</mark></td>
|
||||
<td>Correct word under cursor.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>F9</mark></td>
|
||||
<td>Re-build project indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><mark>F1</mark></td>
|
||||
<td>Open documentation.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="Code"></a>
|
||||
<h2>6. Technical Information</h2>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<p>This section contains details of how novelWriter stores and handles the project data.</p>
|
||||
|
||||
<a name="Code_Project"></a>
|
||||
<h3>6.1 How Data is Stored</h3>
|
||||
<p><a href="#Content">Back to top</a></p>
|
||||
|
||||
<h4>Main Project File</h4>
|
||||
<p>The project itself requires a dedicated folder for storing its files. The main project file
|
||||
is stored as an XML file with the name <mark>nwProject.nwx</mark>. This file contains all
|
||||
the meta data unique for the project. That includes project settings.</p>
|
||||
<p>If this file is lost or corrupted, the structure of the project is lost. It is important to
|
||||
keep this file backed up.</p>
|
||||
<p>The project XML file is suitable for diff tools and version control, although a timesetamp is
|
||||
set in the meta section on line 2 each time the file is saved.</p>
|
||||
|
||||
<h4>Project Documents</h4>
|
||||
<p>The project documents are saved in folders staring with <mark>data_</mark>. Each document has
|
||||
a file handle taken from the first 13 characters of a SHA256 hash of the system time. the
|
||||
documents are saved with a folder and filename derived from this hash.</p>
|
||||
<p>The reason for this is to avoid issues with file naming conventions and restrictions. The
|
||||
file name set in the tree view is only saved in the project XML file.</p>
|
||||
<p>Each document file contains a plain text version of the text from the editor. The file can in
|
||||
principle be edited in any text editor, and is suitable for diffing and version control if
|
||||
so desired.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -104,6 +104,7 @@ class Config:
|
||||
self.homePath = path.expanduser("~")
|
||||
self.appPath = path.dirname(__file__)
|
||||
self.appRoot = path.join(self.appPath,path.pardir)
|
||||
self.helpPath = path.join(self.appRoot,"help","en_GB")
|
||||
self.guiPath = path.join(self.appPath,"gui")
|
||||
self.themePath = path.join(self.appPath,"themes")
|
||||
|
||||
|
||||
+47
-9
@@ -20,6 +20,7 @@ from PyQt5.QtCore import Qt, QTimer
|
||||
from PyQt5.QtWidgets import QTextEdit, QAction, QMenu, QShortcut
|
||||
from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence
|
||||
|
||||
from nw.project.document import NWDoc
|
||||
from nw.gui.dochighlight import GuiDocHighlighter
|
||||
from nw.gui.wordcounter import WordCounter
|
||||
from nw.enum import nwDocAction, nwAlert
|
||||
@@ -28,7 +29,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class GuiDocEditor(QTextEdit):
|
||||
|
||||
def __init__(self, theParent):
|
||||
def __init__(self, theParent, theProject):
|
||||
QTextEdit.__init__(self)
|
||||
|
||||
logger.debug("Initialising DocEditor ...")
|
||||
@@ -36,10 +37,12 @@ class GuiDocEditor(QTextEdit):
|
||||
# Class Variables
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.theProject = theProject
|
||||
self.docChanged = False
|
||||
self.pwlFile = None
|
||||
self.spellCheck = False
|
||||
self.theDocument = theParent.theDocument
|
||||
self.theDocument = NWDoc(self.theProject, self.theParent)
|
||||
self.theHandle = None
|
||||
|
||||
# Document Variables
|
||||
self.charCount = 0
|
||||
@@ -69,9 +72,6 @@ class GuiDocEditor(QTextEdit):
|
||||
self.setMinimumWidth(300)
|
||||
self.setAcceptRichText(False)
|
||||
|
||||
self.clearEditor()
|
||||
self.initEditor()
|
||||
|
||||
self.theQDoc.setDocumentMargin(0)
|
||||
self.theQDoc.contentsChange.connect(self._docChange)
|
||||
|
||||
@@ -87,13 +87,29 @@ class GuiDocEditor(QTextEdit):
|
||||
self.wCounter = WordCounter(self)
|
||||
self.wCounter.finished.connect(self._updateCounts)
|
||||
|
||||
self.clearEditor()
|
||||
self.initEditor()
|
||||
|
||||
logger.debug("DocEditor initialisation complete")
|
||||
|
||||
return
|
||||
|
||||
def clearEditor(self):
|
||||
|
||||
self.theDocument.clearDocument()
|
||||
self.setReadOnly(True)
|
||||
self.clear()
|
||||
self.wcTimer.stop()
|
||||
|
||||
self.theHandle = None
|
||||
self.charCount = 0
|
||||
self.wordCount = 0
|
||||
self.paraCount = 0
|
||||
self.lastEdit = 0
|
||||
self.hasSelection = False
|
||||
|
||||
self.setDocumentChanged(False)
|
||||
|
||||
return True
|
||||
|
||||
def initEditor(self):
|
||||
@@ -114,6 +130,7 @@ class GuiDocEditor(QTextEdit):
|
||||
return True
|
||||
|
||||
def loadText(self, tHandle):
|
||||
|
||||
self.hLight.setHandle(tHandle)
|
||||
self.setPlainText(self.theDocument.openDocument(tHandle))
|
||||
self.setCursorPosition(self.theDocument.theItem.cursorPos)
|
||||
@@ -122,6 +139,27 @@ class GuiDocEditor(QTextEdit):
|
||||
self.wcTimer.start()
|
||||
self.setDocumentChanged(False)
|
||||
self.setReadOnly(False)
|
||||
self.theHandle = tHandle
|
||||
|
||||
return True
|
||||
|
||||
def saveText(self):
|
||||
|
||||
if self.theDocument.theItem is None:
|
||||
return False
|
||||
|
||||
docText = self.getText()
|
||||
cursPos = self.getCursorPosition()
|
||||
theItem = self.theDocument.theItem
|
||||
theItem.setCharCount(self.charCount)
|
||||
theItem.setWordCount(self.wordCount)
|
||||
theItem.setParaCount(self.paraCount)
|
||||
theItem.setCursorPos(cursPos)
|
||||
self.theDocument.saveDocument(docText)
|
||||
self.setDocumentChanged(False)
|
||||
|
||||
self.theParent.theIndex.scanText(theItem.itemHandle, docText)
|
||||
|
||||
return True
|
||||
|
||||
##
|
||||
@@ -381,7 +419,7 @@ class GuiDocEditor(QTextEdit):
|
||||
"""
|
||||
logger.verbose("Updating word count")
|
||||
|
||||
tHandle = self.theParent.theDocument.docHandle
|
||||
tHandle = self.theDocument.docHandle
|
||||
self.charCount = self.wCounter.charCount
|
||||
self.wordCount = self.wCounter.wordCount
|
||||
self.paraCount = self.wCounter.paraCount
|
||||
@@ -392,9 +430,9 @@ class GuiDocEditor(QTextEdit):
|
||||
return
|
||||
|
||||
def _wrapSelection(self, tBefore, tAfter):
|
||||
"""Wraps the selected text in whatever is in tBefore and tAfter. If there is no selection, the autoSelect setting decides
|
||||
the action. AutoSelect will select the word under the cursor before wrapping it. If this feature is disabled, nothing is
|
||||
done.
|
||||
"""Wraps the selected text in whatever is in tBefore and tAfter. If there is no selection,
|
||||
the autoSelect setting decides the action. AutoSelect will select the word under the cursor
|
||||
before wrapping it. If this feature is disabled, nothing is done.
|
||||
"""
|
||||
theCursor = self.textCursor()
|
||||
if self.mainConf.autoSelect and not theCursor.hasSelection():
|
||||
|
||||
+97
-9
@@ -13,34 +13,76 @@
|
||||
import logging
|
||||
import nw
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtCore import Qt, QUrl
|
||||
from PyQt5.QtWidgets import QTextBrowser
|
||||
from PyQt5.QtGui import QTextOption
|
||||
|
||||
from nw.convert.tokenizer import Tokenizer
|
||||
from nw.convert.tohtml import ToHtml
|
||||
from nw.enum import nwItemType
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class GuiDocViewer(QTextBrowser):
|
||||
|
||||
def __init__(self, theParent):
|
||||
def __init__(self, theParent, theProject):
|
||||
QTextBrowser.__init__(self)
|
||||
|
||||
logger.debug("Initialising DocViewer ...")
|
||||
|
||||
# Class Variables
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.theTheme = theParent.theTheme
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theProject = theProject
|
||||
self.theParent = theParent
|
||||
self.theTheme = theParent.theTheme
|
||||
self.theHandle = None
|
||||
|
||||
self.theQDoc = self.document()
|
||||
self.theQDoc.setDefaultStyleSheet((
|
||||
"body {{"
|
||||
" font-size: {textSize}pt;"
|
||||
" color: rgb({tColR},{tColG},{tColB});"
|
||||
"}}\n"
|
||||
"h1, h2, h3, h4 {{"
|
||||
" color: rgb({0},{1},{2});"
|
||||
"}}"
|
||||
" color: rgb({hColR},{hColG},{hColB});"
|
||||
"}}\n"
|
||||
"a {{"
|
||||
" color: rgb({aColR},{aColG},{aColB});"
|
||||
"}}\n"
|
||||
"pre {{"
|
||||
" color: rgb({cColR},{cColG},{cColB});"
|
||||
" font-size: {preSize}pt;"
|
||||
"}}\n"
|
||||
"mark {{"
|
||||
" color: rgb({eColR},{eColG},{eColB});"
|
||||
"}}\n"
|
||||
"table {{"
|
||||
" margin: 10px 0px;"
|
||||
"}}\n"
|
||||
"td {{"
|
||||
" padding: 0px 4px;"
|
||||
"}}\n"
|
||||
).format(
|
||||
*self.theTheme.colHead
|
||||
textSize = self.mainConf.textSize,
|
||||
preSize = self.mainConf.textSize*0.9,
|
||||
tColR = self.theTheme.colText[0],
|
||||
tColG = self.theTheme.colText[1],
|
||||
tColB = self.theTheme.colText[2],
|
||||
hColR = self.theTheme.colHead[0],
|
||||
hColG = self.theTheme.colHead[1],
|
||||
hColB = self.theTheme.colHead[2],
|
||||
cColR = self.theTheme.colComm[0],
|
||||
cColG = self.theTheme.colComm[1],
|
||||
cColB = self.theTheme.colComm[2],
|
||||
eColR = self.theTheme.colEmph[0],
|
||||
eColG = self.theTheme.colEmph[1],
|
||||
eColB = self.theTheme.colEmph[2],
|
||||
aColR = self.theTheme.colLink[0],
|
||||
aColG = self.theTheme.colLink[1],
|
||||
aColB = self.theTheme.colLink[2],
|
||||
))
|
||||
self.theQDoc.setDocumentMargin(self.mainConf.textMargin[0])
|
||||
self.setMinimumWidth(300)
|
||||
self.initEditor()
|
||||
|
||||
theOpt = QTextOption()
|
||||
if self.mainConf.doJustify:
|
||||
@@ -53,6 +95,52 @@ class GuiDocViewer(QTextBrowser):
|
||||
|
||||
def clearViewer(self):
|
||||
self.clear()
|
||||
self.setSearchPaths([""])
|
||||
return True
|
||||
|
||||
def initEditor(self):
|
||||
"""Set editor settings from mani config.
|
||||
"""
|
||||
self.theQDoc.setDocumentMargin(self.mainConf.textMargin[0])
|
||||
theOpt = QTextOption()
|
||||
if self.mainConf.doJustify:
|
||||
theOpt.setAlignment(Qt.AlignJustify)
|
||||
self.theQDoc.setDefaultTextOption(theOpt)
|
||||
|
||||
return True
|
||||
|
||||
def loadText(self, tHandle):
|
||||
|
||||
if tHandle == "Help":
|
||||
self.loadHelp()
|
||||
return True
|
||||
|
||||
tItem = self.theProject.getItem(tHandle)
|
||||
if tItem is None:
|
||||
logger.warning("Item not found")
|
||||
return False
|
||||
|
||||
if tItem.itemType != nwItemType.FILE:
|
||||
return False
|
||||
|
||||
logger.debug("Generating preview for item %s" % tHandle)
|
||||
aDoc = ToHtml(self.theProject, self.theParent)
|
||||
aDoc.setText(tHandle)
|
||||
aDoc.doAutoReplace()
|
||||
aDoc.tokenizeText()
|
||||
aDoc.doConvert()
|
||||
self.setHtml(aDoc.theResult)
|
||||
self.theHandle = tHandle
|
||||
self.theProject.setLastViewed(tHandle)
|
||||
|
||||
return True
|
||||
|
||||
def loadHelp(self):
|
||||
|
||||
self.clearViewer()
|
||||
self.setSearchPaths([self.mainConf.helpPath])
|
||||
self.setSource(QUrl("index.html"))
|
||||
|
||||
return True
|
||||
|
||||
# END Class GuiDocViewer
|
||||
|
||||
@@ -516,6 +516,16 @@ class GuiMainMenu(QMenuBar):
|
||||
menuItem.triggered.connect(self._showAboutQt)
|
||||
self.helpMenu.addAction(menuItem)
|
||||
|
||||
# Help > Separator
|
||||
self.helpMenu.addSeparator()
|
||||
|
||||
# Document > Preview
|
||||
menuItem = QAction(QIcon.fromTheme("text-html"), "Documentation", self)
|
||||
menuItem.setStatusTip("View documentation")
|
||||
menuItem.setShortcut("F1")
|
||||
menuItem.triggered.connect(lambda : self.theParent.viewDocument("Help"))
|
||||
self.helpMenu.addAction(menuItem)
|
||||
|
||||
return
|
||||
|
||||
# END Class GuiMainMenu
|
||||
|
||||
+11
-38
@@ -35,8 +35,6 @@ from nw.project.project import NWProject
|
||||
from nw.project.document import NWDoc
|
||||
from nw.project.item import NWItem
|
||||
from nw.project.index import NWIndex
|
||||
from nw.convert.tokenizer import Tokenizer
|
||||
from nw.convert.tohtml import ToHtml
|
||||
from nw.tools.wordcount import countWords
|
||||
from nw.theme import Theme
|
||||
from nw.enum import nwItemType, nwAlert
|
||||
@@ -53,7 +51,6 @@ class GuiMain(QMainWindow):
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theTheme = Theme()
|
||||
self.theProject = NWProject(self)
|
||||
self.theDocument = NWDoc(self.theProject, self)
|
||||
self.theIndex = NWIndex(self.theProject, self)
|
||||
self.hasProject = False
|
||||
|
||||
@@ -63,12 +60,12 @@ class GuiMain(QMainWindow):
|
||||
self.theTheme.loadTheme()
|
||||
|
||||
# Main GUI Elements
|
||||
self.docEditor = GuiDocEditor(self)
|
||||
self.docViewer = GuiDocViewer(self)
|
||||
self.statusBar = GuiMainStatus(self)
|
||||
self.docEditor = GuiDocEditor(self, self.theProject)
|
||||
self.docViewer = GuiDocViewer(self, self.theProject)
|
||||
self.docDetails = GuiDocDetails(self, self.theProject)
|
||||
self.treeView = GuiDocTree(self, self.theProject)
|
||||
self.mainMenu = GuiMainMenu(self, self.theProject)
|
||||
self.statusBar = GuiMainStatus(self)
|
||||
|
||||
# Minor Gui Elements
|
||||
self.statusIcons = []
|
||||
@@ -284,7 +281,6 @@ class GuiMain(QMainWindow):
|
||||
if self.hasProject:
|
||||
if self.docEditor.docChanged:
|
||||
self.saveDocument()
|
||||
self.theDocument.clearDocument()
|
||||
self.docEditor.clearEditor()
|
||||
return True
|
||||
|
||||
@@ -298,17 +294,8 @@ class GuiMain(QMainWindow):
|
||||
return True
|
||||
|
||||
def saveDocument(self):
|
||||
if self.theDocument.theItem is not None and self.hasProject:
|
||||
docText = self.docEditor.getText()
|
||||
cursPos = self.docEditor.getCursorPosition()
|
||||
theItem = self.theDocument.theItem
|
||||
theItem.setCharCount(self.docEditor.charCount)
|
||||
theItem.setWordCount(self.docEditor.wordCount)
|
||||
theItem.setParaCount(self.docEditor.paraCount)
|
||||
theItem.setCursorPos(cursPos)
|
||||
self.theDocument.saveDocument(docText)
|
||||
self.docEditor.setDocumentChanged(False)
|
||||
self.theIndex.scanText(theItem.itemHandle, docText)
|
||||
if self.hasProject:
|
||||
self.docEditor.saveText()
|
||||
return True
|
||||
|
||||
def viewDocument(self, tHandle=None):
|
||||
@@ -316,30 +303,16 @@ class GuiMain(QMainWindow):
|
||||
if tHandle is None:
|
||||
tHandle = self.treeView.getSelectedHandle()
|
||||
if tHandle is None:
|
||||
logger.warning("No document selected, trying last viewed")
|
||||
logger.debug("No document selected, trying last viewed")
|
||||
tHandle = self.theProject.lastViewed
|
||||
if tHandle is None:
|
||||
logger.warning("No document selected, trying editor document")
|
||||
tHandle = self.theDocument.docHandle
|
||||
logger.debug("No document selected, trying editor document")
|
||||
tHandle = self.docEditor.theHandle
|
||||
if tHandle is None:
|
||||
logger.warning("No document selected, giving up")
|
||||
logger.debug("No document selected, giving up")
|
||||
return False
|
||||
|
||||
tItem = self.theProject.getItem(tHandle)
|
||||
if tItem is None:
|
||||
logger.warning("Item not found")
|
||||
return False
|
||||
|
||||
if tItem.itemType == nwItemType.FILE:
|
||||
logger.debug("Generating preview for item %s" % tHandle)
|
||||
aDoc = ToHtml(self.theProject, self)
|
||||
aDoc.setText(tHandle)
|
||||
aDoc.doAutoReplace()
|
||||
aDoc.tokenizeText()
|
||||
aDoc.doConvert()
|
||||
self.docViewer.setHtml(aDoc.theResult)
|
||||
self.theProject.setLastViewed(tHandle)
|
||||
|
||||
if self.docViewer.loadText(tHandle):
|
||||
bPos = self.splitMain.sizes()
|
||||
self.docViewer.setVisible(True)
|
||||
vPos = [0,0]
|
||||
@@ -596,7 +569,7 @@ class GuiMain(QMainWindow):
|
||||
return
|
||||
|
||||
def _autoSaveDocument(self):
|
||||
if self.hasProject and self.docEditor.docChanged and self.theDocument.theItem is not None:
|
||||
if self.hasProject and self.docEditor.docChanged:
|
||||
logger.debug("Autosaving document")
|
||||
self.saveDocument()
|
||||
return
|
||||
|
||||
@@ -86,6 +86,8 @@ class Theme:
|
||||
## Syntax
|
||||
cnfSec = "Syntax"
|
||||
if confParser.has_section(cnfSec):
|
||||
self.colText = self._loadColour(confParser,cnfSec,"text")
|
||||
self.colLink = self._loadColour(confParser,cnfSec,"link")
|
||||
self.colHead = self._loadColour(confParser,cnfSec,"headertext")
|
||||
self.colHeadH = self._loadColour(confParser,cnfSec,"headertag")
|
||||
self.colEmph = self._loadColour(confParser,cnfSec,"emphasis")
|
||||
|
||||
@@ -10,7 +10,6 @@ QTextEdit {
|
||||
QTextBrowser {
|
||||
background-color: #141414;
|
||||
color: #c7cfd0;
|
||||
/* padding: 40px; */
|
||||
}
|
||||
|
||||
QTreeView, QHeaderView {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
[Syntax]
|
||||
text = 199, 207, 208
|
||||
link = 184, 200, 0
|
||||
headertext = 0, 155, 200
|
||||
headertag = 0, 105, 135
|
||||
emphasis = 200, 120, 0
|
||||
|
||||
Reference in New Issue
Block a user