Add code to save tabs and line breaks to ODT file
This commit is contained in:
+102
-14
@@ -42,6 +42,9 @@ XML_NS = {
|
|||||||
"fo" : "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
|
"fo" : "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_BR = "{%s}line-break" % XML_NS["text"]
|
||||||
|
X_TAB = "{%s}tab" % XML_NS["text"]
|
||||||
|
|
||||||
class ToOdt(Tokenizer):
|
class ToOdt(Tokenizer):
|
||||||
|
|
||||||
def __init__(self, theProject, theParent):
|
def __init__(self, theProject, theParent):
|
||||||
@@ -119,6 +122,9 @@ class ToOdt(Tokenizer):
|
|||||||
"""
|
"""
|
||||||
self.theResult = ""
|
self.theResult = ""
|
||||||
|
|
||||||
|
thisPar = []
|
||||||
|
parStyle = None
|
||||||
|
hasHardBreak = False
|
||||||
for tType, tLine, tText, tFormat, tStyle in self.theTokens:
|
for tType, tLine, tText, tFormat, tStyle in self.theTokens:
|
||||||
|
|
||||||
# Styles
|
# Styles
|
||||||
@@ -139,27 +145,35 @@ class ToOdt(Tokenizer):
|
|||||||
|
|
||||||
# Process Text Type
|
# Process Text Type
|
||||||
if tType == self.T_EMPTY:
|
if tType == self.T_EMPTY:
|
||||||
continue
|
if hasHardBreak and parStyle is not None:
|
||||||
|
if self.doJustify:
|
||||||
|
parStyle.setTextAlign("left")
|
||||||
|
if len(thisPar) > 0:
|
||||||
|
tTemp = "".join(thisPar)
|
||||||
|
self._addTextPar("Text_Body", parStyle, tTemp.rstrip())
|
||||||
|
thisPar = []
|
||||||
|
parStyle = None
|
||||||
|
hasHardBreak = False
|
||||||
|
|
||||||
elif tType == self.T_TITLE:
|
elif tType == self.T_TITLE:
|
||||||
tHead = tText.replace(r"\\", "<br/>")
|
tHead = tText.replace(r"\\", "\n")
|
||||||
self._addTextPar("Title", oStyle, tHead)
|
self._addTextPar("Title", oStyle, tHead, isHead=True)
|
||||||
|
|
||||||
elif tType == self.T_HEAD1:
|
elif tType == self.T_HEAD1:
|
||||||
tHead = tText.replace(r"\\", "<br/>")
|
tHead = tText.replace(r"\\", "\n")
|
||||||
self._addTextPar("Heading_1", oStyle, tHead, oLevel="1")
|
self._addTextPar("Heading_1", oStyle, tHead, isHead=True, oLevel="1")
|
||||||
|
|
||||||
elif tType == self.T_HEAD2:
|
elif tType == self.T_HEAD2:
|
||||||
tHead = tText.replace(r"\\", "<br/>")
|
tHead = tText.replace(r"\\", "\n")
|
||||||
self._addTextPar("Heading_2", oStyle, tHead, oLevel="2")
|
self._addTextPar("Heading_2", oStyle, tHead, isHead=True, oLevel="2")
|
||||||
|
|
||||||
elif tType == self.T_HEAD3:
|
elif tType == self.T_HEAD3:
|
||||||
tHead = tText.replace(r"\\", "<br/>")
|
tHead = tText.replace(r"\\", "\n")
|
||||||
self._addTextPar("Heading_3", oStyle, tHead, oLevel="3")
|
self._addTextPar("Heading_3", oStyle, tHead, isHead=True, oLevel="3")
|
||||||
|
|
||||||
elif tType == self.T_HEAD4:
|
elif tType == self.T_HEAD4:
|
||||||
tHead = tText.replace(r"\\", "<br/>")
|
tHead = tText.replace(r"\\", "\n")
|
||||||
self._addTextPar("Heading_4", oStyle, tHead, oLevel="4")
|
self._addTextPar("Heading_4", oStyle, tHead, isHead=True, oLevel="4")
|
||||||
|
|
||||||
elif tType == self.T_SEP:
|
elif tType == self.T_SEP:
|
||||||
self._addTextPar("Text_Body", oStyle, tText)
|
self._addTextPar("Text_Body", oStyle, tText)
|
||||||
@@ -167,6 +181,18 @@ class ToOdt(Tokenizer):
|
|||||||
elif tType == self.T_SKIP:
|
elif tType == self.T_SKIP:
|
||||||
self._addTextPar("Text_Body", oStyle, "")
|
self._addTextPar("Text_Body", oStyle, "")
|
||||||
|
|
||||||
|
elif tType == self.T_TEXT:
|
||||||
|
tTemp = tText
|
||||||
|
if parStyle is None:
|
||||||
|
parStyle = oStyle
|
||||||
|
# for xPos, xLen, xFmt in reversed(tFormat):
|
||||||
|
# tTemp = tTemp[:xPos]+htmlTags[xFmt]+tTemp[xPos+xLen:]
|
||||||
|
if tText.endswith(" "):
|
||||||
|
thisPar.append(tTemp.rstrip()+"\n")
|
||||||
|
hasHardBreak = True
|
||||||
|
else:
|
||||||
|
thisPar.append(tTemp.rstrip()+" ")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def closeDocument(self):
|
def closeDocument(self):
|
||||||
@@ -192,15 +218,51 @@ class ToOdt(Tokenizer):
|
|||||||
# Internal Functions
|
# Internal Functions
|
||||||
##
|
##
|
||||||
|
|
||||||
def _addTextPar(self, styleName, oStyle, theText, oLevel=None):
|
def _addTextPar(self, styleName, oStyle, theText, isHead=False, oLevel=None):
|
||||||
"""Add a text paragraph to the text XML element.
|
"""Add a text paragraph to the text XML element.
|
||||||
"""
|
"""
|
||||||
tAttr = {}
|
tAttr = {}
|
||||||
tAttr[_mkTag("text", "style-name")] = self._paraStyle(styleName, oStyle)
|
tAttr[_mkTag("text", "style-name")] = self._paraStyle(styleName, oStyle)
|
||||||
if oLevel is not None:
|
if oLevel is not None:
|
||||||
tAttr[_mkTag("text", "outline-level")] = oLevel
|
tAttr[_mkTag("text", "outline-level")] = oLevel
|
||||||
xElem = etree.SubElement(self._xText, _mkTag("text", "p"), attrib=tAttr)
|
|
||||||
xElem.text = theText
|
pTag = "h" if isHead else "p"
|
||||||
|
xElem = etree.SubElement(self._xText, _mkTag("text", pTag), attrib=tAttr)
|
||||||
|
|
||||||
|
if not theText:
|
||||||
|
return
|
||||||
|
|
||||||
|
if "\t" not in theText and "\n" not in theText:
|
||||||
|
xElem.text = theText
|
||||||
|
return
|
||||||
|
|
||||||
|
# Process tabs and line breaks
|
||||||
|
tTemp = ""
|
||||||
|
xTail = None
|
||||||
|
for c in theText:
|
||||||
|
if c == "\t":
|
||||||
|
if xTail is None:
|
||||||
|
xElem.text = tTemp
|
||||||
|
else:
|
||||||
|
xTail.tail = tTemp
|
||||||
|
tTemp = ""
|
||||||
|
xTail = etree.SubElement(xElem, X_TAB)
|
||||||
|
elif c == "\n":
|
||||||
|
if xTail is None:
|
||||||
|
xElem.text = tTemp
|
||||||
|
else:
|
||||||
|
xTail.tail = tTemp
|
||||||
|
tTemp = ""
|
||||||
|
xTail = etree.SubElement(xElem, X_BR)
|
||||||
|
else:
|
||||||
|
tTemp += c
|
||||||
|
|
||||||
|
if tTemp != "":
|
||||||
|
if xTail is None:
|
||||||
|
xElem.text = tTemp
|
||||||
|
else:
|
||||||
|
xTail.tail = tTemp
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def _paraStyle(self, parName, oStyle):
|
def _paraStyle(self, parName, oStyle):
|
||||||
@@ -299,6 +361,10 @@ class ToOdt(Tokenizer):
|
|||||||
oStyle.setMarginTop("0cm")
|
oStyle.setMarginTop("0cm")
|
||||||
oStyle.setMarginBottom("0.247cm")
|
oStyle.setMarginBottom("0.247cm")
|
||||||
oStyle.setLineHeight("115%")
|
oStyle.setLineHeight("115%")
|
||||||
|
if self.doJustify:
|
||||||
|
oStyle.setTextAlign("justify")
|
||||||
|
else:
|
||||||
|
oStyle.setTextAlign("left")
|
||||||
oStyle.packXML(self._xStyl, "Text_Body")
|
oStyle.packXML(self._xStyl, "Text_Body")
|
||||||
|
|
||||||
self._mainPara["Text_Body"] = oStyle
|
self._mainPara["Text_Body"] = oStyle
|
||||||
@@ -501,6 +567,28 @@ class ODTParagraphStyle():
|
|||||||
self._tAttr["font-weight"][1] = str(theValue)
|
self._tAttr["font-weight"][1] = str(theValue)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
##
|
||||||
|
# Getters
|
||||||
|
##
|
||||||
|
|
||||||
|
def getAttr(self, attrName):
|
||||||
|
"""Look through the dictionaries for the value, and return it if
|
||||||
|
we can find it, If not, return None.
|
||||||
|
"""
|
||||||
|
retVal = self._mAttr.get(attrName, None)
|
||||||
|
if retVal is not None:
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
retVal = self._pAttr.get(attrName, None)
|
||||||
|
if retVal is not None:
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
retVal = self._tAttr.get(attrName, None)
|
||||||
|
if retVal is not None:
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
##
|
##
|
||||||
# Methods
|
# Methods
|
||||||
##
|
##
|
||||||
|
|||||||
+10
-3
@@ -753,7 +753,7 @@ class GuiBuildNovel(QDialog):
|
|||||||
elif theFormat == self.FMT_FODT:
|
elif theFormat == self.FMT_FODT:
|
||||||
fileExt = "fodt"
|
fileExt = "fodt"
|
||||||
textFmt = "Flat Open Document"
|
textFmt = "Flat Open Document"
|
||||||
outTool = "NW2"
|
outTool = "NW_ODT"
|
||||||
|
|
||||||
elif theFormat == self.FMT_PDF:
|
elif theFormat == self.FMT_PDF:
|
||||||
fileExt = "pdf"
|
fileExt = "pdf"
|
||||||
@@ -898,12 +898,19 @@ class GuiBuildNovel(QDialog):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
errMsg = str(e)
|
errMsg = str(e)
|
||||||
|
|
||||||
elif outTool == "NW2":
|
elif outTool == "NW_ODT":
|
||||||
|
|
||||||
if theFormat == self.FMT_FODT:
|
if theFormat == self.FMT_FODT:
|
||||||
makeOdt = ToOdt(self.theProject, self.theParent)
|
makeOdt = ToOdt(self.theProject, self.theParent)
|
||||||
self._doBuild(makeOdt)
|
self._doBuild(makeOdt)
|
||||||
wSuccess = True
|
try:
|
||||||
|
with open(savePath, mode="wb") as outFile:
|
||||||
|
outFile.write(makeOdt.theResult)
|
||||||
|
|
||||||
|
wSuccess = True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
errMsg = str(e)
|
||||||
|
|
||||||
elif outTool == "QtPrint" and theFormat == self.FMT_PDF:
|
elif outTool == "QtPrint" and theFormat == self.FMT_PDF:
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user