From 1d90d6d3859e61d94f699844ef1f36d3bcff0598 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 29 May 2023 21:47:13 +0200 Subject: [PATCH] Update XML classes and tests --- novelwriter/core/projectxml.py | 6 +- novelwriter/core/toodt.py | 33 ++++--- sample/nwProject.nwx | 8 +- .../guiBuild_Tool_Step1_Lorem_Ipsum.fodt | 11 +-- .../guiBuild_Tool_Step2_Lorem_Ipsum.fodt | 89 ++++++++++--------- .../guiBuild_Tool_Step3_Lorem_Ipsum.fodt | 89 ++++++++++--------- tests/test_core/test_core_toodt.py | 55 ++++++------ 7 files changed, 143 insertions(+), 148 deletions(-) diff --git a/novelwriter/core/projectxml.py b/novelwriter/core/projectxml.py index a103774b..b39356a2 100644 --- a/novelwriter/core/projectxml.py +++ b/novelwriter/core/projectxml.py @@ -25,7 +25,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import sys import logging import xml.etree.ElementTree as ET @@ -561,10 +560,7 @@ class ProjectXMLWriter: backFile = saveFile.with_suffix(".bak") try: xml = ET.ElementTree(xRoot) - if sys.hexversion < 0x030900f0: - xmlIndent(xml, space=" ") - else: - ET.indent(xml, space=" ") + xmlIndent(xml) xml.write(tempFile, encoding="utf-8", xml_declaration=True) except Exception as exc: self._error = exc diff --git a/novelwriter/core/toodt.py b/novelwriter/core/toodt.py index dd980d23..1725a4c7 100644 --- a/novelwriter/core/toodt.py +++ b/novelwriter/core/toodt.py @@ -92,20 +92,20 @@ class ToOdt(Tokenizer): self._isFlat = isFlat # Flat: .fodt, otherwise .odt - self._dFlat = None # FODT file XML root - self._dCont = None # ODT content.xml root - self._dMeta = None # ODT meta.xml root - self._dStyl = None # ODT styles.xml root + self._dFlat = ET.Element("") # FODT file XML root + self._dCont = ET.Element("") # ODT content.xml root + self._dMeta = ET.Element("") # ODT meta.xml root + self._dStyl = ET.Element("") # ODT styles.xml root - self._xMeta = None # Office meta root - self._xFont = None # Office font face declaration - self._xFnt2 = None # Office font face declaration, secondary - self._xStyl = None # Office styles root - self._xAuto = None # Office auto-styles root - self._xAut2 = None # Office auto-styles root, secondary - self._xMast = None # Office master-styles root - self._xBody = None # Office body root - self._xText = None # Office text root + self._xMeta = ET.Element("") # Office meta root + self._xFont = ET.Element("") # Office font face declaration + self._xFnt2 = ET.Element("") # Office font face declaration, secondary + self._xStyl = ET.Element("") # Office styles root + self._xAuto = ET.Element("") # Office auto-styles root + self._xAut2 = ET.Element("") # Office auto-styles root, secondary + self._xMast = ET.Element("") # Office master-styles root + self._xBody = ET.Element("") # Office body root + self._xText = ET.Element("") # Office text root self._mainPara = {} # User-accessible paragraph styles self._autoPara = {} # Auto-generated paragraph styles @@ -502,7 +502,7 @@ class ToOdt(Tokenizer): """ with open(savePath, mode="wb") as outFile: xml = ET.ElementTree(self._dFlat) - xmlIndent(xml, space=" ") + xmlIndent(xml) xml.write(outFile, encoding="utf-8", xml_declaration=True) return @@ -529,7 +529,6 @@ class ToOdt(Tokenizer): def putInZip(name, xObj, zipObj): with zipObj.open(name, mode="w") as fObj: xml = ET.ElementTree(xObj) - xmlIndent(xml, space=" ") xml.write(fObj, encoding="utf-8", xml_declaration=True) with ZipFile(savePath, mode="w") as outZip: @@ -1337,8 +1336,8 @@ class XMLParagraph: def __init__(self, xRoot): self._xRoot = xRoot - self._xTail = None - self._xSing = None + self._xTail = ET.Element("") + self._xSing = ET.Element("") self._nState = X_ROOT_TEXT self._chrPos = 0 diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index 96e22a4a..afb0157a 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,6 +1,6 @@ - - + + Sample Project Sample Project Jane Smith @@ -65,7 +65,7 @@ Chapter One - + Making a Scene @@ -153,4 +153,4 @@ Delete Me! - \ No newline at end of file + diff --git a/tests/reference/guiBuild_Tool_Step1_Lorem_Ipsum.fodt b/tests/reference/guiBuild_Tool_Step1_Lorem_Ipsum.fodt index ce4afc35..de682d59 100644 --- a/tests/reference/guiBuild_Tool_Step1_Lorem_Ipsum.fodt +++ b/tests/reference/guiBuild_Tool_Step1_Lorem_Ipsum.fodt @@ -1,13 +1,13 @@ - 2023-05-29T20:00:01 + 2023-05-29T20:51:32 novelWriter/2.0.7 lipsum.com 40 P0DT0H31M45S Lorem Ipsum - 2023-05-29T20:00:01 + 2023-05-29T20:51:32 lipsum.com @@ -95,16 +95,13 @@ Lorem Ipsum - - By lipsum.com - + By lipsum.com “Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit…” “There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain…” Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of “de Finibus Bonorum et Malorum” (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, “Lorem ipsum dolor sit amet..”, comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from “de Finibus Bonorum et Malorum” by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. Prologue - - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Act One “Fusce maximus felis libero” Chapter 1: Chapter One diff --git a/tests/reference/guiBuild_Tool_Step2_Lorem_Ipsum.fodt b/tests/reference/guiBuild_Tool_Step2_Lorem_Ipsum.fodt index d179c99d..ff23fc4a 100644 --- a/tests/reference/guiBuild_Tool_Step2_Lorem_Ipsum.fodt +++ b/tests/reference/guiBuild_Tool_Step2_Lorem_Ipsum.fodt @@ -1,105 +1,106 @@ - + - 2023-02-12T15:00:22 - novelWriter/2.0.4 + 2023-05-29T20:57:00 + novelWriter/2.0.7 lipsum.com - 38 - P0DT0H31M40S + 40 + P0DT0H31M45S Lorem Ipsum - 2023-02-12T15:00:22 + 2023-05-29T20:57:00 lipsum.com - + - - + + - + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - Lorem Ipsum / lipsum.com / 2 + Lorem Ipsum / lipsum.com / 2 + - + @@ -147,9 +148,9 @@ Ut et consequat enim, quis ornare nibh. In lectus neque, mollis et suscipit et, vestibulum vitae augue. Praesent id ante sit amet odio venenatis placerat a at erat. Sed sed metus sed nisi dictum varius. Integer tincidunt fermentum purus ac porta. Fusce porttitor non risus eget tristique. Donec augue nunc, maximus at fermentum vel, varius et neque. Ut sed consectetur mauris. Quisque ipsum enim, porttitor vitae imperdiet sit amet, tempor et mauris. Aliquam malesuada tincidunt lectus quis blandit. Sed commodo orci felis, quis ultrices tellus facilisis sed. Nunc vel varius est. Duis ullamcorper eu metus in pulvinar. Morbi at sapien dictum, rutrum mauris eget, interdum tellus. Why do we use it? Comment: Exctracted from the lipsum.com website. - It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. - The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. - Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). + It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. + The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. + Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). Chapter Two: Chapter Two Point of View: Bod Plot: Main diff --git a/tests/reference/guiBuild_Tool_Step3_Lorem_Ipsum.fodt b/tests/reference/guiBuild_Tool_Step3_Lorem_Ipsum.fodt index ca391d27..dfa9262c 100644 --- a/tests/reference/guiBuild_Tool_Step3_Lorem_Ipsum.fodt +++ b/tests/reference/guiBuild_Tool_Step3_Lorem_Ipsum.fodt @@ -1,105 +1,106 @@ - + - 2023-02-12T15:01:25 - novelWriter/2.0.4 + 2023-05-29T21:06:32 + novelWriter/2.0.7 lipsum.com - 38 - P0DT0H31M40S + 40 + P0DT0H31M45S Lorem Ipsum - 2023-02-12T15:01:25 + 2023-05-29T21:06:32 lipsum.com - + - - + + - + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - Lorem Ipsum / lipsum.com / 2 + Lorem Ipsum / lipsum.com / 2 + - + @@ -147,9 +148,9 @@ Ut et consequat enim, quis ornare nibh. In lectus neque, mollis et suscipit et, vestibulum vitae augue. Praesent id ante sit amet odio venenatis placerat a at erat. Sed sed metus sed nisi dictum varius. Integer tincidunt fermentum purus ac porta. Fusce porttitor non risus eget tristique. Donec augue nunc, maximus at fermentum vel, varius et neque. Ut sed consectetur mauris. Quisque ipsum enim, porttitor vitae imperdiet sit amet, tempor et mauris. Aliquam malesuada tincidunt lectus quis blandit. Sed commodo orci felis, quis ultrices tellus facilisis sed. Nunc vel varius est. Duis ullamcorper eu metus in pulvinar. Morbi at sapien dictum, rutrum mauris eget, interdum tellus. Why do we use it? Comment: Exctracted from the lipsum.com website. - It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. - The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. - Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). + It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. + The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. + Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). Chapter Two: Chapter Two Point of View: Bod Plot: Main diff --git a/tests/test_core/test_core_toodt.py b/tests/test_core/test_core_toodt.py index c85e473f..55c6d785 100644 --- a/tests/test_core/test_core_toodt.py +++ b/tests/test_core/test_core_toodt.py @@ -64,21 +64,21 @@ def testCoreToOdt_Init(mockGUI): theDoc.initDocument() # Document XML - assert theDoc._dFlat is not None - assert theDoc._dCont is None - assert theDoc._dMeta is None - assert theDoc._dStyl is None + assert theDoc._dFlat.tag == _mkTag("office", "document") + assert theDoc._dCont.tag == "" + assert theDoc._dMeta.tag == "" + assert theDoc._dStyl.tag == "" # Content XML - assert theDoc._xMeta is not None - assert theDoc._xFont is not None - assert theDoc._xFnt2 is None - assert theDoc._xStyl is not None - assert theDoc._xAuto is not None - assert theDoc._xAut2 is None - assert theDoc._xMast is not None - assert theDoc._xBody is not None - assert theDoc._xText is not None + assert theDoc._xMeta.tag == _mkTag("office", "meta") + assert theDoc._xFont.tag == _mkTag("office", "font-face-decls") + assert theDoc._xFnt2.tag == "" + assert theDoc._xStyl.tag == _mkTag("office", "styles") + assert theDoc._xAuto.tag == _mkTag("office", "automatic-styles") + assert theDoc._xAut2.tag == "" + assert theDoc._xMast.tag == _mkTag("office", "master-styles") + assert theDoc._xBody.tag == _mkTag("office", "body") + assert theDoc._xText.tag == _mkTag("office", "text") # ODT Doc # ======= @@ -87,21 +87,22 @@ def testCoreToOdt_Init(mockGUI): theDoc.initDocument() # Document XML - assert theDoc._dFlat is None - assert theDoc._dCont is not None - assert theDoc._dMeta is not None - assert theDoc._dStyl is not None + assert theDoc._dFlat.tag == "" + assert theDoc._dCont.tag == _mkTag("office", "document-content") + assert theDoc._dMeta.tag == _mkTag("office", "document-meta") + assert theDoc._dStyl.tag == _mkTag("office", "document-styles") # Content XML - assert theDoc._xMeta is not None - assert theDoc._xFont is not None - assert theDoc._xFnt2 is not None - assert theDoc._xStyl is not None - assert theDoc._xAuto is not None - assert theDoc._xAut2 is not None - assert theDoc._xMast is not None - assert theDoc._xBody is not None - assert theDoc._xText is not None + assert theDoc._xMeta.tag == _mkTag("office", "meta") + assert theDoc._xFont.tag == _mkTag("office", "font-face-decls") + assert theDoc._xFnt2.tag == _mkTag("office", "font-face-decls") + assert theDoc._xStyl.tag == _mkTag("office", "styles") + assert theDoc._xAuto.tag == _mkTag("office", "automatic-styles") + assert theDoc._xAut2.tag == _mkTag("office", "automatic-styles") + assert theDoc._xMast.tag == _mkTag("office", "master-styles") + assert theDoc._xBody.tag == _mkTag("office", "body") + assert theDoc._xText.tag == _mkTag("office", "text") + # END Test testCoreToOdt_Init @@ -726,7 +727,7 @@ def testCoreToOdt_SaveFull(mockGUI, fncPath, tstPaths): def prettifyXml(inFile, outFile): with open(outFile, mode="wb") as fStream: xml = ET.parse(inFile) - xmlIndent(xml, space=" ") + xmlIndent(xml) xml.write(fStream, encoding="utf-8", xml_declaration=True) prettifyXml(maniOut, maniFile)