Reworked the title formatting functionality. All keywords can be used in all headings, and also added scene numbers.
This commit is contained in:
@@ -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> – This is replaced with the text you put in your headings in your
|
||||
documents</p>
|
||||
<p><mark>%num%</mark> – This is replaced with the chapter number of your chapter type
|
||||
headings. These are generated automaticall starting from 1.</p>
|
||||
<p><mark>%numword%</mark> – 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> – 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> – 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> – 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> – 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> – 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
@@ -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
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user