Added printing and save to PDF, and made some changes to the tohtml class
This commit is contained in:
+38
-24
@@ -30,15 +30,19 @@ import re
|
|||||||
import nw
|
import nw
|
||||||
|
|
||||||
from nw.core.tokenizer import Tokenizer
|
from nw.core.tokenizer import Tokenizer
|
||||||
from nw.constants import nwUnicode, nwLabels
|
from nw.constants import nwUnicode, nwLabels, nwKeyWords
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class ToHtml(Tokenizer):
|
class ToHtml(Tokenizer):
|
||||||
|
|
||||||
|
M_PREVIEW = 0 # Tweak output for the DocViewer
|
||||||
|
M_EXPORT = 1 # Tweak output for saving to HTML or printing
|
||||||
|
M_EBOOK = 2 # Tweak output for converting to epub
|
||||||
|
|
||||||
def __init__(self, theProject, theParent):
|
def __init__(self, theProject, theParent):
|
||||||
Tokenizer.__init__(self, theProject, theParent)
|
Tokenizer.__init__(self, theProject, theParent)
|
||||||
self.forPreview = False
|
self.genMode = self.M_EXPORT
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -47,11 +51,11 @@ class ToHtml(Tokenizer):
|
|||||||
|
|
||||||
def setPreview(self, forPreview, doComments):
|
def setPreview(self, forPreview, doComments):
|
||||||
"""If we're using this class to generate markdown preview, we
|
"""If we're using this class to generate markdown preview, we
|
||||||
need to make a few changes to formatting, which is selected by
|
need to make a few changes to formatting, which is managed by
|
||||||
this flag.
|
these flags.
|
||||||
"""
|
"""
|
||||||
self.forPreview = forPreview
|
|
||||||
if forPreview:
|
if forPreview:
|
||||||
|
self.genMode = self.M_PREVIEW
|
||||||
self.doKeywords = True
|
self.doKeywords = True
|
||||||
self.doComments = doComments
|
self.doComments = doComments
|
||||||
return
|
return
|
||||||
@@ -66,7 +70,7 @@ class ToHtml(Tokenizer):
|
|||||||
"""
|
"""
|
||||||
Tokenizer.doAutoReplace(self)
|
Tokenizer.doAutoReplace(self)
|
||||||
|
|
||||||
if self.forPreview:
|
if self.genMode == self.M_PREVIEW:
|
||||||
tabFmt = " "*8
|
tabFmt = " "*8
|
||||||
else:
|
else:
|
||||||
tabFmt = " "
|
tabFmt = " "
|
||||||
@@ -102,6 +106,7 @@ class ToHtml(Tokenizer):
|
|||||||
|
|
||||||
self.theResult = ""
|
self.theResult = ""
|
||||||
thisPar = []
|
thisPar = []
|
||||||
|
parStyle = ""
|
||||||
for tType, tText, tFormat, tStyle in self.theTokens:
|
for tType, tText, tFormat, tStyle in self.theTokens:
|
||||||
|
|
||||||
# Styles
|
# Styles
|
||||||
@@ -141,8 +146,9 @@ class ToHtml(Tokenizer):
|
|||||||
if tType == self.T_EMPTY:
|
if tType == self.T_EMPTY:
|
||||||
if len(thisPar) > 0:
|
if len(thisPar) > 0:
|
||||||
tTemp = "".join(thisPar)
|
tTemp = "".join(thisPar)
|
||||||
self.theResult += "<p%s>%s</p>\n" % (hStyle,tTemp.rstrip())
|
self.theResult += "<p%s>%s</p>\n" % (parStyle,tTemp.rstrip())
|
||||||
thisPar = []
|
thisPar = []
|
||||||
|
parStyle = ""
|
||||||
|
|
||||||
elif tType == self.T_HEAD1:
|
elif tType == self.T_HEAD1:
|
||||||
tHead = tText.replace(r"\\", "<br/>")
|
tHead = tText.replace(r"\\", "<br/>")
|
||||||
@@ -164,13 +170,11 @@ class ToHtml(Tokenizer):
|
|||||||
self.theResult += "<p%s>%s</p>\n" % (hStyle, tText)
|
self.theResult += "<p%s>%s</p>\n" % (hStyle, tText)
|
||||||
|
|
||||||
elif tType == self.T_SKIP:
|
elif tType == self.T_SKIP:
|
||||||
self.theResult += "<p> </p>\n"
|
self.theResult += "<p%s> </p>\n" % hStyle
|
||||||
|
|
||||||
elif tType == self.T_PBREAK:
|
|
||||||
self.theResult += "<p style='page-break-after: always;'> </p>\n"
|
|
||||||
|
|
||||||
elif tType == self.T_TEXT:
|
elif tType == self.T_TEXT:
|
||||||
tTemp = tText
|
tTemp = tText
|
||||||
|
parStyle = hStyle
|
||||||
for xPos, xLen, xFmt in reversed(tFormat):
|
for xPos, xLen, xFmt in reversed(tFormat):
|
||||||
tTemp = tTemp[:xPos]+htmlTags[xFmt]+tTemp[xPos+xLen:]
|
tTemp = tTemp[:xPos]+htmlTags[xFmt]+tTemp[xPos+xLen:]
|
||||||
if tText.endswith(" "):
|
if tText.endswith(" "):
|
||||||
@@ -196,20 +200,18 @@ class ToHtml(Tokenizer):
|
|||||||
def _formatSynopsis(self, tText):
|
def _formatSynopsis(self, tText):
|
||||||
"""Apply HTML formatting to synopsis.
|
"""Apply HTML formatting to synopsis.
|
||||||
"""
|
"""
|
||||||
|
if self.genMode == self.M_EXPORT:
|
||||||
if not self.forPreview:
|
|
||||||
return "<p class='synopsis'><strong>Synopsis: </strong>%s</p>\n" % tText
|
return "<p class='synopsis'><strong>Synopsis: </strong>%s</p>\n" % tText
|
||||||
|
else:
|
||||||
return "<p class='comment'>%s</p>\n" % tText
|
return "<p class='comment'>%s</p>\n" % tText
|
||||||
|
|
||||||
def _formatComments(self, tText):
|
def _formatComments(self, tText):
|
||||||
"""Apply HTML formatting to comments.
|
"""Apply HTML formatting to comments.
|
||||||
"""
|
"""
|
||||||
|
if self.genMode == self.M_EXPORT:
|
||||||
if not self.forPreview:
|
|
||||||
return "<p class='comment'><strong>Comment: </strong>%s</p>\n" % tText
|
return "<p class='comment'><strong>Comment: </strong>%s</p>\n" % tText
|
||||||
|
else:
|
||||||
return "<p class='comment'>%s</p>\n" % tText
|
return "<p class='comment'>%s</p>\n" % tText
|
||||||
|
|
||||||
def _formatKeywords(self, tText):
|
def _formatKeywords(self, tText):
|
||||||
"""Apply HTML formatting to keywords.
|
"""Apply HTML formatting to keywords.
|
||||||
@@ -224,11 +226,23 @@ class ToHtml(Tokenizer):
|
|||||||
refTags = []
|
refTags = []
|
||||||
if theBits[0] in nwLabels.KEY_NAME:
|
if theBits[0] in nwLabels.KEY_NAME:
|
||||||
retText += "<span class='tags'>%s:</span> " % nwLabels.KEY_NAME[theBits[0]]
|
retText += "<span class='tags'>%s:</span> " % nwLabels.KEY_NAME[theBits[0]]
|
||||||
for tTag in theBits[1:]:
|
if self.genMode == self.M_PREVIEW:
|
||||||
refTags.append("<a href='#%s=%s'>%s</a>" % (
|
for tTag in theBits[1:]:
|
||||||
theBits[0][1:], tTag, tTag
|
refTags.append("<a href='#%s=%s'>%s</a>" % (
|
||||||
))
|
theBits[0][1:], tTag, tTag
|
||||||
retText += ", ".join(refTags)
|
))
|
||||||
|
retText += ", ".join(refTags)
|
||||||
|
else:
|
||||||
|
if theBits[0] == nwKeyWords.TAG_KEY:
|
||||||
|
retText += "<a name='tag_%s'/>%s" % (
|
||||||
|
theBits[1], theBits[1]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for tTag in theBits[1:]:
|
||||||
|
refTags.append("<a href='#tag_%s'>%s</a>" % (
|
||||||
|
tTag, tTag
|
||||||
|
))
|
||||||
|
retText += ", ".join(refTags)
|
||||||
|
|
||||||
return "<div>%s</div>" % retText
|
return "<div>%s</div>" % retText
|
||||||
|
|
||||||
|
|||||||
+72
-123
@@ -58,7 +58,6 @@ class Tokenizer():
|
|||||||
T_TEXT = 9 # Text line
|
T_TEXT = 9 # Text line
|
||||||
T_SEP = 10 # Scene separator
|
T_SEP = 10 # Scene separator
|
||||||
T_SKIP = 11 # Paragraph break
|
T_SKIP = 11 # Paragraph break
|
||||||
T_PBREAK = 12 # Page break
|
|
||||||
|
|
||||||
A_LEFT = 1 # Left aligned
|
A_LEFT = 1 # Left aligned
|
||||||
A_RIGHT = 2 # Right aligned
|
A_RIGHT = 2 # Right aligned
|
||||||
@@ -108,6 +107,18 @@ class Tokenizer():
|
|||||||
self.numAbsScene = 0 # Counter for scene number within novel
|
self.numAbsScene = 0 # Counter for scene number within novel
|
||||||
self.firstScene = False # Flag to indicate that the first scene of the chapter
|
self.firstScene = False # Flag to indicate that the first scene of the chapter
|
||||||
|
|
||||||
|
# This File
|
||||||
|
self.isNone = False
|
||||||
|
self.isTitle = False
|
||||||
|
self.isBook = False
|
||||||
|
self.isPage = False
|
||||||
|
self.isPart = False
|
||||||
|
self.isUnNum = False
|
||||||
|
self.isChap = False
|
||||||
|
self.isScene = False
|
||||||
|
self.isNote = False
|
||||||
|
self.isNovel = False
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def clearData(self):
|
def clearData(self):
|
||||||
@@ -121,6 +132,18 @@ class Tokenizer():
|
|||||||
self.theResult = None
|
self.theResult = None
|
||||||
self.numChapter = 0
|
self.numChapter = 0
|
||||||
self.firstScene = False
|
self.firstScene = False
|
||||||
|
|
||||||
|
self.isNone = False
|
||||||
|
self.isTitle = False
|
||||||
|
self.isBook = False
|
||||||
|
self.isPage = False
|
||||||
|
self.isPart = False
|
||||||
|
self.isUnNum = False
|
||||||
|
self.isChap = False
|
||||||
|
self.isScene = False
|
||||||
|
self.isNote = False
|
||||||
|
self.isNovel = False
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -189,6 +212,17 @@ class Tokenizer():
|
|||||||
theDocument = NWDoc(self.theProject, self.theParent)
|
theDocument = NWDoc(self.theProject, self.theParent)
|
||||||
self.theText = theDocument.openDocument(theHandle)
|
self.theText = theDocument.openDocument(theHandle)
|
||||||
|
|
||||||
|
self.isNone = self.theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
|
self.isTitle = self.theItem.itemLayout == nwItemLayout.TITLE
|
||||||
|
self.isBook = self.theItem.itemLayout == nwItemLayout.BOOK
|
||||||
|
self.isPage = self.theItem.itemLayout == nwItemLayout.PAGE
|
||||||
|
self.isPart = self.theItem.itemLayout == nwItemLayout.PARTITION
|
||||||
|
self.isUnNum = self.theItem.itemLayout == nwItemLayout.UNNUMBERED
|
||||||
|
self.isChap = self.theItem.itemLayout == nwItemLayout.CHAPTER
|
||||||
|
self.isScene = self.theItem.itemLayout == nwItemLayout.SCENE
|
||||||
|
self.isNote = self.theItem.itemLayout == nwItemLayout.NOTE
|
||||||
|
self.isNovel = self.isBook or self.isUnNum or self.isChap or self.isScene
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def getResult(self):
|
def getResult(self):
|
||||||
@@ -251,61 +285,37 @@ 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, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
))
|
))
|
||||||
elif aLine[0] == "%":
|
elif aLine[0] == "%":
|
||||||
cLine = aLine[1:].strip()
|
cLine = aLine[1:].strip()
|
||||||
if cLine.lower().startswith("synopsis:"):
|
if cLine.lower().startswith("synopsis:"):
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_SYNOPSIS,
|
self.T_SYNOPSIS, cLine[9:].strip(), None, defAlign
|
||||||
cLine[9:].strip(),
|
|
||||||
None,
|
|
||||||
defAlign
|
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_COMMENT,
|
self.T_COMMENT, aLine[1:].strip(), None, defAlign
|
||||||
aLine[1:].strip(),
|
|
||||||
None,
|
|
||||||
defAlign
|
|
||||||
))
|
))
|
||||||
elif aLine[0] == "@":
|
elif aLine[0] == "@":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_KEYWORD,
|
self.T_KEYWORD, aLine[1:].strip(), None, self.A_LEFT
|
||||||
aLine[1:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_LEFT
|
|
||||||
))
|
))
|
||||||
elif aLine[:2] == "# ":
|
elif aLine[:2] == "# ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD1,
|
self.T_HEAD1, aLine[2:].strip(), None, self.A_LEFT | self.A_PBB
|
||||||
aLine[2:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBB
|
|
||||||
))
|
))
|
||||||
elif aLine[:3] == "## ":
|
elif aLine[:3] == "## ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD2,
|
self.T_HEAD2, aLine[3:].strip(), None, self.A_LEFT | self.A_PBA_AV
|
||||||
aLine[3:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBA_AV
|
|
||||||
))
|
))
|
||||||
elif aLine[:4] == "### ":
|
elif aLine[:4] == "### ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD3,
|
self.T_HEAD3, aLine[4:].strip(), None, self.A_LEFT | self.A_PBA_AV
|
||||||
aLine[4:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBA_AV
|
|
||||||
))
|
))
|
||||||
elif aLine[:5] == "#### ":
|
elif aLine[:5] == "#### ":
|
||||||
self.theTokens.append((
|
self.theTokens.append((
|
||||||
self.T_HEAD4,
|
self.T_HEAD4, aLine[5:].strip(), None, self.A_LEFT | self.A_PBA_AV
|
||||||
aLine[5:].strip(),
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBA_AV
|
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
if not self.doBodyText:
|
if not self.doBodyText:
|
||||||
@@ -328,18 +338,12 @@ 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, aLine, fmtPos, defAlign
|
||||||
aLine,
|
|
||||||
fmtPos,
|
|
||||||
defAlign
|
|
||||||
))
|
))
|
||||||
|
|
||||||
# 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, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
))
|
))
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -349,23 +353,13 @@ class Tokenizer():
|
|||||||
layout and user settings.
|
layout and user settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
isNone = self.theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
|
||||||
isTitle = self.theItem.itemLayout == nwItemLayout.TITLE
|
|
||||||
isBook = self.theItem.itemLayout == nwItemLayout.BOOK
|
|
||||||
isPage = self.theItem.itemLayout == nwItemLayout.PAGE
|
|
||||||
isPart = self.theItem.itemLayout == nwItemLayout.PARTITION
|
|
||||||
isUnNum = self.theItem.itemLayout == nwItemLayout.UNNUMBERED
|
|
||||||
isChap = self.theItem.itemLayout == nwItemLayout.CHAPTER
|
|
||||||
isScene = self.theItem.itemLayout == nwItemLayout.SCENE
|
|
||||||
isNote = self.theItem.itemLayout == nwItemLayout.NOTE
|
|
||||||
|
|
||||||
# No special header formatting for notes and no-layout files
|
# No special header formatting for notes and no-layout files
|
||||||
if isNone or isNote:
|
if self.isNone or self.isNote:
|
||||||
return
|
return
|
||||||
|
|
||||||
# For novel files, we need to handle chapter numbering and scene
|
# For novel files, we need to handle chapter numbering and scene
|
||||||
# breaks
|
# breaks
|
||||||
if isBook or isUnNum or isChap or isScene:
|
if self.isNovel:
|
||||||
for n in range(len(self.theTokens)):
|
for n in range(len(self.theTokens)):
|
||||||
|
|
||||||
tToken = self.theTokens[n]
|
tToken = self.theTokens[n]
|
||||||
@@ -382,10 +376,7 @@ class Tokenizer():
|
|||||||
|
|
||||||
tText = self._formatHeading(self.fmtTitle, tText)
|
tText = self._formatHeading(self.fmtTitle, tText)
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tType,
|
tType, tText, None, self.A_LEFT | self.A_PBB_R
|
||||||
tText,
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBB_R
|
|
||||||
)
|
)
|
||||||
|
|
||||||
elif tType == self.T_HEAD2:
|
elif tType == self.T_HEAD2:
|
||||||
@@ -393,7 +384,7 @@ class Tokenizer():
|
|||||||
# =============
|
# =============
|
||||||
|
|
||||||
# Numbered or Unnumbered
|
# Numbered or Unnumbered
|
||||||
if isUnNum:
|
if self.isUnNum:
|
||||||
tText = self._formatHeading(self.fmtUnNum, tText)
|
tText = self._formatHeading(self.fmtUnNum, tText)
|
||||||
else:
|
else:
|
||||||
self.numChapter += 1
|
self.numChapter += 1
|
||||||
@@ -401,10 +392,7 @@ class Tokenizer():
|
|||||||
|
|
||||||
# Format the chapter header
|
# Format the chapter header
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tType,
|
tType, tText, None, self.A_LEFT | self.A_PBB_R
|
||||||
tText,
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBB_R
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set scene variables
|
# Set scene variables
|
||||||
@@ -421,47 +409,29 @@ class Tokenizer():
|
|||||||
tTemp = self._formatHeading(self.fmtScene, tText)
|
tTemp = self._formatHeading(self.fmtScene, tText)
|
||||||
if tTemp == "" and self.hideScene:
|
if tTemp == "" and self.hideScene:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
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, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_SKIP,
|
self.T_SKIP, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
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, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_SEP,
|
self.T_SEP, tTemp, None, self.A_CENTRE
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tType,
|
tType, tTemp, None, self.A_LEFT | self.A_PBA_AV
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBA_AV
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Definitely no longer the first scene
|
# Definitely no longer the first scene
|
||||||
@@ -474,62 +444,41 @@ class Tokenizer():
|
|||||||
tTemp = self._formatHeading(self.fmtSection, tText)
|
tTemp = self._formatHeading(self.fmtSection, tText)
|
||||||
if tTemp == "" and self.hideSection:
|
if tTemp == "" and self.hideSection:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_EMPTY,
|
self.T_EMPTY, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
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, "", None, None
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
)
|
)
|
||||||
elif tTemp == self.fmtSection:
|
elif tTemp == self.fmtSection:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
self.T_SEP,
|
self.T_SEP, tTemp, None, self.A_CENTRE
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tType,
|
tType, tTemp, None, self.A_LEFT | self.A_PBA_AV
|
||||||
tTemp,
|
|
||||||
None,
|
|
||||||
self.A_LEFT | self.A_PBA_AV
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# For title page and partitions, we need to centre all text.
|
# For title page and partitions, we need to centre all text.
|
||||||
# For partition, we also add a page break before, and for
|
# For partition, we also add a page break before, and for
|
||||||
# both types we always add a page break after the content.
|
# both types we always add a page break after the content.
|
||||||
if isTitle or isPart:
|
if self.isTitle or self.isPart:
|
||||||
for n in range(len(self.theTokens)):
|
for n, tToken in enumerate(self.theTokens):
|
||||||
tToken = self.theTokens[n]
|
|
||||||
tType = tToken[0]
|
tType = tToken[0]
|
||||||
tText = tToken[1]
|
tText = tToken[1]
|
||||||
tFormat = tToken[2]
|
tFormat = tToken[2]
|
||||||
if isTitle:
|
if self.isTitle:
|
||||||
self.theTokens[n] = (
|
self.theTokens[n] = (
|
||||||
tType,
|
tType, tText, tFormat, self.A_CENTRE
|
||||||
tText,
|
|
||||||
tFormat,
|
|
||||||
self.A_CENTRE
|
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
self.theTokens[n] = (
|
# Add a page break after the last entry
|
||||||
tType,
|
n = len(self.theTokens) - 1
|
||||||
tText,
|
if n >= 0:
|
||||||
tFormat,
|
tToken = self.theTokens[n]
|
||||||
self.A_CENTRE | self.A_PBB_R
|
self.theTokens[n] = (
|
||||||
)
|
tToken[0], tToken[1], tToken[2], tToken[3] | self.A_PBA
|
||||||
self.theTokens.append((
|
)
|
||||||
self.T_PBREAK,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
))
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
+71
-28
@@ -31,6 +31,7 @@ import nw
|
|||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, QByteArray
|
from PyQt5.QtCore import Qt, QByteArray
|
||||||
|
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QTextOption, QPalette, QColor, QTextDocumentWriter
|
QTextOption, QPalette, QColor, QTextDocumentWriter
|
||||||
)
|
)
|
||||||
@@ -230,9 +231,9 @@ class GuiBuildNovel(QDialog):
|
|||||||
self.saveODT.triggered.connect(lambda: self._saveDocument(self.FMT_ODT))
|
self.saveODT.triggered.connect(lambda: self._saveDocument(self.FMT_ODT))
|
||||||
self.saveMenu.addAction(self.saveODT)
|
self.saveMenu.addAction(self.saveODT)
|
||||||
|
|
||||||
# self.savePDF = QAction("Portable Document Format (.pdf)")
|
self.savePDF = QAction("Portable Document Format (.pdf)")
|
||||||
# self.savePDF.triggered.connect(lambda: self._saveDocument(self.FMT_PDF))
|
self.savePDF.triggered.connect(lambda: self._saveDocument(self.FMT_PDF))
|
||||||
# self.saveMenu.addAction(self.savePDF)
|
self.saveMenu.addAction(self.savePDF)
|
||||||
|
|
||||||
self.saveHTM1 = QAction("Qt Style HTML (.htm)")
|
self.saveHTM1 = QAction("Qt Style HTML (.htm)")
|
||||||
self.saveHTM1.triggered.connect(lambda: self._saveDocument(self.FMT_HTM1))
|
self.saveHTM1.triggered.connect(lambda: self._saveDocument(self.FMT_HTM1))
|
||||||
@@ -406,10 +407,15 @@ class GuiBuildNovel(QDialog):
|
|||||||
# Create the settings
|
# Create the settings
|
||||||
if theFormat == self.FMT_ODT:
|
if theFormat == self.FMT_ODT:
|
||||||
byteFmt.append("odf")
|
byteFmt.append("odf")
|
||||||
fileExt = "odf"
|
fileExt = "odt"
|
||||||
textFmt = "Open Document"
|
textFmt = "Open Document"
|
||||||
outTool = "Qt"
|
outTool = "Qt"
|
||||||
|
|
||||||
|
elif theFormat == self.FMT_PDF:
|
||||||
|
fileExt = "pdf"
|
||||||
|
textFmt = "PDF"
|
||||||
|
outTool = "QtPrint"
|
||||||
|
|
||||||
elif theFormat == self.FMT_HTM1:
|
elif theFormat == self.FMT_HTM1:
|
||||||
byteFmt.append("html")
|
byteFmt.append("html")
|
||||||
fileExt = "htm"
|
fileExt = "htm"
|
||||||
@@ -479,32 +485,56 @@ class GuiBuildNovel(QDialog):
|
|||||||
), nwAlert.ERROR
|
), nwAlert.ERROR
|
||||||
)
|
)
|
||||||
|
|
||||||
elif outTool == "NW":
|
elif outTool == "NW" and theFormat == self.FMT_HTM2:
|
||||||
if theFormat == self.FMT_HTM2:
|
try:
|
||||||
try:
|
with open(savePath, mode="w", encoding="utf8") as outFile:
|
||||||
with open(savePath, mode="w", encoding="utf8") as outFile:
|
outFile.write("<!DOCTYPE html>\n")
|
||||||
outFile.write("<!DOCTYPE html>\n")
|
outFile.write("<html>\n")
|
||||||
outFile.write("<html>\n")
|
outFile.write("<head>\n")
|
||||||
outFile.write("<head>\n")
|
outFile.write("<meta charset='utf-8'>\n")
|
||||||
outFile.write("<meta charset='utf-8'>\n")
|
outFile.write("</head>\n")
|
||||||
outFile.write("</head>\n")
|
outFile.write("<body>\n")
|
||||||
outFile.write("<body>\n")
|
outFile.write("<article style='width: 800px; margin: 40px auto'>\n")
|
||||||
outFile.write(self.htmlText)
|
outFile.write(self.htmlText)
|
||||||
outFile.write("</body>\n")
|
outFile.write("</article>\n")
|
||||||
outFile.write("</html>\n")
|
outFile.write("</body>\n")
|
||||||
|
outFile.write("</html>\n")
|
||||||
|
|
||||||
self.theParent.makeAlert(
|
self.theParent.makeAlert(
|
||||||
"Document successfully written in %s format to file: %s" % (
|
"Document successfully written in %s format to file: %s" % (
|
||||||
textFmt, savePath
|
textFmt, savePath
|
||||||
), nwAlert.INFO
|
), nwAlert.INFO
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.theParent.makeAlert(
|
self.theParent.makeAlert(
|
||||||
"Failed to write document in %s format to file: %s" % (
|
"Failed to write document in %s format to file: %s" % (
|
||||||
textFmt, str(e)
|
textFmt, str(e)
|
||||||
), nwAlert.ERROR
|
), nwAlert.ERROR
|
||||||
)
|
)
|
||||||
|
|
||||||
|
elif outTool == "QtPrint" and theFormat == self.FMT_PDF:
|
||||||
|
try:
|
||||||
|
thePrinter = QPrinter()
|
||||||
|
thePrinter.setOutputFormat(QPrinter.PdfFormat)
|
||||||
|
thePrinter.setOrientation(QPrinter.Portrait)
|
||||||
|
thePrinter.setDuplex(QPrinter.DuplexLongSide)
|
||||||
|
thePrinter.setFontEmbeddingEnabled(True)
|
||||||
|
thePrinter.setColorMode(QPrinter.Color)
|
||||||
|
thePrinter.setOutputFileName(savePath)
|
||||||
|
self.docView.qDocument.print(thePrinter)
|
||||||
|
self.theParent.makeAlert(
|
||||||
|
"Document successfully written in %s format to file: %s" % (
|
||||||
|
textFmt, savePath
|
||||||
|
), nwAlert.INFO
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.theParent.makeAlert(
|
||||||
|
"Failed to write document in %s format to file: %s" % (
|
||||||
|
textFmt, str(e)
|
||||||
|
), nwAlert.ERROR
|
||||||
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -512,6 +542,19 @@ class GuiBuildNovel(QDialog):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def _printDocument(self):
|
def _printDocument(self):
|
||||||
|
"""Open the print preview dialog.
|
||||||
|
"""
|
||||||
|
thePreview = QPrintPreviewDialog(self)
|
||||||
|
thePreview.paintRequested.connect(self._doPrintPreview)
|
||||||
|
thePreview.exec_()
|
||||||
|
return
|
||||||
|
|
||||||
|
def _doPrintPreview(self, thePrinter):
|
||||||
|
"""Connect the print preview painter to the document viewer.
|
||||||
|
"""
|
||||||
|
thePrinter.setOrientation(QPrinter.Portrait)
|
||||||
|
thePrinter.setOutputFormat(QPrinter.NativeFormat | QPrinter.PdfFormat)
|
||||||
|
self.docView.qDocument.print(thePrinter)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _toggelOutlineMode(self, theState):
|
def _toggelOutlineMode(self, theState):
|
||||||
|
|||||||
+1
-1
@@ -352,7 +352,7 @@ class GuiMainMenu(QMenuBar):
|
|||||||
self.docuMenu.addAction(self.aCloseView)
|
self.docuMenu.addAction(self.aCloseView)
|
||||||
|
|
||||||
# Document > Toggle View Comments
|
# Document > Toggle View Comments
|
||||||
self.aViewDocComments = QAction("View Comments", self)
|
self.aViewDocComments = QAction("Show Comments", self)
|
||||||
self.aViewDocComments.setStatusTip("Show comments in view panel")
|
self.aViewDocComments.setStatusTip("Show comments in view panel")
|
||||||
self.aViewDocComments.setCheckable(True)
|
self.aViewDocComments.setCheckable(True)
|
||||||
self.aViewDocComments.setChecked(self.mainConf.viewComments)
|
self.aViewDocComments.setChecked(self.mainConf.viewComments)
|
||||||
|
|||||||
Reference in New Issue
Block a user