Replaxe lxml with standard library xml in ODT class
This commit is contained in:
+113
-122
@@ -24,13 +24,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
from lxml import etree
|
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from novelwriter import __version__
|
from novelwriter import __version__
|
||||||
|
from novelwriter.common import xmlIndent
|
||||||
from novelwriter.constants import nwKeyWords, nwLabels
|
from novelwriter.constants import nwKeyWords, nwLabels
|
||||||
from novelwriter.core.tokenizer import Tokenizer, stripEscape
|
from novelwriter.core.tokenizer import Tokenizer, stripEscape
|
||||||
|
|
||||||
@@ -38,30 +39,27 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# Main XML NameSpaces
|
# Main XML NameSpaces
|
||||||
XML_NS = {
|
XML_NS = {
|
||||||
"office": "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
|
"manifest": "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0",
|
||||||
"style": "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
|
"office": "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
|
||||||
"loext": "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0",
|
"style": "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
|
||||||
"text": "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
|
"loext": "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0",
|
||||||
"meta": "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
|
"text": "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
|
||||||
"fo": "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
|
"meta": "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
|
||||||
"dc": "http://purl.org/dc/elements/1.1/",
|
"fo": "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
|
||||||
}
|
"dc": "http://purl.org/dc/elements/1.1/",
|
||||||
MANI_NS = {
|
|
||||||
"manifest": "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
|
|
||||||
}
|
|
||||||
OFFICE_NS = {
|
|
||||||
"office": "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
|
|
||||||
}
|
}
|
||||||
|
for ns, uri in XML_NS.items():
|
||||||
|
ET.register_namespace(ns, uri)
|
||||||
|
|
||||||
|
|
||||||
def _mkTag(nsName, tagName, nsMap=XML_NS):
|
def _mkTag(ns, tag):
|
||||||
"""Assemble namespace and tag name.
|
"""Assemble namespace and tag name.
|
||||||
"""
|
"""
|
||||||
theNS = nsMap.get(nsName, "")
|
uri = XML_NS.get(ns, "")
|
||||||
if theNS:
|
if uri:
|
||||||
return f"{{{theNS}}}{tagName}"
|
return f"{{{uri}}}{tag}"
|
||||||
logger.warning("Missing xml namespace '%s'", nsName)
|
logger.warning("Missing xml namespace '%s'", ns)
|
||||||
return tagName
|
return tag
|
||||||
|
|
||||||
|
|
||||||
# Mimetype and Version
|
# Mimetype and Version
|
||||||
@@ -284,16 +282,16 @@ class ToOdt(Tokenizer):
|
|||||||
tAttr[_mkTag("office", "mimetype")] = X_MIME
|
tAttr[_mkTag("office", "mimetype")] = X_MIME
|
||||||
|
|
||||||
tFlat = _mkTag("office", "document")
|
tFlat = _mkTag("office", "document")
|
||||||
self._dFlat = etree.Element(tFlat, attrib=tAttr, nsmap=XML_NS)
|
self._dFlat = ET.Element(tFlat, attrib=tAttr)
|
||||||
|
|
||||||
self._xMeta = etree.SubElement(self._dFlat, _mkTag("office", "meta"))
|
self._xMeta = ET.SubElement(self._dFlat, _mkTag("office", "meta"))
|
||||||
self._xFont = etree.SubElement(self._dFlat, _mkTag("office", "font-face-decls"))
|
self._xFont = ET.SubElement(self._dFlat, _mkTag("office", "font-face-decls"))
|
||||||
self._xStyl = etree.SubElement(self._dFlat, _mkTag("office", "styles"))
|
self._xStyl = ET.SubElement(self._dFlat, _mkTag("office", "styles"))
|
||||||
self._xAuto = etree.SubElement(self._dFlat, _mkTag("office", "automatic-styles"))
|
self._xAuto = ET.SubElement(self._dFlat, _mkTag("office", "automatic-styles"))
|
||||||
self._xMast = etree.SubElement(self._dFlat, _mkTag("office", "master-styles"))
|
self._xMast = ET.SubElement(self._dFlat, _mkTag("office", "master-styles"))
|
||||||
self._xBody = etree.SubElement(self._dFlat, _mkTag("office", "body"))
|
self._xBody = ET.SubElement(self._dFlat, _mkTag("office", "body"))
|
||||||
|
|
||||||
etree.SubElement(self._xFont, _mkTag("style", "font-face"), attrib=fAttr)
|
ET.SubElement(self._xFont, _mkTag("style", "font-face"), attrib=fAttr)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
@@ -305,59 +303,59 @@ class ToOdt(Tokenizer):
|
|||||||
tStyl = _mkTag("office", "document-styles")
|
tStyl = _mkTag("office", "document-styles")
|
||||||
|
|
||||||
# content.xml
|
# content.xml
|
||||||
self._dCont = etree.Element(tCont, attrib=tAttr, nsmap=XML_NS)
|
self._dCont = ET.Element(tCont, attrib=tAttr)
|
||||||
self._xFont = etree.SubElement(self._dCont, _mkTag("office", "font-face-decls"))
|
self._xFont = ET.SubElement(self._dCont, _mkTag("office", "font-face-decls"))
|
||||||
self._xAuto = etree.SubElement(self._dCont, _mkTag("office", "automatic-styles"))
|
self._xAuto = ET.SubElement(self._dCont, _mkTag("office", "automatic-styles"))
|
||||||
self._xBody = etree.SubElement(self._dCont, _mkTag("office", "body"))
|
self._xBody = ET.SubElement(self._dCont, _mkTag("office", "body"))
|
||||||
|
|
||||||
# meta.xml
|
# meta.xml
|
||||||
self._dMeta = etree.Element(tMeta, attrib=tAttr, nsmap=XML_NS)
|
self._dMeta = ET.Element(tMeta, attrib=tAttr)
|
||||||
self._xMeta = etree.SubElement(self._dMeta, _mkTag("office", "meta"))
|
self._xMeta = ET.SubElement(self._dMeta, _mkTag("office", "meta"))
|
||||||
|
|
||||||
# styles.xml
|
# styles.xml
|
||||||
self._dStyl = etree.Element(tStyl, attrib=tAttr, nsmap=XML_NS)
|
self._dStyl = ET.Element(tStyl, attrib=tAttr)
|
||||||
self._xFnt2 = etree.SubElement(self._dStyl, _mkTag("office", "font-face-decls"))
|
self._xFnt2 = ET.SubElement(self._dStyl, _mkTag("office", "font-face-decls"))
|
||||||
self._xStyl = etree.SubElement(self._dStyl, _mkTag("office", "styles"))
|
self._xStyl = ET.SubElement(self._dStyl, _mkTag("office", "styles"))
|
||||||
self._xAut2 = etree.SubElement(self._dStyl, _mkTag("office", "automatic-styles"))
|
self._xAut2 = ET.SubElement(self._dStyl, _mkTag("office", "automatic-styles"))
|
||||||
self._xMast = etree.SubElement(self._dStyl, _mkTag("office", "master-styles"))
|
self._xMast = ET.SubElement(self._dStyl, _mkTag("office", "master-styles"))
|
||||||
|
|
||||||
etree.SubElement(self._xFont, _mkTag("style", "font-face"), attrib=fAttr)
|
ET.SubElement(self._xFont, _mkTag("style", "font-face"), attrib=fAttr)
|
||||||
etree.SubElement(self._xFnt2, _mkTag("style", "font-face"), attrib=fAttr)
|
ET.SubElement(self._xFnt2, _mkTag("style", "font-face"), attrib=fAttr)
|
||||||
|
|
||||||
# Finalise
|
# Finalise
|
||||||
# ========
|
# ========
|
||||||
|
|
||||||
self._xText = etree.SubElement(self._xBody, _mkTag("office", "text"))
|
self._xText = ET.SubElement(self._xBody, _mkTag("office", "text"))
|
||||||
|
|
||||||
timeStamp = datetime.now().isoformat(sep="T", timespec="seconds")
|
timeStamp = datetime.now().isoformat(sep="T", timespec="seconds")
|
||||||
|
|
||||||
# Office Meta Data
|
# Office Meta Data
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "creation-date"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("meta", "creation-date"))
|
||||||
xMeta.text = timeStamp
|
xMeta.text = timeStamp
|
||||||
|
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "generator"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("meta", "generator"))
|
||||||
xMeta.text = f"novelWriter/{__version__}"
|
xMeta.text = f"novelWriter/{__version__}"
|
||||||
|
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "initial-creator"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("meta", "initial-creator"))
|
||||||
xMeta.text = self.theProject.data.author
|
xMeta.text = self.theProject.data.author
|
||||||
|
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "editing-cycles"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("meta", "editing-cycles"))
|
||||||
xMeta.text = str(self.theProject.data.saveCount)
|
xMeta.text = str(self.theProject.data.saveCount)
|
||||||
|
|
||||||
# Format is: PnYnMnDTnHnMnS
|
# Format is: PnYnMnDTnHnMnS
|
||||||
# https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#duration
|
# https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#duration
|
||||||
eT = self.theProject.data.editTime
|
eT = self.theProject.data.editTime
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "editing-duration"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("meta", "editing-duration"))
|
||||||
xMeta.text = f"P{eT//86400:d}DT{eT%86400//3600:d}H{eT%3600//60:d}M{eT%60:d}S"
|
xMeta.text = f"P{eT//86400:d}DT{eT%86400//3600:d}H{eT%3600//60:d}M{eT%60:d}S"
|
||||||
|
|
||||||
# Dublin Core Meta Data
|
# Dublin Core Meta Data
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("dc", "title"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("dc", "title"))
|
||||||
xMeta.text = self.theProject.data.title or self.theProject.data.name
|
xMeta.text = self.theProject.data.title or self.theProject.data.name
|
||||||
|
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("dc", "date"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("dc", "date"))
|
||||||
xMeta.text = timeStamp
|
xMeta.text = timeStamp
|
||||||
|
|
||||||
xMeta = etree.SubElement(self._xMeta, _mkTag("dc", "creator"))
|
xMeta = ET.SubElement(self._xMeta, _mkTag("dc", "creator"))
|
||||||
xMeta.text = self.theProject.data.author
|
xMeta.text = self.theProject.data.author
|
||||||
|
|
||||||
self._pageStyles()
|
self._pageStyles()
|
||||||
@@ -503,51 +501,44 @@ class ToOdt(Tokenizer):
|
|||||||
"""Save the data to an .fodt file.
|
"""Save the data to an .fodt file.
|
||||||
"""
|
"""
|
||||||
with open(savePath, mode="wb") as outFile:
|
with open(savePath, mode="wb") as outFile:
|
||||||
outFile.write(etree.tostring(
|
xml = ET.ElementTree(self._dFlat)
|
||||||
self._dFlat,
|
xmlIndent(xml, space=" ")
|
||||||
pretty_print=True,
|
xml.write(outFile, encoding="utf-8", xml_declaration=True)
|
||||||
encoding="utf-8",
|
|
||||||
xml_declaration=True
|
|
||||||
))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def saveOpenDocText(self, savePath):
|
def saveOpenDocText(self, savePath):
|
||||||
"""Save the data to an .odt file.
|
"""Save the data to an .odt file.
|
||||||
"""
|
"""
|
||||||
mMani = _mkTag("manifest", "manifest", nsMap=MANI_NS)
|
mMani = _mkTag("manifest", "manifest")
|
||||||
mVers = _mkTag("manifest", "version", nsMap=MANI_NS)
|
mVers = _mkTag("manifest", "version")
|
||||||
mPath = _mkTag("manifest", "full-path", nsMap=MANI_NS)
|
mPath = _mkTag("manifest", "full-path")
|
||||||
mType = _mkTag("manifest", "media-type", nsMap=MANI_NS)
|
mType = _mkTag("manifest", "media-type")
|
||||||
mFile = _mkTag("manifest", "file-entry", nsMap=MANI_NS)
|
mFile = _mkTag("manifest", "file-entry")
|
||||||
|
|
||||||
xMani = etree.Element(mMani, attrib={mVers: X_VERS}, nsmap=MANI_NS)
|
xMani = ET.Element(mMani, attrib={mVers: X_VERS})
|
||||||
etree.SubElement(xMani, mFile, attrib={mPath: "/", mVers: X_VERS, mType: X_MIME})
|
ET.SubElement(xMani, mFile, attrib={mPath: "/", mVers: X_VERS, mType: X_MIME})
|
||||||
etree.SubElement(xMani, mFile, attrib={mPath: "settings.xml", mType: "text/xml"})
|
ET.SubElement(xMani, mFile, attrib={mPath: "settings.xml", mType: "text/xml"})
|
||||||
etree.SubElement(xMani, mFile, attrib={mPath: "content.xml", mType: "text/xml"})
|
ET.SubElement(xMani, mFile, attrib={mPath: "content.xml", mType: "text/xml"})
|
||||||
etree.SubElement(xMani, mFile, attrib={mPath: "meta.xml", mType: "text/xml"})
|
ET.SubElement(xMani, mFile, attrib={mPath: "meta.xml", mType: "text/xml"})
|
||||||
etree.SubElement(xMani, mFile, attrib={mPath: "styles.xml", mType: "text/xml"})
|
ET.SubElement(xMani, mFile, attrib={mPath: "styles.xml", mType: "text/xml"})
|
||||||
|
|
||||||
oRoot = _mkTag("office", "document-settings", nsMap=OFFICE_NS)
|
oRoot = _mkTag("office", "document-settings")
|
||||||
oVers = _mkTag("office", "version", nsMap=OFFICE_NS)
|
oVers = _mkTag("office", "version")
|
||||||
xSett = etree.Element(oRoot, nsmap=OFFICE_NS, attrib={oVers: X_VERS})
|
xSett = ET.Element(oRoot, attrib={oVers: X_VERS})
|
||||||
|
|
||||||
with ZipFile(savePath, mode="w") as outFile:
|
def putInZip(name, xObj, zipObj):
|
||||||
outFile.writestr("mimetype", X_MIME)
|
with zipObj.open(name, mode="w") as fObj:
|
||||||
outFile.writestr("META-INF/manifest.xml", etree.tostring(
|
xml = ET.ElementTree(xObj)
|
||||||
xMani, pretty_print=False, encoding="utf-8", xml_declaration=True
|
xmlIndent(xml, space=" ")
|
||||||
))
|
xml.write(fObj, encoding="utf-8", xml_declaration=True)
|
||||||
outFile.writestr("settings.xml", etree.tostring(
|
|
||||||
xSett, pretty_print=False, encoding="utf-8", xml_declaration=True
|
with ZipFile(savePath, mode="w") as outZip:
|
||||||
))
|
outZip.writestr("mimetype", X_MIME)
|
||||||
outFile.writestr("content.xml", etree.tostring(
|
putInZip("META-INF/manifest.xml", xMani, outZip)
|
||||||
self._dCont, pretty_print=False, encoding="utf-8", xml_declaration=True
|
putInZip("settings.xml", xSett, outZip)
|
||||||
))
|
putInZip("content.xml", self._dCont, outZip)
|
||||||
outFile.writestr("meta.xml", etree.tostring(
|
putInZip("meta.xml", self._dMeta, outZip)
|
||||||
self._dMeta, pretty_print=False, encoding="utf-8", xml_declaration=True
|
putInZip("styles.xml", self._dStyl, outZip)
|
||||||
))
|
|
||||||
outFile.writestr("styles.xml", etree.tostring(
|
|
||||||
self._dStyl, pretty_print=False, encoding="utf-8", xml_declaration=True
|
|
||||||
))
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -604,7 +595,7 @@ class ToOdt(Tokenizer):
|
|||||||
tAttr[_mkTag("text", "outline-level")] = oLevel
|
tAttr[_mkTag("text", "outline-level")] = oLevel
|
||||||
|
|
||||||
pTag = "h" if isHead else "p"
|
pTag = "h" if isHead else "p"
|
||||||
xElem = etree.SubElement(self._xText, _mkTag("text", pTag), attrib=tAttr)
|
xElem = ET.SubElement(self._xText, _mkTag("text", pTag), attrib=tAttr)
|
||||||
|
|
||||||
# It's important to set the initial text field to empty, otherwise
|
# It's important to set the initial text field to empty, otherwise
|
||||||
# lxml will add a line break if the first subelement is a span.
|
# lxml will add a line break if the first subelement is a span.
|
||||||
@@ -732,25 +723,25 @@ class ToOdt(Tokenizer):
|
|||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "name")] = "PM1"
|
theAttr[_mkTag("style", "name")] = "PM1"
|
||||||
if self._isFlat:
|
if self._isFlat:
|
||||||
xPage = etree.SubElement(self._xAuto, _mkTag("style", "page-layout"), attrib=theAttr)
|
xPage = ET.SubElement(self._xAuto, _mkTag("style", "page-layout"), attrib=theAttr)
|
||||||
else:
|
else:
|
||||||
xPage = etree.SubElement(self._xAut2, _mkTag("style", "page-layout"), attrib=theAttr)
|
xPage = ET.SubElement(self._xAut2, _mkTag("style", "page-layout"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("fo", "margin-top")] = self._mDocTop
|
theAttr[_mkTag("fo", "margin-top")] = self._mDocTop
|
||||||
theAttr[_mkTag("fo", "margin-bottom")] = self._mDocBtm
|
theAttr[_mkTag("fo", "margin-bottom")] = self._mDocBtm
|
||||||
theAttr[_mkTag("fo", "margin-left")] = self._mDocLeft
|
theAttr[_mkTag("fo", "margin-left")] = self._mDocLeft
|
||||||
theAttr[_mkTag("fo", "margin-right")] = self._mDocRight
|
theAttr[_mkTag("fo", "margin-right")] = self._mDocRight
|
||||||
etree.SubElement(xPage, _mkTag("style", "page-layout-properties"), attrib=theAttr)
|
ET.SubElement(xPage, _mkTag("style", "page-layout-properties"), attrib=theAttr)
|
||||||
|
|
||||||
xHead = etree.SubElement(xPage, _mkTag("style", "header-style"))
|
xHead = ET.SubElement(xPage, _mkTag("style", "header-style"))
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("fo", "min-height")] = "0.600cm"
|
theAttr[_mkTag("fo", "min-height")] = "0.600cm"
|
||||||
theAttr[_mkTag("fo", "margin-left")] = "0.000cm"
|
theAttr[_mkTag("fo", "margin-left")] = "0.000cm"
|
||||||
theAttr[_mkTag("fo", "margin-right")] = "0.000cm"
|
theAttr[_mkTag("fo", "margin-right")] = "0.000cm"
|
||||||
theAttr[_mkTag("fo", "margin-bottom")] = "0.500cm"
|
theAttr[_mkTag("fo", "margin-bottom")] = "0.500cm"
|
||||||
etree.SubElement(xHead, _mkTag("style", "header-footer-properties"), attrib=theAttr)
|
ET.SubElement(xHead, _mkTag("style", "header-footer-properties"), attrib=theAttr)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -762,13 +753,13 @@ class ToOdt(Tokenizer):
|
|||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "family")] = "paragraph"
|
theAttr[_mkTag("style", "family")] = "paragraph"
|
||||||
xStyl = etree.SubElement(self._xStyl, _mkTag("style", "default-style"), attrib=theAttr)
|
xStyl = ET.SubElement(self._xStyl, _mkTag("style", "default-style"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "line-break")] = "strict"
|
theAttr[_mkTag("style", "line-break")] = "strict"
|
||||||
theAttr[_mkTag("style", "tab-stop-distance")] = "1.251cm"
|
theAttr[_mkTag("style", "tab-stop-distance")] = "1.251cm"
|
||||||
theAttr[_mkTag("style", "writing-mode")] = "page"
|
theAttr[_mkTag("style", "writing-mode")] = "page"
|
||||||
etree.SubElement(xStyl, _mkTag("style", "paragraph-properties"), attrib=theAttr)
|
ET.SubElement(xStyl, _mkTag("style", "paragraph-properties"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "font-name")] = self._textFont
|
theAttr[_mkTag("style", "font-name")] = self._textFont
|
||||||
@@ -776,7 +767,7 @@ class ToOdt(Tokenizer):
|
|||||||
theAttr[_mkTag("fo", "font-size")] = self._fSizeText
|
theAttr[_mkTag("fo", "font-size")] = self._fSizeText
|
||||||
theAttr[_mkTag("fo", "language")] = self._dLanguage
|
theAttr[_mkTag("fo", "language")] = self._dLanguage
|
||||||
theAttr[_mkTag("fo", "country")] = self._dCountry
|
theAttr[_mkTag("fo", "country")] = self._dCountry
|
||||||
etree.SubElement(xStyl, _mkTag("style", "text-properties"), attrib=theAttr)
|
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib=theAttr)
|
||||||
|
|
||||||
# Add Standard Paragraph Style
|
# Add Standard Paragraph Style
|
||||||
# ============================
|
# ============================
|
||||||
@@ -785,13 +776,13 @@ class ToOdt(Tokenizer):
|
|||||||
theAttr[_mkTag("style", "name")] = "Standard"
|
theAttr[_mkTag("style", "name")] = "Standard"
|
||||||
theAttr[_mkTag("style", "family")] = "paragraph"
|
theAttr[_mkTag("style", "family")] = "paragraph"
|
||||||
theAttr[_mkTag("style", "class")] = "text"
|
theAttr[_mkTag("style", "class")] = "text"
|
||||||
xStyl = etree.SubElement(self._xStyl, _mkTag("style", "style"), attrib=theAttr)
|
xStyl = ET.SubElement(self._xStyl, _mkTag("style", "style"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "font-name")] = self._textFont
|
theAttr[_mkTag("style", "font-name")] = self._textFont
|
||||||
theAttr[_mkTag("fo", "font-family")] = self._fontFamily
|
theAttr[_mkTag("fo", "font-family")] = self._fontFamily
|
||||||
theAttr[_mkTag("fo", "font-size")] = self._fSizeText
|
theAttr[_mkTag("fo", "font-size")] = self._fSizeText
|
||||||
etree.SubElement(xStyl, _mkTag("style", "text-properties"), attrib=theAttr)
|
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib=theAttr)
|
||||||
|
|
||||||
# Add Default Heading Style
|
# Add Default Heading Style
|
||||||
# =========================
|
# =========================
|
||||||
@@ -802,19 +793,19 @@ class ToOdt(Tokenizer):
|
|||||||
theAttr[_mkTag("style", "parent-style-name")] = "Standard"
|
theAttr[_mkTag("style", "parent-style-name")] = "Standard"
|
||||||
theAttr[_mkTag("style", "next-style-name")] = "Text_20_body"
|
theAttr[_mkTag("style", "next-style-name")] = "Text_20_body"
|
||||||
theAttr[_mkTag("style", "class")] = "text"
|
theAttr[_mkTag("style", "class")] = "text"
|
||||||
xStyl = etree.SubElement(self._xStyl, _mkTag("style", "style"), attrib=theAttr)
|
xStyl = ET.SubElement(self._xStyl, _mkTag("style", "style"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("fo", "margin-top")] = self._mTopHead
|
theAttr[_mkTag("fo", "margin-top")] = self._mTopHead
|
||||||
theAttr[_mkTag("fo", "margin-bottom")] = self._mBotHead
|
theAttr[_mkTag("fo", "margin-bottom")] = self._mBotHead
|
||||||
theAttr[_mkTag("fo", "keep-with-next")] = "always"
|
theAttr[_mkTag("fo", "keep-with-next")] = "always"
|
||||||
etree.SubElement(xStyl, _mkTag("style", "paragraph-properties"), attrib=theAttr)
|
ET.SubElement(xStyl, _mkTag("style", "paragraph-properties"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "font-name")] = self._textFont
|
theAttr[_mkTag("style", "font-name")] = self._textFont
|
||||||
theAttr[_mkTag("fo", "font-family")] = self._fontFamily
|
theAttr[_mkTag("fo", "font-family")] = self._fontFamily
|
||||||
theAttr[_mkTag("fo", "font-size")] = self._fSizeHead
|
theAttr[_mkTag("fo", "font-size")] = self._fSizeHead
|
||||||
etree.SubElement(xStyl, _mkTag("style", "text-properties"), attrib=theAttr)
|
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib=theAttr)
|
||||||
|
|
||||||
# Add Header and Footer Styles
|
# Add Header and Footer Styles
|
||||||
# ============================
|
# ============================
|
||||||
@@ -824,7 +815,7 @@ class ToOdt(Tokenizer):
|
|||||||
theAttr[_mkTag("style", "family")] = "paragraph"
|
theAttr[_mkTag("style", "family")] = "paragraph"
|
||||||
theAttr[_mkTag("style", "parent-style-name")] = "Standard"
|
theAttr[_mkTag("style", "parent-style-name")] = "Standard"
|
||||||
theAttr[_mkTag("style", "class")] = "extra"
|
theAttr[_mkTag("style", "class")] = "extra"
|
||||||
etree.SubElement(self._xStyl, _mkTag("style", "style"), attrib=theAttr)
|
ET.SubElement(self._xStyl, _mkTag("style", "style"), attrib=theAttr)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -989,23 +980,23 @@ class ToOdt(Tokenizer):
|
|||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "name")] = "Standard"
|
theAttr[_mkTag("style", "name")] = "Standard"
|
||||||
theAttr[_mkTag("style", "page-layout-name")] = "PM1"
|
theAttr[_mkTag("style", "page-layout-name")] = "PM1"
|
||||||
xPage = etree.SubElement(self._xMast, _mkTag("style", "master-page"), attrib=theAttr)
|
xPage = ET.SubElement(self._xMast, _mkTag("style", "master-page"), attrib=theAttr)
|
||||||
|
|
||||||
# Standard Page Header
|
# Standard Page Header
|
||||||
xHead = etree.SubElement(xPage, _mkTag("style", "header"))
|
xHead = ET.SubElement(xPage, _mkTag("style", "header"))
|
||||||
xPar = etree.SubElement(xHead, _mkTag("text", "p"), attrib={
|
xPar = ET.SubElement(xHead, _mkTag("text", "p"), attrib={
|
||||||
_mkTag("text", "style-name"): "Header"
|
_mkTag("text", "style-name"): "Header"
|
||||||
})
|
})
|
||||||
xPar.text = self._headerText.strip() + " "
|
xPar.text = self._headerText.strip() + " "
|
||||||
|
|
||||||
xTail = etree.SubElement(xPar, _mkTag("text", "page-number"), attrib={
|
xTail = ET.SubElement(xPar, _mkTag("text", "page-number"), attrib={
|
||||||
_mkTag("text", "select-page"): "current"
|
_mkTag("text", "select-page"): "current"
|
||||||
})
|
})
|
||||||
xTail.text = "2"
|
xTail.text = "2"
|
||||||
|
|
||||||
# First Page Header
|
# First Page Header
|
||||||
xHead = etree.SubElement(xPage, _mkTag("style", "header-first"))
|
xHead = ET.SubElement(xPage, _mkTag("style", "header-first"))
|
||||||
xPar = etree.SubElement(xHead, _mkTag("text", "p"), attrib={
|
xPar = ET.SubElement(xHead, _mkTag("text", "p"), attrib={
|
||||||
_mkTag("text", "style-name"): "Header"
|
_mkTag("text", "style-name"): "Header"
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1209,7 +1200,7 @@ class ODTParagraphStyle:
|
|||||||
if aVal is not None:
|
if aVal is not None:
|
||||||
theAttr[_mkTag(aNm, aName)] = aVal
|
theAttr[_mkTag(aNm, aName)] = aVal
|
||||||
|
|
||||||
xEntry = etree.SubElement(xParent, _mkTag("style", "style"), attrib=theAttr)
|
xEntry = ET.SubElement(xParent, _mkTag("style", "style"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
for aName, (aNm, aVal) in self._pAttr.items():
|
for aName, (aNm, aVal) in self._pAttr.items():
|
||||||
@@ -1217,7 +1208,7 @@ class ODTParagraphStyle:
|
|||||||
theAttr[_mkTag(aNm, aName)] = aVal
|
theAttr[_mkTag(aNm, aName)] = aVal
|
||||||
|
|
||||||
if theAttr:
|
if theAttr:
|
||||||
etree.SubElement(xEntry, _mkTag("style", "paragraph-properties"), attrib=theAttr)
|
ET.SubElement(xEntry, _mkTag("style", "paragraph-properties"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
for aName, (aNm, aVal) in self._tAttr.items():
|
for aName, (aNm, aVal) in self._tAttr.items():
|
||||||
@@ -1225,7 +1216,7 @@ class ODTParagraphStyle:
|
|||||||
theAttr[_mkTag(aNm, aName)] = aVal
|
theAttr[_mkTag(aNm, aName)] = aVal
|
||||||
|
|
||||||
if theAttr:
|
if theAttr:
|
||||||
etree.SubElement(xEntry, _mkTag("style", "text-properties"), attrib=theAttr)
|
ET.SubElement(xEntry, _mkTag("style", "text-properties"), attrib=theAttr)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1296,7 +1287,7 @@ class ODTTextStyle:
|
|||||||
theAttr = {}
|
theAttr = {}
|
||||||
theAttr[_mkTag("style", "name")] = xName
|
theAttr[_mkTag("style", "name")] = xName
|
||||||
theAttr[_mkTag("style", "family")] = "text"
|
theAttr[_mkTag("style", "family")] = "text"
|
||||||
xEntry = etree.SubElement(xParent, _mkTag("style", "style"), attrib=theAttr)
|
xEntry = ET.SubElement(xParent, _mkTag("style", "style"), attrib=theAttr)
|
||||||
|
|
||||||
theAttr = {}
|
theAttr = {}
|
||||||
for aName, (aNm, aVal) in self._tAttr.items():
|
for aName, (aNm, aVal) in self._tAttr.items():
|
||||||
@@ -1304,7 +1295,7 @@ class ODTTextStyle:
|
|||||||
theAttr[_mkTag(aNm, aName)] = aVal
|
theAttr[_mkTag(aNm, aName)] = aVal
|
||||||
|
|
||||||
if theAttr:
|
if theAttr:
|
||||||
etree.SubElement(xEntry, _mkTag("style", "text-properties"), attrib=theAttr)
|
ET.SubElement(xEntry, _mkTag("style", "text-properties"), attrib=theAttr)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1377,26 +1368,26 @@ class XMLParagraph:
|
|||||||
|
|
||||||
if c == "\n":
|
if c == "\n":
|
||||||
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
||||||
self._xTail = etree.SubElement(self._xRoot, TAG_BR)
|
self._xTail = ET.SubElement(self._xRoot, TAG_BR)
|
||||||
self._xTail.tail = ""
|
self._xTail.tail = ""
|
||||||
self._nState = X_ROOT_TAIL
|
self._nState = X_ROOT_TAIL
|
||||||
self._chrPos += 1
|
self._chrPos += 1
|
||||||
|
|
||||||
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
||||||
self._xSing = etree.SubElement(self._xTail, TAG_BR)
|
self._xSing = ET.SubElement(self._xTail, TAG_BR)
|
||||||
self._xSing.tail = ""
|
self._xSing.tail = ""
|
||||||
self._nState = X_SPAN_SING
|
self._nState = X_SPAN_SING
|
||||||
self._chrPos += 1
|
self._chrPos += 1
|
||||||
|
|
||||||
elif c == "\t":
|
elif c == "\t":
|
||||||
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
||||||
self._xTail = etree.SubElement(self._xRoot, TAG_TAB)
|
self._xTail = ET.SubElement(self._xRoot, TAG_TAB)
|
||||||
self._xTail.tail = ""
|
self._xTail.tail = ""
|
||||||
self._nState = X_ROOT_TAIL
|
self._nState = X_ROOT_TAIL
|
||||||
self._chrPos += 1
|
self._chrPos += 1
|
||||||
|
|
||||||
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
||||||
self._xSing = etree.SubElement(self._xTail, TAG_TAB)
|
self._xSing = ET.SubElement(self._xTail, TAG_TAB)
|
||||||
self._xSing.tail = ""
|
self._xSing.tail = ""
|
||||||
self._chrPos += 1
|
self._chrPos += 1
|
||||||
self._nState = X_SPAN_SING
|
self._nState = X_SPAN_SING
|
||||||
@@ -1426,7 +1417,7 @@ class XMLParagraph:
|
|||||||
Therefore we return to the root element level when we're done
|
Therefore we return to the root element level when we're done
|
||||||
processing the text of the span.
|
processing the text of the span.
|
||||||
"""
|
"""
|
||||||
self._xTail = etree.SubElement(self._xRoot, TAG_SPAN, attrib={
|
self._xTail = ET.SubElement(self._xRoot, TAG_SPAN, attrib={
|
||||||
TAG_STNM: tFmt
|
TAG_STNM: tFmt
|
||||||
})
|
})
|
||||||
self._xTail.text = "" # Defaults to None
|
self._xTail.text = "" # Defaults to None
|
||||||
@@ -1478,20 +1469,20 @@ class XMLParagraph:
|
|||||||
|
|
||||||
if nSpaces == 2:
|
if nSpaces == 2:
|
||||||
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
||||||
self._xTail = etree.SubElement(self._xRoot, TAG_SPC)
|
self._xTail = ET.SubElement(self._xRoot, TAG_SPC)
|
||||||
self._xTail.tail = ""
|
self._xTail.tail = ""
|
||||||
self._nState = X_ROOT_TAIL
|
self._nState = X_ROOT_TAIL
|
||||||
self._chrPos += nSpaces - 1
|
self._chrPos += nSpaces - 1
|
||||||
|
|
||||||
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
||||||
self._xSing = etree.SubElement(self._xTail, TAG_SPC)
|
self._xSing = ET.SubElement(self._xTail, TAG_SPC)
|
||||||
self._xSing.tail = ""
|
self._xSing.tail = ""
|
||||||
self._nState = X_SPAN_SING
|
self._nState = X_SPAN_SING
|
||||||
self._chrPos += nSpaces - 1
|
self._chrPos += nSpaces - 1
|
||||||
|
|
||||||
elif nSpaces > 2:
|
elif nSpaces > 2:
|
||||||
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
if self._nState in (X_ROOT_TEXT, X_ROOT_TAIL):
|
||||||
self._xTail = etree.SubElement(self._xRoot, TAG_SPC, attrib={
|
self._xTail = ET.SubElement(self._xRoot, TAG_SPC, attrib={
|
||||||
TAG_NSPC: str(nSpaces - 1)
|
TAG_NSPC: str(nSpaces - 1)
|
||||||
})
|
})
|
||||||
self._xTail.tail = ""
|
self._xTail.tail = ""
|
||||||
@@ -1499,7 +1490,7 @@ class XMLParagraph:
|
|||||||
self._chrPos += nSpaces - 1
|
self._chrPos += nSpaces - 1
|
||||||
|
|
||||||
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
elif self._nState in (X_SPAN_TEXT, X_SPAN_SING):
|
||||||
self._xSing = etree.SubElement(self._xTail, TAG_SPC, attrib={
|
self._xSing = ET.SubElement(self._xTail, TAG_SPC, attrib={
|
||||||
TAG_NSPC: str(nSpaces - 1)
|
TAG_NSPC: str(nSpaces - 1)
|
||||||
})
|
})
|
||||||
self._xSing.tail = ""
|
self._xSing.tail = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user