Reshuffle build and preview in Build Novel Project tool
This commit is contained in:
+73
-8
@@ -61,6 +61,8 @@ class ToHtml(Tokenizer):
|
|||||||
self.reReverse = []
|
self.reReverse = []
|
||||||
self._buildRegEx()
|
self._buildRegEx()
|
||||||
|
|
||||||
|
self.fullHTML = []
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -90,6 +92,11 @@ class ToHtml(Tokenizer):
|
|||||||
# Class Methods
|
# Class Methods
|
||||||
##
|
##
|
||||||
|
|
||||||
|
def getFullResultSize(self):
|
||||||
|
"""Return the size of the full HTML result.
|
||||||
|
"""
|
||||||
|
return sum([len(x) for x in self.fullHTML])
|
||||||
|
|
||||||
def doAutoReplace(self):
|
def doAutoReplace(self):
|
||||||
"""Extend the auto-replace to also properly encode some unicode
|
"""Extend the auto-replace to also properly encode some unicode
|
||||||
characters into their respective HTML entities.
|
characters into their respective HTML entities.
|
||||||
@@ -108,9 +115,12 @@ class ToHtml(Tokenizer):
|
|||||||
if self.genMode == self.M_PREVIEW:
|
if self.genMode == self.M_PREVIEW:
|
||||||
# Doesn't matter for preview as we don't use the markdown
|
# Doesn't matter for preview as we don't use the markdown
|
||||||
return
|
return
|
||||||
self.theMarkdown = self.reReverse.sub(
|
|
||||||
lambda x: self.revDict[x.group(0)], self.theMarkdown
|
if self.keepMarkdown:
|
||||||
)
|
self.theMarkdown[-1] = self.reReverse.sub(
|
||||||
|
lambda x: self.revDict[x.group(0)], self.theMarkdown[-1]
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def doConvert(self):
|
def doConvert(self):
|
||||||
@@ -165,21 +175,28 @@ class ToHtml(Tokenizer):
|
|||||||
if tStyle is not None and self.cssStyles:
|
if tStyle is not None and self.cssStyles:
|
||||||
if tStyle & self.A_LEFT:
|
if tStyle & self.A_LEFT:
|
||||||
aStyle.append("text-align: left;")
|
aStyle.append("text-align: left;")
|
||||||
if tStyle & self.A_RIGHT:
|
elif tStyle & self.A_RIGHT:
|
||||||
aStyle.append("text-align: right;")
|
aStyle.append("text-align: right;")
|
||||||
if tStyle & self.A_CENTRE:
|
elif tStyle & self.A_CENTRE:
|
||||||
aStyle.append("text-align: center;")
|
aStyle.append("text-align: center;")
|
||||||
if tStyle & self.A_JUSTIFY:
|
elif tStyle & self.A_JUSTIFY:
|
||||||
aStyle.append("text-align: justify;")
|
aStyle.append("text-align: justify;")
|
||||||
|
|
||||||
if tStyle & self.A_PBB:
|
if tStyle & self.A_PBB:
|
||||||
aStyle.append("page-break-before: always;")
|
aStyle.append("page-break-before: always;")
|
||||||
if tStyle & self.A_PBB_AUT:
|
elif tStyle & self.A_PBB_AUT:
|
||||||
aStyle.append("page-break-before: auto;")
|
aStyle.append("page-break-before: auto;")
|
||||||
|
|
||||||
if tStyle & self.A_PBA:
|
if tStyle & self.A_PBA:
|
||||||
aStyle.append("page-break-after: always;")
|
aStyle.append("page-break-after: always;")
|
||||||
if tStyle & self.A_PBA_AUT:
|
elif tStyle & self.A_PBA_AUT:
|
||||||
aStyle.append("page-break-after: auto;")
|
aStyle.append("page-break-after: auto;")
|
||||||
|
|
||||||
|
if tStyle & self.A_Z_BTMMRG:
|
||||||
|
aStyle.append("margin-bottom: 0;")
|
||||||
|
if tStyle & self.A_Z_TOPMRG:
|
||||||
|
aStyle.append("margin-top: 0;")
|
||||||
|
|
||||||
if len(aStyle) > 0:
|
if len(aStyle) > 0:
|
||||||
hStyle = " style='%s'" % (" ".join(aStyle))
|
hStyle = " style='%s'" % (" ".join(aStyle))
|
||||||
else:
|
else:
|
||||||
@@ -255,6 +272,54 @@ class ToHtml(Tokenizer):
|
|||||||
self.theResult = "".join(tmpResult)
|
self.theResult = "".join(tmpResult)
|
||||||
tmpResult = []
|
tmpResult = []
|
||||||
|
|
||||||
|
if self.genMode != self.M_PREVIEW:
|
||||||
|
self.fullHTML.append(self.theResult)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def saveHTML5(self, savePath):
|
||||||
|
"""Save the data to an .html file.
|
||||||
|
"""
|
||||||
|
with open(savePath, mode="w", encoding="utf8") as outFile:
|
||||||
|
theStyle = self.getStyleSheet()
|
||||||
|
theStyle.append("article {width: 800px; margin: 40px auto;}")
|
||||||
|
bodyText = "".join(self.fullHTML)
|
||||||
|
bodyText = bodyText.replace("\t", "	")
|
||||||
|
|
||||||
|
theHtml = (
|
||||||
|
"<!DOCTYPE html>\n"
|
||||||
|
"<html>\n"
|
||||||
|
"<head>\n"
|
||||||
|
"<meta charset='utf-8'>\n"
|
||||||
|
"<title>{projTitle:s}</title>\n"
|
||||||
|
"</head>\n"
|
||||||
|
"<style>\n"
|
||||||
|
"{htmlStyle:s}\n"
|
||||||
|
"</style>\n"
|
||||||
|
"<body>\n"
|
||||||
|
"<article>\n"
|
||||||
|
"{bodyText:s}\n"
|
||||||
|
"</article>\n"
|
||||||
|
"</body>\n"
|
||||||
|
"</html>\n"
|
||||||
|
).format(
|
||||||
|
projTitle = self.theProject.projName,
|
||||||
|
htmlStyle = "\n".join(theStyle),
|
||||||
|
bodyText = bodyText,
|
||||||
|
)
|
||||||
|
outFile.write(theHtml)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def replaceTabs(self, nSpaces=8, spaceChar=" "):
|
||||||
|
"""Replace tabs with spaces in the html.
|
||||||
|
"""
|
||||||
|
htmlText = []
|
||||||
|
eightSpace = spaceChar*nSpaces
|
||||||
|
for aLine in self.fullHTML:
|
||||||
|
htmlText.append(aLine.replace("\t", eightSpace))
|
||||||
|
|
||||||
|
self.fullHTML = htmlText
|
||||||
return
|
return
|
||||||
|
|
||||||
def getStyleSheet(self):
|
def getStyleSheet(self):
|
||||||
|
|||||||
+99
-184
@@ -70,6 +70,8 @@ class Tokenizer():
|
|||||||
A_PBB_AUT = 0x0020 # Page break before auto
|
A_PBB_AUT = 0x0020 # Page break before auto
|
||||||
A_PBA = 0x0040 # Page break after always
|
A_PBA = 0x0040 # Page break after always
|
||||||
A_PBA_AUT = 0x0080 # Page break after auto
|
A_PBA_AUT = 0x0080 # Page break after auto
|
||||||
|
A_Z_TOPMRG = 0x0100 # Zero top margin
|
||||||
|
A_Z_BTMMRG = 0x0200 # Zero bottom margin
|
||||||
|
|
||||||
def __init__(self, theProject, theParent):
|
def __init__(self, theProject, theParent):
|
||||||
|
|
||||||
@@ -77,12 +79,14 @@ class Tokenizer():
|
|||||||
self.theParent = theParent
|
self.theParent = theParent
|
||||||
|
|
||||||
# Data Variables
|
# Data Variables
|
||||||
self.theText = None # The raw text to be tokenized
|
self.theText = "" # The raw text to be tokenized
|
||||||
self.theHandle = None # The handle associated with the text
|
self.theHandle = None # The handle associated with the text
|
||||||
self.theItem = None # The NWItem associated with the handle
|
self.theItem = None # The NWItem associated with the handle
|
||||||
self.theTokens = None # The list of the processed tokens
|
self.theTokens = [] # The list of the processed tokens
|
||||||
self.theResult = None # The result text after conversion
|
self.theResult = "" # The result of the last document
|
||||||
self.theMarkdown = None # The result text in novelWriter markdown
|
|
||||||
|
self.keepMarkdown = False # Whether to keep the markdown text
|
||||||
|
self.theMarkdown = [] # The result novelWriter markdown of all documents
|
||||||
|
|
||||||
# User Settings
|
# User Settings
|
||||||
self.textFont = "Serif" # Output text font
|
self.textFont = "Serif" # Output text font
|
||||||
@@ -96,12 +100,13 @@ class Tokenizer():
|
|||||||
self.doKeywords = False # Also process keywords like tags and references
|
self.doKeywords = False # Also process keywords like tags and references
|
||||||
|
|
||||||
## Title Margins
|
## Title Margins
|
||||||
self.marginTitle = (1.00, 0.50)
|
self.marginTitle = (1.000, 0.500)
|
||||||
self.marginHead1 = (1.00, 0.50)
|
self.marginHead1 = (1.000, 0.500)
|
||||||
self.marginHead2 = (0.85, 0.50)
|
self.marginHead2 = (0.834, 0.500)
|
||||||
self.marginHead3 = (0.58, 0.50)
|
self.marginHead3 = (0.584, 0.500)
|
||||||
self.marginHead4 = (0.58, 0.50)
|
self.marginHead4 = (0.584, 0.500)
|
||||||
self.marginText = (0.00, 0.58)
|
self.marginText = (0.000, 0.584)
|
||||||
|
self.marginMeta = (0.000, 0.584)
|
||||||
|
|
||||||
## Title Formats
|
## Title Formats
|
||||||
self.fmtTitle = "%title%" # Formatting for titles
|
self.fmtTitle = "%title%" # Formatting for titles
|
||||||
@@ -202,6 +207,10 @@ class Tokenizer():
|
|||||||
self.marginText = (float(mUpper), float(mLower))
|
self.marginText = (float(mUpper), float(mLower))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def setMetaMargins(self, mUpper, mLower):
|
||||||
|
self.marginMeta = (float(mUpper), float(mLower))
|
||||||
|
return
|
||||||
|
|
||||||
def setLinkHeaders(self, linkHeaders):
|
def setLinkHeaders(self, linkHeaders):
|
||||||
self.linkHeaders = linkHeaders
|
self.linkHeaders = linkHeaders
|
||||||
return
|
return
|
||||||
@@ -222,6 +231,10 @@ class Tokenizer():
|
|||||||
self.doKeywords = doKeywords
|
self.doKeywords = doKeywords
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def setKeepMarkdown(self, keepMarkdown):
|
||||||
|
self.keepMarkdown = keepMarkdown
|
||||||
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Class Methods
|
# Class Methods
|
||||||
##
|
##
|
||||||
@@ -241,7 +254,8 @@ class Tokenizer():
|
|||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_TITLE, 0, theTitle, None, self.A_PBB | self.A_CENTRE
|
self.T_TITLE, 0, theTitle, None, self.A_PBB | self.A_CENTRE
|
||||||
))
|
))
|
||||||
self.theMarkdown = "# %s\n\n" % theTitle
|
if self.keepMarkdown:
|
||||||
|
self.theMarkdown.append("# %s\n\n" % theTitle)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -283,23 +297,6 @@ class Tokenizer():
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getResult(self):
|
|
||||||
"""Return the result from the conversion.
|
|
||||||
"""
|
|
||||||
return self.theResult
|
|
||||||
|
|
||||||
def getResultSize(self):
|
|
||||||
"""Return the size of the result from the conversion.
|
|
||||||
"""
|
|
||||||
if self.theResult is None:
|
|
||||||
return 0
|
|
||||||
return len(self.theResult)
|
|
||||||
|
|
||||||
def getFilteredMarkdown(self):
|
|
||||||
"""Return the novelWriter markdown after the filters have been applied.
|
|
||||||
"""
|
|
||||||
return self.theMarkdown
|
|
||||||
|
|
||||||
def doAutoReplace(self):
|
def doAutoReplace(self):
|
||||||
"""Run through the user's auto-replace dictionary.
|
"""Run through the user's auto-replace dictionary.
|
||||||
"""
|
"""
|
||||||
@@ -352,7 +349,6 @@ class Tokenizer():
|
|||||||
]
|
]
|
||||||
|
|
||||||
self.theTokens = []
|
self.theTokens = []
|
||||||
self.theMarkdown = ""
|
|
||||||
tmpMarkdown = []
|
tmpMarkdown = []
|
||||||
nLine = 0
|
nLine = 0
|
||||||
for aLine in self.theText.splitlines():
|
for aLine in self.theText.splitlines():
|
||||||
@@ -361,88 +357,61 @@ class Tokenizer():
|
|||||||
# Tag lines starting with specific characters
|
# Tag lines starting with specific characters
|
||||||
if len(aLine.strip()) == 0:
|
if len(aLine.strip()) == 0:
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, nLine, "", None, self.A_NONE
|
||||||
nLine,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
tmpMarkdown.append("\n")
|
if self.keepMarkdown:
|
||||||
|
tmpMarkdown.append("\n")
|
||||||
|
|
||||||
elif aLine[0] == "%":
|
elif aLine[0] == "%":
|
||||||
cLine = aLine[1:].lstrip()
|
cLine = aLine[1:].lstrip()
|
||||||
synTag = cLine[:9].lower()
|
synTag = cLine[:9].lower()
|
||||||
if synTag == "synopsis:":
|
if synTag == "synopsis:":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_SYNOPSIS,
|
self.T_SYNOPSIS, nLine, cLine[9:].strip(), None, self.A_NONE
|
||||||
nLine,
|
|
||||||
cLine[9:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
if self.doSynopsis:
|
if self.doSynopsis and self.keepMarkdown:
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
else:
|
else:
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_COMMENT,
|
self.T_COMMENT, nLine, aLine[1:].strip(), None, self.A_NONE
|
||||||
nLine,
|
|
||||||
aLine[1:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
if self.doComments:
|
if self.doComments and self.keepMarkdown:
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
|
|
||||||
elif aLine[0] == "@":
|
elif aLine[0] == "@":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_KEYWORD,
|
self.T_KEYWORD, nLine, aLine[1:].strip(), None, self.A_NONE
|
||||||
nLine,
|
|
||||||
aLine[1:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
if self.doKeywords:
|
if self.doKeywords and self.keepMarkdown:
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
|
|
||||||
elif aLine[:2] == "# ":
|
elif aLine[:2] == "# ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD1,
|
self.T_HEAD1, nLine, aLine[2:].strip(), None, self.A_NONE
|
||||||
nLine,
|
|
||||||
aLine[2:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
if self.keepMarkdown:
|
||||||
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
|
|
||||||
elif aLine[:3] == "## ":
|
elif aLine[:3] == "## ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD2,
|
self.T_HEAD2, nLine, aLine[3:].strip(), None, self.A_NONE
|
||||||
nLine,
|
|
||||||
aLine[3:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
if self.keepMarkdown:
|
||||||
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
|
|
||||||
elif aLine[:4] == "### ":
|
elif aLine[:4] == "### ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD3,
|
self.T_HEAD3, nLine, aLine[4:].strip(), None, self.A_NONE
|
||||||
nLine,
|
|
||||||
aLine[4:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
if self.keepMarkdown:
|
||||||
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
|
|
||||||
elif aLine[:5] == "#### ":
|
elif aLine[:5] == "#### ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD4,
|
self.T_HEAD4, nLine, aLine[5:].strip(), None, self.A_NONE
|
||||||
nLine,
|
|
||||||
aLine[5:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
if self.keepMarkdown:
|
||||||
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not self.doBodyText:
|
if not self.doBodyText:
|
||||||
@@ -465,26 +434,44 @@ class Tokenizer():
|
|||||||
# sorted by position
|
# sorted by position
|
||||||
fmtPos = sorted(fmtPos, key=itemgetter(0))
|
fmtPos = sorted(fmtPos, key=itemgetter(0))
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_TEXT,
|
self.T_TEXT, nLine, aLine, fmtPos, self.A_NONE
|
||||||
nLine,
|
|
||||||
aLine,
|
|
||||||
fmtPos,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
tmpMarkdown.append("%s\n" % aLine)
|
if self.keepMarkdown:
|
||||||
|
tmpMarkdown.append("%s\n" % aLine)
|
||||||
|
|
||||||
# Always add an empty line at the end
|
# Always add an empty line at the end
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, nLine, "", None, self.A_NONE
|
||||||
nLine,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
))
|
))
|
||||||
tmpMarkdown.append("\n")
|
if self.keepMarkdown:
|
||||||
|
tmpMarkdown.append("\n")
|
||||||
|
|
||||||
self.theMarkdown = "".join(tmpMarkdown)
|
if self.keepMarkdown:
|
||||||
tmpMarkdown = []
|
self.theMarkdown.append("".join(tmpMarkdown))
|
||||||
|
|
||||||
|
# Second Pass
|
||||||
|
# ===========
|
||||||
|
# Some items need a second pass
|
||||||
|
|
||||||
|
pToken = (self.T_EMPTY, 0, "", None, self.A_NONE)
|
||||||
|
nToken = (self.T_EMPTY, 0, "", None, self.A_NONE)
|
||||||
|
tCount = len(self.theTokens)
|
||||||
|
for n, tToken in enumerate(self.theTokens):
|
||||||
|
|
||||||
|
if n > 0:
|
||||||
|
pToken = self.theTokens[n-1]
|
||||||
|
if n < tCount - 1:
|
||||||
|
nToken = self.theTokens[n+1]
|
||||||
|
|
||||||
|
if tToken[0] == self.T_KEYWORD:
|
||||||
|
aStyle = tToken[4]
|
||||||
|
if pToken[0] == self.T_KEYWORD:
|
||||||
|
aStyle |= self.A_Z_TOPMRG
|
||||||
|
if nToken[0] == self.T_KEYWORD:
|
||||||
|
aStyle |= self.A_Z_BTMMRG
|
||||||
|
self.theTokens[n] = (
|
||||||
|
tToken[0], tToken[1], tToken[2], tToken[3], aStyle
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -499,9 +486,7 @@ class Tokenizer():
|
|||||||
# For novel files, we need to handle chapter numbering, scene
|
# For novel files, we need to handle chapter numbering, scene
|
||||||
# numbering, and scene breaks
|
# numbering, and scene breaks
|
||||||
if self.isNovel:
|
if self.isNovel:
|
||||||
for n in range(len(self.theTokens)):
|
for n, tToken in enumerate(self.theTokens):
|
||||||
|
|
||||||
tToken = self.theTokens[n]
|
|
||||||
|
|
||||||
# In case we see text before a scene, we reset the flag
|
# In case we see text before a scene, we reset the flag
|
||||||
if tToken[0] == self.T_TEXT:
|
if tToken[0] == self.T_TEXT:
|
||||||
@@ -513,11 +498,7 @@ class Tokenizer():
|
|||||||
|
|
||||||
tTemp = self._formatHeading(self.fmtTitle, tToken[2])
|
tTemp = self._formatHeading(self.fmtTitle, tToken[2])
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tTemp, None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
elif tToken[0] == self.T_HEAD2:
|
elif tToken[0] == self.T_HEAD2:
|
||||||
@@ -535,11 +516,7 @@ class Tokenizer():
|
|||||||
|
|
||||||
# Format the chapter header
|
# Format the chapter header
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tTemp, None, self.A_PBB
|
||||||
tToken[1],
|
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_PBB
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set scene variables
|
# Set scene variables
|
||||||
@@ -556,53 +533,29 @@ class Tokenizer():
|
|||||||
tTemp = self._formatHeading(self.fmtScene, tToken[2])
|
tTemp = self._formatHeading(self.fmtScene, tToken[2])
|
||||||
if tTemp == "" and self.hideScene:
|
if tTemp == "" and self.hideScene:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, tToken[1], "", None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
elif tTemp == "" and not self.hideScene:
|
elif tTemp == "" and not self.hideScene:
|
||||||
if self.firstScene:
|
if self.firstScene:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, tToken[1], "", None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_SKIP,
|
self.T_SKIP, tToken[1], "", None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
elif tTemp == self.fmtScene:
|
elif tTemp == self.fmtScene:
|
||||||
if self.firstScene:
|
if self.firstScene:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, tToken[1], "", None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_SEP,
|
self.T_SEP, tToken[1], tTemp, None, self.A_CENTRE
|
||||||
tToken[1],
|
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tTemp, None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Definitely no longer the first scene
|
# Definitely no longer the first scene
|
||||||
@@ -615,35 +568,19 @@ class Tokenizer():
|
|||||||
tTemp = self._formatHeading(self.fmtSection, tToken[2])
|
tTemp = self._formatHeading(self.fmtSection, tToken[2])
|
||||||
if tTemp == "" and self.hideSection:
|
if tTemp == "" and self.hideSection:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, tToken[1], "", None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
elif tTemp == "" and not self.hideSection:
|
elif tTemp == "" and not self.hideSection:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_SKIP,
|
self.T_SKIP, tToken[1], "", None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
elif tTemp == self.fmtSection:
|
elif tTemp == self.fmtSection:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_SEP,
|
self.T_SEP, tToken[1], tTemp, None, self.A_CENTRE
|
||||||
tToken[1],
|
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tTemp, None, self.A_NONE
|
||||||
tToken[1],
|
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_NONE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# For title page and partitions, we need to centre all text.
|
# For title page and partitions, we need to centre all text.
|
||||||
@@ -654,28 +591,18 @@ class Tokenizer():
|
|||||||
for n, tToken in enumerate(self.theTokens):
|
for n, tToken in enumerate(self.theTokens):
|
||||||
if tToken[0] == self.T_HEAD1:
|
if tToken[0] == self.T_HEAD1:
|
||||||
if self.isTitle:
|
if self.isTitle:
|
||||||
|
aStyle = self.A_PBB_AUT | self.A_CENTRE
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_TITLE,
|
self.T_TITLE, tToken[1], tToken[2], tToken[3], aStyle
|
||||||
tToken[1],
|
|
||||||
tToken[2],
|
|
||||||
tToken[3],
|
|
||||||
self.A_PBB_AUT | self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
aStyle = self.A_PBB | self.A_CENTRE
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tToken[2], tToken[3], aStyle
|
||||||
tToken[1],
|
|
||||||
tToken[2],
|
|
||||||
tToken[3],
|
|
||||||
self.A_PBB | self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tToken[2], tToken[3], self.A_CENTRE
|
||||||
tToken[1],
|
|
||||||
tToken[2],
|
|
||||||
tToken[3],
|
|
||||||
self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add a page break after the last entry
|
# Add a page break after the last entry
|
||||||
@@ -683,11 +610,7 @@ class Tokenizer():
|
|||||||
if n >= 0:
|
if n >= 0:
|
||||||
tToken = self.theTokens[n]
|
tToken = self.theTokens[n]
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tToken[2], tToken[3], tToken[4] | self.A_PBA
|
||||||
tToken[1],
|
|
||||||
tToken[2],
|
|
||||||
tToken[3],
|
|
||||||
tToken[4] | self.A_PBA
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# A single page is always left-aligned and starts on a fresh
|
# A single page is always left-aligned and starts on a fresh
|
||||||
@@ -696,19 +619,11 @@ class Tokenizer():
|
|||||||
for n, tToken in enumerate(self.theTokens):
|
for n, tToken in enumerate(self.theTokens):
|
||||||
if n == 0:
|
if n == 0:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tToken[2], tToken[3], self.A_LEFT | self.A_PBB
|
||||||
tToken[1],
|
|
||||||
tToken[2],
|
|
||||||
tToken[3],
|
|
||||||
self.A_LEFT | self.A_PBB
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tToken[0],
|
tToken[0], tToken[1], tToken[2], tToken[3], self.A_LEFT
|
||||||
tToken[1],
|
|
||||||
tToken[2],
|
|
||||||
tToken[3],
|
|
||||||
self.A_LEFT
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
+20
-9
@@ -116,6 +116,7 @@ class ToOdt(Tokenizer):
|
|||||||
self._mTopHead4 = "0.247cm"
|
self._mTopHead4 = "0.247cm"
|
||||||
self._mTopHead = "0.423cm"
|
self._mTopHead = "0.423cm"
|
||||||
self._mTopText = "0.000cm"
|
self._mTopText = "0.000cm"
|
||||||
|
self._mTopMeta = "0.000cm"
|
||||||
|
|
||||||
self._mBotTitle = "0.212cm"
|
self._mBotTitle = "0.212cm"
|
||||||
self._mBotHead1 = "0.212cm"
|
self._mBotHead1 = "0.212cm"
|
||||||
@@ -124,6 +125,7 @@ class ToOdt(Tokenizer):
|
|||||||
self._mBotHead4 = "0.212cm"
|
self._mBotHead4 = "0.212cm"
|
||||||
self._mBotHead = "0.212cm"
|
self._mBotHead = "0.212cm"
|
||||||
self._mBotText = "0.247cm"
|
self._mBotText = "0.247cm"
|
||||||
|
self._mBotMeta = "0.106cm"
|
||||||
|
|
||||||
## Colour
|
## Colour
|
||||||
self._colHead12 = None
|
self._colHead12 = None
|
||||||
@@ -170,7 +172,7 @@ class ToOdt(Tokenizer):
|
|||||||
|
|
||||||
self._fontFamily = self.textFont
|
self._fontFamily = self.textFont
|
||||||
if len(self.textFont.split()) > 1:
|
if len(self.textFont.split()) > 1:
|
||||||
self._fontFamily = f"'{self.textFont}'"
|
self._fontFamily = f"'{self.textFont}'"
|
||||||
self._fontPitch = "fixed" if self.textFixed else "variable"
|
self._fontPitch = "fixed" if self.textFixed else "variable"
|
||||||
|
|
||||||
self._fSizeTitle = f"{round(2.50 * self.textSize):d}pt"
|
self._fSizeTitle = f"{round(2.50 * self.textSize):d}pt"
|
||||||
@@ -188,6 +190,7 @@ class ToOdt(Tokenizer):
|
|||||||
self._mTopHead4 = self._emToCm(self.marginHead4[0])
|
self._mTopHead4 = self._emToCm(self.marginHead4[0])
|
||||||
self._mTopHead = self._emToCm(self.marginHead4[0])
|
self._mTopHead = self._emToCm(self.marginHead4[0])
|
||||||
self._mTopText = self._emToCm(self.marginText[0])
|
self._mTopText = self._emToCm(self.marginText[0])
|
||||||
|
self._mTopMeta = self._emToCm(self.marginMeta[0])
|
||||||
|
|
||||||
self._mBotTitle = self._emToCm(self.marginTitle[1])
|
self._mBotTitle = self._emToCm(self.marginTitle[1])
|
||||||
self._mBotHead1 = self._emToCm(self.marginHead1[1])
|
self._mBotHead1 = self._emToCm(self.marginHead1[1])
|
||||||
@@ -196,13 +199,14 @@ class ToOdt(Tokenizer):
|
|||||||
self._mBotHead4 = self._emToCm(self.marginHead4[1])
|
self._mBotHead4 = self._emToCm(self.marginHead4[1])
|
||||||
self._mBotHead = self._emToCm(self.marginHead4[1])
|
self._mBotHead = self._emToCm(self.marginHead4[1])
|
||||||
self._mBotText = self._emToCm(self.marginText[1])
|
self._mBotText = self._emToCm(self.marginText[1])
|
||||||
|
self._mBotMeta = self._emToCm(self.marginMeta[1])
|
||||||
|
|
||||||
if self.colourHead:
|
if self.colourHead:
|
||||||
self._colHead12 = "#2a6099"
|
self._colHead12 = "#2a6099"
|
||||||
self._opaHead12 = "100%"
|
self._opaHead12 = "100%"
|
||||||
self._colHead34 = "#444444"
|
self._colHead34 = "#444444"
|
||||||
self._opaHead34 = "100%"
|
self._opaHead34 = "100%"
|
||||||
self._colMetaTx = "#666666"
|
self._colMetaTx = "#813709"
|
||||||
self._opaMetaTx = "100%"
|
self._opaMetaTx = "100%"
|
||||||
|
|
||||||
self._lineHeight = f"{round(100 * self.lineHeight):d}%"
|
self._lineHeight = f"{round(100 * self.lineHeight):d}%"
|
||||||
@@ -302,21 +306,28 @@ class ToOdt(Tokenizer):
|
|||||||
if tStyle is not None:
|
if tStyle is not None:
|
||||||
if tStyle & self.A_LEFT:
|
if tStyle & self.A_LEFT:
|
||||||
oStyle.setTextAlign("left")
|
oStyle.setTextAlign("left")
|
||||||
if tStyle & self.A_RIGHT:
|
elif tStyle & self.A_RIGHT:
|
||||||
oStyle.setTextAlign("right")
|
oStyle.setTextAlign("right")
|
||||||
if tStyle & self.A_CENTRE:
|
elif tStyle & self.A_CENTRE:
|
||||||
oStyle.setTextAlign("center")
|
oStyle.setTextAlign("center")
|
||||||
if tStyle & self.A_JUSTIFY:
|
elif tStyle & self.A_JUSTIFY:
|
||||||
oStyle.setTextAlign("justify")
|
oStyle.setTextAlign("justify")
|
||||||
|
|
||||||
if tStyle & self.A_PBB:
|
if tStyle & self.A_PBB:
|
||||||
oStyle.setBreakBefore("page")
|
oStyle.setBreakBefore("page")
|
||||||
if tStyle & self.A_PBB_AUT:
|
elif tStyle & self.A_PBB_AUT:
|
||||||
oStyle.setBreakBefore("auto")
|
oStyle.setBreakBefore("auto")
|
||||||
|
|
||||||
if tStyle & self.A_PBA:
|
if tStyle & self.A_PBA:
|
||||||
oStyle.setBreakAfter("page")
|
oStyle.setBreakAfter("page")
|
||||||
if tStyle & self.A_PBA_AUT:
|
elif tStyle & self.A_PBA_AUT:
|
||||||
oStyle.setBreakAfter("auto")
|
oStyle.setBreakAfter("auto")
|
||||||
|
|
||||||
|
if tStyle & self.A_Z_BTMMRG:
|
||||||
|
oStyle.setMarginBottom("0.000cm")
|
||||||
|
if tStyle & self.A_Z_TOPMRG:
|
||||||
|
oStyle.setMarginTop("0.000cm")
|
||||||
|
|
||||||
# Process Text Types
|
# Process Text Types
|
||||||
if tType == self.T_EMPTY:
|
if tType == self.T_EMPTY:
|
||||||
if hasHardBreak and parStyle is not None:
|
if hasHardBreak and parStyle is not None:
|
||||||
@@ -740,8 +751,8 @@ class ToOdt(Tokenizer):
|
|||||||
oStyle.setDisplayName("Text Meta")
|
oStyle.setDisplayName("Text Meta")
|
||||||
oStyle.setParentStyleName("Standard")
|
oStyle.setParentStyleName("Standard")
|
||||||
oStyle.setClass("text")
|
oStyle.setClass("text")
|
||||||
oStyle.setMarginTop(self._mTopText)
|
oStyle.setMarginTop(self._mTopMeta)
|
||||||
oStyle.setMarginBottom(self._mBotText)
|
oStyle.setMarginBottom(self._mBotMeta)
|
||||||
oStyle.setLineHeight(self._lineHeight)
|
oStyle.setLineHeight(self._lineHeight)
|
||||||
oStyle.setFontName(self.textFont)
|
oStyle.setFontName(self.textFont)
|
||||||
oStyle.setFontFamily(self._fontFamily)
|
oStyle.setFontFamily(self._fontFamily)
|
||||||
|
|||||||
+125
-143
@@ -79,7 +79,6 @@ class GuiBuildNovel(QDialog):
|
|||||||
|
|
||||||
self.htmlText = [] # List of html documents
|
self.htmlText = [] # List of html documents
|
||||||
self.htmlStyle = [] # List of html styles
|
self.htmlStyle = [] # List of html styles
|
||||||
self.nwdText = [] # List of markdown documents
|
|
||||||
self.htmlSize = 0 # Size of the html document
|
self.htmlSize = 0 # Size of the html document
|
||||||
self.buildTime = 0 # The timestamp of the last build
|
self.buildTime = 0 # The timestamp of the last build
|
||||||
|
|
||||||
@@ -532,7 +531,6 @@ class GuiBuildNovel(QDialog):
|
|||||||
else:
|
else:
|
||||||
self.htmlText = []
|
self.htmlText = []
|
||||||
self.htmlStyle = []
|
self.htmlStyle = []
|
||||||
self.nwdText = []
|
|
||||||
self.buildTime = 0
|
self.buildTime = 0
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -552,34 +550,26 @@ class GuiBuildNovel(QDialog):
|
|||||||
textSize = self.textSize.value()
|
textSize = self.textSize.value()
|
||||||
replaceTabs = self.replaceTabs.isChecked()
|
replaceTabs = self.replaceTabs.isChecked()
|
||||||
|
|
||||||
tStart = int(time())
|
|
||||||
|
|
||||||
self.htmlText = []
|
self.htmlText = []
|
||||||
self.htmlStyle = []
|
self.htmlStyle = []
|
||||||
self.nwdText = []
|
|
||||||
self.htmlSize = 0
|
self.htmlSize = 0
|
||||||
|
|
||||||
|
# Build Preview
|
||||||
|
# =============
|
||||||
|
|
||||||
makeHtml = ToHtml(self.theProject, self.theParent)
|
makeHtml = ToHtml(self.theProject, self.theParent)
|
||||||
self._doBuild(makeHtml)
|
self._doBuild(makeHtml, isPreview=True)
|
||||||
|
|
||||||
if replaceTabs:
|
if replaceTabs:
|
||||||
htmlText = []
|
makeHtml.replaceTabs()
|
||||||
eightSpace = " "*8
|
|
||||||
for aLine in self.htmlText:
|
|
||||||
htmlText.append(aLine.replace("\t", eightSpace))
|
|
||||||
self.htmlText = htmlText
|
|
||||||
|
|
||||||
nwdText = []
|
self.htmlText = makeHtml.fullHTML
|
||||||
for aLine in self.nwdText:
|
|
||||||
nwdText.append(aLine.replace("\t", " "))
|
|
||||||
self.nwdText = nwdText
|
|
||||||
|
|
||||||
tEnd = int(time())
|
|
||||||
logger.debug("Built project in %.3f ms" % (1000*(tEnd - tStart)))
|
|
||||||
self.htmlStyle = makeHtml.getStyleSheet()
|
self.htmlStyle = makeHtml.getStyleSheet()
|
||||||
self.buildTime = tEnd
|
self.htmlSize = makeHtml.getFullResultSize()
|
||||||
|
self.buildTime = int(time())
|
||||||
|
|
||||||
|
# Load Preview
|
||||||
|
# ============
|
||||||
|
|
||||||
# Load the preview document with the html data
|
|
||||||
self.docView.setTextFont(textFont, textSize)
|
self.docView.setTextFont(textFont, textSize)
|
||||||
self.docView.setJustify(justifyText)
|
self.docView.setJustify(justifyText)
|
||||||
if noStyling:
|
if noStyling:
|
||||||
@@ -600,9 +590,11 @@ class GuiBuildNovel(QDialog):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def _doBuild(self, bldObj):
|
def _doBuild(self, bldObj, isPreview=False, doConvert=True):
|
||||||
"""Rund the build with a specific build object.
|
"""Rund the build with a specific build object.
|
||||||
"""
|
"""
|
||||||
|
tStart = int(time())
|
||||||
|
|
||||||
# Get Settings
|
# Get Settings
|
||||||
fmtTitle = self.fmtTitle.text().strip()
|
fmtTitle = self.fmtTitle.text().strip()
|
||||||
fmtChapter = self.fmtChapter.text().strip()
|
fmtChapter = self.fmtChapter.text().strip()
|
||||||
@@ -644,7 +636,6 @@ class GuiBuildNovel(QDialog):
|
|||||||
|
|
||||||
if isHtml:
|
if isHtml:
|
||||||
bldObj.setStyles(not noStyling)
|
bldObj.setStyles(not noStyling)
|
||||||
self.htmlSize = 0
|
|
||||||
|
|
||||||
if isOdt:
|
if isOdt:
|
||||||
bldObj.setColourHeaders(not noStyling)
|
bldObj.setColourHeaders(not noStyling)
|
||||||
@@ -667,31 +658,27 @@ class GuiBuildNovel(QDialog):
|
|||||||
if noteRoot:
|
if noteRoot:
|
||||||
# Add headers for root folders of notes
|
# Add headers for root folders of notes
|
||||||
bldObj.addRootHeading(tItem.itemHandle)
|
bldObj.addRootHeading(tItem.itemHandle)
|
||||||
bldObj.doConvert()
|
if doConvert:
|
||||||
if isHtml:
|
bldObj.doConvert()
|
||||||
self.htmlText.append(bldObj.getResult())
|
|
||||||
self.nwdText.append(bldObj.getFilteredMarkdown())
|
|
||||||
self.htmlSize += bldObj.getResultSize()
|
|
||||||
|
|
||||||
elif self._checkInclude(tItem, noteFiles, novelFiles, ignoreFlag):
|
elif self._checkInclude(tItem, noteFiles, novelFiles, ignoreFlag):
|
||||||
bldObj.setText(tItem.itemHandle)
|
bldObj.setText(tItem.itemHandle)
|
||||||
bldObj.doAutoReplace()
|
bldObj.doAutoReplace()
|
||||||
bldObj.tokenizeText()
|
bldObj.tokenizeText()
|
||||||
bldObj.doHeaders()
|
bldObj.doHeaders()
|
||||||
bldObj.doConvert()
|
if doConvert:
|
||||||
|
bldObj.doConvert()
|
||||||
bldObj.doPostProcessing()
|
bldObj.doPostProcessing()
|
||||||
if isHtml:
|
|
||||||
self.htmlText.append(bldObj.getResult())
|
|
||||||
self.nwdText.append(bldObj.getFilteredMarkdown())
|
|
||||||
self.htmlSize += bldObj.getResultSize()
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Failed to generate html of document '%s'" % tItem.itemHandle)
|
logger.error("Failed to generate html of document '%s'" % tItem.itemHandle)
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
self.docView.setText((
|
if isPreview:
|
||||||
"Failed to generate preview. "
|
self.docView.setText((
|
||||||
"Document with title '%s' could not be parsed."
|
"Failed to generate preview. "
|
||||||
) % tItem.itemName)
|
"Document with title '%s' could not be parsed."
|
||||||
|
) % tItem.itemName)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Update progress bar, also for skipped items
|
# Update progress bar, also for skipped items
|
||||||
@@ -700,6 +687,9 @@ class GuiBuildNovel(QDialog):
|
|||||||
if isOdt:
|
if isOdt:
|
||||||
bldObj.closeDocument()
|
bldObj.closeDocument()
|
||||||
|
|
||||||
|
tEnd = int(time())
|
||||||
|
logger.debug("Built project in %.3f ms" % (1000*(tEnd - tStart)))
|
||||||
|
|
||||||
if bldObj.errData:
|
if bldObj.errData:
|
||||||
self.theParent.makeAlert((
|
self.theParent.makeAlert((
|
||||||
"There were problems when building the project:"
|
"There were problems when building the project:"
|
||||||
@@ -751,63 +741,59 @@ class GuiBuildNovel(QDialog):
|
|||||||
def _saveDocument(self, theFormat):
|
def _saveDocument(self, theFormat):
|
||||||
"""Save the document to various formats.
|
"""Save the document to various formats.
|
||||||
"""
|
"""
|
||||||
|
replaceTabs = self.replaceTabs.isChecked()
|
||||||
|
|
||||||
byteFmt = QByteArray()
|
byteFmt = QByteArray()
|
||||||
fileExt = ""
|
fileExt = ""
|
||||||
textFmt = ""
|
textFmt = ""
|
||||||
outTool = ""
|
|
||||||
|
|
||||||
# Create the settings
|
# Settings
|
||||||
|
# ========
|
||||||
|
|
||||||
if theFormat == self.FMT_ODT:
|
if theFormat == self.FMT_ODT:
|
||||||
fileExt = "odt"
|
fileExt = "odt"
|
||||||
textFmt = "Open Document"
|
textFmt = "Open Document"
|
||||||
outTool = "NW_ODT"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_FODT:
|
elif theFormat == self.FMT_FODT:
|
||||||
fileExt = "fodt"
|
fileExt = "fodt"
|
||||||
textFmt = "Flat Open Document"
|
textFmt = "Flat Open Document"
|
||||||
outTool = "NW_ODT"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_PDF:
|
elif theFormat == self.FMT_PDF:
|
||||||
fileExt = "pdf"
|
fileExt = "pdf"
|
||||||
textFmt = "PDF"
|
textFmt = "PDF"
|
||||||
outTool = "QtPrint"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_HTM:
|
elif theFormat == self.FMT_HTM:
|
||||||
fileExt = "htm"
|
fileExt = "htm"
|
||||||
textFmt = "Plain HTML"
|
textFmt = "Plain HTML"
|
||||||
outTool = "NW"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_MD:
|
elif theFormat == self.FMT_MD:
|
||||||
byteFmt.append("markdown")
|
byteFmt.append("markdown")
|
||||||
fileExt = "md"
|
fileExt = "md"
|
||||||
textFmt = "Markdown"
|
textFmt = "Markdown"
|
||||||
outTool = "Qt"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_NWD:
|
elif theFormat == self.FMT_NWD:
|
||||||
fileExt = "nwd"
|
fileExt = "nwd"
|
||||||
textFmt = "%s Markdown" % nw.__package__
|
textFmt = "%s Markdown" % nw.__package__
|
||||||
outTool = "NW"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_TXT:
|
elif theFormat == self.FMT_TXT:
|
||||||
byteFmt.append("plaintext")
|
byteFmt.append("plaintext")
|
||||||
fileExt = "txt"
|
fileExt = "txt"
|
||||||
textFmt = "Plain Text"
|
textFmt = "Plain Text"
|
||||||
outTool = "Qt"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_JSON_H:
|
elif theFormat == self.FMT_JSON_H:
|
||||||
fileExt = "json"
|
fileExt = "json"
|
||||||
textFmt = "JSON + %s HTML" % nw.__package__
|
textFmt = "JSON + %s HTML" % nw.__package__
|
||||||
outTool = "NW"
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_JSON_M:
|
elif theFormat == self.FMT_JSON_M:
|
||||||
fileExt = "json"
|
fileExt = "json"
|
||||||
textFmt = "JSON + %s Markdown" % nw.__package__
|
textFmt = "JSON + %s Markdown" % nw.__package__
|
||||||
outTool = "NW"
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Generate the file name
|
# Generate File Name
|
||||||
|
# ==================
|
||||||
|
|
||||||
if fileExt:
|
if fileExt:
|
||||||
|
|
||||||
cleanName = makeFileNameSafe(self.theProject.projName)
|
cleanName = makeFileNameSafe(self.theProject.projName)
|
||||||
@@ -830,109 +816,109 @@ class GuiBuildNovel(QDialog):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Do the actual writing
|
# Build and Write
|
||||||
wSuccess = False
|
# ===============
|
||||||
|
|
||||||
errMsg = ""
|
errMsg = ""
|
||||||
if outTool == "Qt":
|
wSuccess = False
|
||||||
|
|
||||||
|
if theFormat == self.FMT_MD or theFormat == self.FMT_TXT:
|
||||||
docWriter = QTextDocumentWriter()
|
docWriter = QTextDocumentWriter()
|
||||||
docWriter.setFileName(savePath)
|
docWriter.setFileName(savePath)
|
||||||
docWriter.setFormat(byteFmt)
|
docWriter.setFormat(byteFmt)
|
||||||
wSuccess = docWriter.write(self.docView.qDocument)
|
wSuccess = docWriter.write(self.docView.qDocument)
|
||||||
|
|
||||||
elif outTool == "NW":
|
elif theFormat == self.FMT_HTM:
|
||||||
|
makeHtml = ToHtml(self.theProject, self.theParent)
|
||||||
|
self._doBuild(makeHtml)
|
||||||
|
if replaceTabs:
|
||||||
|
makeHtml.replaceTabs()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(savePath, mode="w", encoding="utf8") as outFile:
|
makeHtml.saveHTML5(savePath)
|
||||||
if theFormat == self.FMT_HTM:
|
|
||||||
# Write novelWriter HTML data
|
|
||||||
theStyle = self.htmlStyle.copy()
|
|
||||||
theStyle.append(r"article {width: 800px; margin: 40px auto;}")
|
|
||||||
bodyText = "".join(self.htmlText)
|
|
||||||
bodyText = bodyText.replace("\t", "	")
|
|
||||||
|
|
||||||
theHtml = (
|
|
||||||
"<!DOCTYPE html>\n"
|
|
||||||
"<html>\n"
|
|
||||||
"<head>\n"
|
|
||||||
"<meta charset='utf-8'>\n"
|
|
||||||
"<title>{projTitle:s}</title>\n"
|
|
||||||
"</head>\n"
|
|
||||||
"<style>\n"
|
|
||||||
"{htmlStyle:s}\n"
|
|
||||||
"</style>\n"
|
|
||||||
"<body>\n"
|
|
||||||
"<article>\n"
|
|
||||||
"{bodyText:s}\n"
|
|
||||||
"</article>\n"
|
|
||||||
"</body>\n"
|
|
||||||
"</html>\n"
|
|
||||||
).format(
|
|
||||||
projTitle = self.theProject.projName,
|
|
||||||
htmlStyle = "\n".join(theStyle),
|
|
||||||
bodyText = bodyText,
|
|
||||||
)
|
|
||||||
outFile.write(theHtml)
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_NWD:
|
|
||||||
# Write novelWriter markdown data
|
|
||||||
for aLine in self.nwdText:
|
|
||||||
outFile.write(aLine)
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_JSON_H or theFormat == self.FMT_JSON_M:
|
|
||||||
jsonData = {
|
|
||||||
"meta" : {
|
|
||||||
"workingTitle" : self.theProject.projName,
|
|
||||||
"novelTitle" : self.theProject.bookTitle,
|
|
||||||
"authors" : self.theProject.bookAuthors,
|
|
||||||
"buildTime" : self.buildTime,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if theFormat == self.FMT_JSON_H:
|
|
||||||
theBody = []
|
|
||||||
for htmlPage in self.htmlText:
|
|
||||||
theBody.append(htmlPage.rstrip("\n").split("\n"))
|
|
||||||
jsonData["text"] = {
|
|
||||||
"css" : self.htmlStyle,
|
|
||||||
"html" : theBody,
|
|
||||||
}
|
|
||||||
elif theFormat == self.FMT_JSON_M:
|
|
||||||
theBody = []
|
|
||||||
for nwdPage in self.nwdText:
|
|
||||||
theBody.append(nwdPage.split("\n"))
|
|
||||||
jsonData["text"] = {
|
|
||||||
"nwd" : theBody,
|
|
||||||
}
|
|
||||||
|
|
||||||
outFile.write(json.dumps(jsonData, indent=2))
|
|
||||||
|
|
||||||
wSuccess = True
|
wSuccess = True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
errMsg = str(e)
|
errMsg = str(e)
|
||||||
|
|
||||||
elif outTool == "NW_ODT":
|
elif theFormat == self.FMT_NWD:
|
||||||
|
makeNwd = ToHtml(self.theProject, self.theParent)
|
||||||
|
makeNwd.setKeepMarkdown(True)
|
||||||
|
self._doBuild(makeNwd, doConvert=False)
|
||||||
|
if replaceTabs:
|
||||||
|
makeNwd.replaceTabs(spaceChar=" ")
|
||||||
|
|
||||||
if theFormat == self.FMT_FODT:
|
try:
|
||||||
makeOdt = ToOdt(self.theProject, self.theParent, isFlat=True)
|
with open(savePath, mode="w", encoding="utf8") as outFile:
|
||||||
self._doBuild(makeOdt)
|
for nwdPage in makeNwd.theMarkdown:
|
||||||
try:
|
outFile.write(nwdPage)
|
||||||
makeOdt.saveFlatXML(savePath)
|
wSuccess = True
|
||||||
|
except Exception as e:
|
||||||
|
errMsg = str(e)
|
||||||
|
|
||||||
|
elif theFormat == self.FMT_FODT:
|
||||||
|
makeOdt = ToOdt(self.theProject, self.theParent, isFlat=True)
|
||||||
|
self._doBuild(makeOdt)
|
||||||
|
try:
|
||||||
|
makeOdt.saveFlatXML(savePath)
|
||||||
|
wSuccess = True
|
||||||
|
except Exception as e:
|
||||||
|
errMsg = str(e)
|
||||||
|
|
||||||
|
elif theFormat == self.FMT_ODT:
|
||||||
|
makeOdt = ToOdt(self.theProject, self.theParent, isFlat=False)
|
||||||
|
self._doBuild(makeOdt)
|
||||||
|
try:
|
||||||
|
makeOdt.saveOpenDocText(savePath)
|
||||||
|
wSuccess = True
|
||||||
|
except Exception as e:
|
||||||
|
errMsg = str(e)
|
||||||
|
|
||||||
|
elif theFormat == self.FMT_JSON_H or theFormat == self.FMT_JSON_M:
|
||||||
|
jsonData = {
|
||||||
|
"meta" : {
|
||||||
|
"workingTitle" : self.theProject.projName,
|
||||||
|
"novelTitle" : self.theProject.bookTitle,
|
||||||
|
"authors" : self.theProject.bookAuthors,
|
||||||
|
"buildTime" : self.buildTime,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if theFormat == self.FMT_JSON_H:
|
||||||
|
makeHtml = ToHtml(self.theProject, self.theParent)
|
||||||
|
self._doBuild(makeHtml)
|
||||||
|
if replaceTabs:
|
||||||
|
makeHtml.replaceTabs()
|
||||||
|
|
||||||
|
theBody = []
|
||||||
|
for htmlPage in makeHtml.fullHTML:
|
||||||
|
theBody.append(htmlPage.rstrip("\n").split("\n"))
|
||||||
|
jsonData["text"] = {
|
||||||
|
"css" : self.htmlStyle,
|
||||||
|
"html" : theBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
elif theFormat == self.FMT_JSON_M:
|
||||||
|
makeNwd = ToHtml(self.theProject, self.theParent)
|
||||||
|
makeNwd.setKeepMarkdown(True)
|
||||||
|
self._doBuild(makeNwd, doConvert=False)
|
||||||
|
if replaceTabs:
|
||||||
|
makeNwd.replaceTabs(spaceChar=" ")
|
||||||
|
|
||||||
|
theBody = []
|
||||||
|
for nwdPage in makeNwd.theMarkdown:
|
||||||
|
theBody.append(nwdPage.split("\n"))
|
||||||
|
jsonData["text"] = {
|
||||||
|
"nwd" : theBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(savePath, mode="w", encoding="utf8") as outFile:
|
||||||
|
outFile.write(json.dumps(jsonData, indent=2))
|
||||||
wSuccess = True
|
wSuccess = True
|
||||||
|
except Exception as e:
|
||||||
|
errMsg = str(e)
|
||||||
|
|
||||||
except Exception as e:
|
elif theFormat == self.FMT_PDF:
|
||||||
errMsg = str(e)
|
|
||||||
|
|
||||||
elif theFormat == self.FMT_ODT:
|
|
||||||
makeOdt = ToOdt(self.theProject, self.theParent, isFlat=False)
|
|
||||||
self._doBuild(makeOdt)
|
|
||||||
try:
|
|
||||||
makeOdt.saveOpenDocText(savePath)
|
|
||||||
wSuccess = True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
errMsg = str(e)
|
|
||||||
|
|
||||||
elif outTool == "QtPrint" and theFormat == self.FMT_PDF:
|
|
||||||
try:
|
try:
|
||||||
thePrinter = QPrinter()
|
thePrinter = QPrinter()
|
||||||
thePrinter.setOutputFormat(QPrinter.PdfFormat)
|
thePrinter.setOutputFormat(QPrinter.PdfFormat)
|
||||||
@@ -1021,13 +1007,10 @@ class GuiBuildNovel(QDialog):
|
|||||||
if "htmlStyle" in theData.keys():
|
if "htmlStyle" in theData.keys():
|
||||||
self.htmlStyle = theData["htmlStyle"]
|
self.htmlStyle = theData["htmlStyle"]
|
||||||
dataCount += 1
|
dataCount += 1
|
||||||
if "nwdText" in theData.keys():
|
|
||||||
self.nwdText = theData["nwdText"]
|
|
||||||
dataCount += 1
|
|
||||||
if "buildTime" in theData.keys():
|
if "buildTime" in theData.keys():
|
||||||
self.buildTime = theData["buildTime"]
|
self.buildTime = theData["buildTime"]
|
||||||
|
|
||||||
return dataCount == 3
|
return dataCount == 2
|
||||||
|
|
||||||
def _saveCache(self):
|
def _saveCache(self):
|
||||||
"""Save the current data to cache.
|
"""Save the current data to cache.
|
||||||
@@ -1040,7 +1023,6 @@ class GuiBuildNovel(QDialog):
|
|||||||
outFile.write(json.dumps({
|
outFile.write(json.dumps({
|
||||||
"htmlText" : self.htmlText,
|
"htmlText" : self.htmlText,
|
||||||
"htmlStyle" : self.htmlStyle,
|
"htmlStyle" : self.htmlStyle,
|
||||||
"nwdText" : self.nwdText,
|
|
||||||
"buildTime" : self.buildTime,
|
"buildTime" : self.buildTime,
|
||||||
}, indent=2))
|
}, indent=2))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user