Reworked the title formatting functionality. All keywords can be used in all headings, and also added scene numbers.

This commit is contained in:
Veronica K. B. Olsen
2020-05-11 19:00:01 +02:00
parent 4dead91af2
commit 7c1f3144bd
4 changed files with 82 additions and 64 deletions
+18 -13
View File
@@ -1,25 +1,30 @@
<h1>Help!</h1>
<p>A brief guide to make the most out of the Build Project tool.</p>
<p><i>A brief guide to make the most out of the Build Novel Project tool.</i></p>
<h2>Novel Title Formats</h2>
<p>The format of the various title levels in the files under the Novel folder can be customised in
these settings. The actual title given in the headings of your files will replace all
occurrences of the keyword <mark>%title%</mark>. Any static text will be left as-is in the
these settings. The actual title given in the headings of your files will for instance replace
all occurrences of the keyword <mark>%title%</mark>. Any static text will be left as-is in the
final title. An empty field means the title isn't written out at all.</p>
<p>The available formatting keywords are:</p>
<p><mark>%title%</mark> &ndash; This is replaced with the text you put in your headings in your
documents</p>
<p><mark>%num%</mark> &ndash; This is replaced with the chapter number of your chapter type
headings. These are generated automaticall starting from 1.</p>
<p><mark>%numword%</mark> &ndash; This is replaced with the chapter number of your chapter type
headings, but instead of an arabic number, the word for it is used instead, e.g. One, Two,
Fifteen, Twenty-Five, etc.</p>
<p><mark>%chnum%</mark> &ndash; This is replaced with the chapter number of your chapter type
headings. These are generated automaticall starting from 1, but ignoring chapter headings in
files with "Unnumbered" layout.</p>
<p><mark>%chnumword%</mark> &ndash; This is replaced with the chapter number, but instead of an
arabic number, the word for it is used, e.g. One, Two, Fifteen, Twenty-Five, etc.</p>
<p><mark>%scnum%</mark> &ndash; This is replaced with the scene number. The number is reset to one
for each new chapter, so it is the scene number within the current chapter.</p>
<p><mark>%scabsnum%</mark> &ndash; This is replaced with the absolute scene number. That is, the
number is counted from the first scene in the novel, and not reset for each chapter.</p>
<p><mark>\\</mark> &ndash; Two backslashes are replaced by a line break.</p>
<p><b>Note:</b> The Scene format is treated slightly differently than the other title formats. If a
scene format is a constant text, that is, contains no <mark>%title%</mark>, it will be treated
as a scene separator instead. Scene separators are centred, and not shown if the chapter starts
directly on the first scene. If the field is blank, a large space between the scenes is added
instead.</p>
<p><b>Note:</b> The Scene and Section formats are treated slightly differently than the other title
formats. If the format is a constant text, that is, contains no <mark>%keyword%</mark> tags, it
will be treated as a separator instead. Scene and Section separators are centred, and for
scenes, not shown if placed directly after the chapter heading. For instance, it you want the
classic three asterisk <mark>* * *</mark> separator between scenes, just put that into the
scene format box, and nothing else.</p>
<h2>Build Overrides</h2>
<p><b>Novel Outline Mode:</b> This option will build an outline version of the novel rather than the
+53 -40
View File
@@ -104,6 +104,8 @@ class Tokenizer():
# Instance Variables
self.numChapter = 0 # Counter for chapter numbers
self.numChScene = 0 # Counter for scene number within chapter
self.numAbsScene = 0 # Counter for scene number within novel
self.firstScene = False # Flag to indicate that the first scene of the chapter
return
@@ -370,23 +372,53 @@ class Tokenizer():
tType = tToken[0]
tText = tToken[1]
# In case we see text before a scene, we reset the flag
if tType == self.T_TEXT:
self.firstScene = False
elif tType == self.T_HEAD2: # Novel Chapter
if not isUnNum:
self.numChapter += 1
tText = self._formatChapter(tText,isUnNum)
elif tType == self.T_HEAD1:
# Main Title
# ==========
tText = self._formatHeading(self.fmtTitle, tText)
self.theTokens[n] = (
tType,
tText,
None,
self.A_LEFT | self.A_PBB_R
)
self.firstScene = True
elif tType == self.T_HEAD3: # Novel Scene
tTemp = self._formatScene(tText)
elif tType == self.T_HEAD2:
# Novel Chapter
# =============
# Numbered or Unnumbered
if isUnNum:
tText = self._formatHeading(self.fmtUnNum, tText)
else:
self.numChapter += 1
tText = self._formatHeading(self.fmtChapter, tText)
# Format the chapter header
self.theTokens[n] = (
tType,
tText,
None,
self.A_LEFT | self.A_PBB_R
)
# Set scene variables
self.firstScene = True
self.numChScene = 0
elif tType == self.T_HEAD3:
# Novel Scene
# ===========
self.numChScene += 1
self.numAbsScene += 1
tTemp = self._formatHeading(self.fmtScene, tText)
if tTemp == "" and self.hideScene:
self.theTokens[n] = (
self.T_EMPTY,
@@ -431,10 +463,15 @@ class Tokenizer():
None,
self.A_LEFT | self.A_PBA_AV
)
# Definitely no longer the first scene
self.firstScene = False
elif tType == self.T_HEAD4: # Novel Section
tTemp = self._formatSection(tText)
elif tType == self.T_HEAD4:
# Novel Section
# =============
tTemp = self._formatHeading(self.fmtSection, tText)
if tTemp == "" and self.hideSection:
self.theTokens[n] = (
self.T_EMPTY,
@@ -500,38 +537,14 @@ class Tokenizer():
# Internal Functions
##
def _formatTitle(self, theText):
"""Replace tokens for headers level 1.
def _formatHeading(self, theTitle, theText):
"""Replaces the %keyword% strings.
"""
theTitle = self.fmtTitle
theTitle = theTitle.replace("%title%", theText)
return theTitle
def _formatChapter(self, theText, noNum):
"""Replace tokens for headers level 2.
"""
if noNum:
theTitle = self.fmtUnNum
theTitle = theTitle.replace("%title%", theText)
else:
theTitle = self.fmtChapter
theTitle = theTitle.replace("%title%", theText)
theTitle = theTitle.replace("%num%", str(self.numChapter))
theTitle = theTitle.replace("%numword%", numberToWord(self.numChapter,"en"))
return theTitle
def _formatScene(self, theText):
"""Replace tokens for headers level 3.
"""
theTitle = self.fmtScene
theTitle = theTitle.replace("%title%", theText)
return theTitle
def _formatSection(self, theText):
"""Replace tokens for headers level 4.
"""
theTitle = self.fmtSection
theTitle = theTitle.replace("%title%", theText)
theTitle = theTitle.replace(r"%title%", theText)
theTitle = theTitle.replace(r"%chnum%", str(self.numChapter))
theTitle = theTitle.replace(r"%scnum%", str(self.numChScene))
theTitle = theTitle.replace(r"%scabsnum%", str(self.numAbsScene))
theTitle = theTitle.replace(r"%chnumword%", numberToWord(self.numChapter,"en"))
return theTitle
# END Class Tokenizer
+6 -6
View File
@@ -69,7 +69,7 @@ class GuiBuildNovel(QDialog):
self.htmlText = ""
self.setWindowTitle("Build Project")
self.setWindowTitle("Build Novel Project")
self.setMinimumWidth(800)
self.setMinimumHeight(800)
@@ -315,11 +315,11 @@ class GuiBuildNovel(QDialog):
doBodyText = True
if outlineMode:
fmtTitle = "%title%"
fmtChapter = "Chapter: %title%"
fmtUnnumbered = "Chapter: %title%"
fmtScene = "Scene: %title%"
fmtSection = "Section: %title%"
fmtTitle = r"%title%"
fmtChapter = r"Chapter %chnum%: %title%"
fmtUnnumbered = r"%title%"
fmtScene = r"Scene %chnum%.%scnum%: %title%"
fmtSection = r"Section: %title%"
doBodyText = False
incSynopsis = True
novelFiles = True
+5 -5
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.5" fileVersion="1.0" saveCount="263" autoCount="31" timeStamp="2020-05-10 23:14:34">
<novelWriterXML appVersion="0.5" fileVersion="1.0" saveCount="279" autoCount="37" timeStamp="2020-05-11 18:58:21">
<project>
<name>Sample Project</name>
<title>Sample Project</title>
@@ -10,8 +10,8 @@
<settings>
<spellCheck>True</spellCheck>
<autoOutline>True</autoOutline>
<lastEdited>6a2d6d5f4f401</lastEdited>
<lastViewed>b3e74dbc1f584</lastViewed>
<lastEdited>96b68994dfa3d</lastEdited>
<lastViewed>6a2d6d5f4f401</lastViewed>
<lastWordCount>875</lastWordCount>
<autoReplace>
<A>B</A>
@@ -20,9 +20,9 @@
</autoReplace>
<titleFormat>
<title>%title%</title>
<chapter>Chapter %num%.\\%title%</chapter>
<chapter>Chapter %chnum%.\\%title%</chapter>
<unnumbered>%title%</unnumbered>
<scene>* * *</scene>
<scene>Scene %chnum%.%scnum%: %title%</scene>
<section></section>
<withSynopsis>True</withSynopsis>
<withComments>False</withComments>