Standardise the save document call for all document classes
This commit is contained in:
@@ -178,10 +178,7 @@ class NWBuildDocument:
|
|||||||
self._cache = makeObj
|
self._cache = makeObj
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if isFlat:
|
makeObj.saveDocument(path)
|
||||||
makeObj.saveFlatXML(path)
|
|
||||||
else:
|
|
||||||
makeObj.saveOpenDocText(path)
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logException()
|
logException()
|
||||||
self._error = formatException(exc)
|
self._error = formatException(exc)
|
||||||
@@ -213,10 +210,7 @@ class NWBuildDocument:
|
|||||||
|
|
||||||
if isinstance(path, Path):
|
if isinstance(path, Path):
|
||||||
try:
|
try:
|
||||||
if asJson:
|
makeObj.saveDocument(path, asJson=asJson)
|
||||||
makeObj.saveHtmlJson(path)
|
|
||||||
else:
|
|
||||||
makeObj.saveHtml5(path)
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logException()
|
logException()
|
||||||
self._error = formatException(exc)
|
self._error = formatException(exc)
|
||||||
@@ -246,7 +240,7 @@ class NWBuildDocument:
|
|||||||
self._cache = makeObj
|
self._cache = makeObj
|
||||||
|
|
||||||
try:
|
try:
|
||||||
makeObj.saveMarkdown(path)
|
makeObj.saveDocument(path)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logException()
|
logException()
|
||||||
self._error = formatException(exc)
|
self._error = formatException(exc)
|
||||||
@@ -276,10 +270,7 @@ class NWBuildDocument:
|
|||||||
|
|
||||||
if isinstance(path, Path):
|
if isinstance(path, Path):
|
||||||
try:
|
try:
|
||||||
if asJson:
|
makeObj.saveRawDocument(path, asJson=asJson)
|
||||||
makeObj.saveRawMarkdownJSON(path)
|
|
||||||
else:
|
|
||||||
makeObj.saveRawMarkdown(path)
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logException()
|
logException()
|
||||||
self._error = formatException(exc)
|
self._error = formatException(exc)
|
||||||
|
|||||||
@@ -290,8 +290,26 @@ class ToHtml(Tokenizer):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def saveHtml5(self, path: str | Path) -> None:
|
def saveDocument(self, path: str | Path, asJson: bool = False) -> None:
|
||||||
"""Save the data to an HTML file."""
|
"""Save the data to an HTML file."""
|
||||||
|
if asJson:
|
||||||
|
ts = time()
|
||||||
|
data = {
|
||||||
|
"meta": {
|
||||||
|
"projectName": self._project.data.name,
|
||||||
|
"novelAuthor": self._project.data.author,
|
||||||
|
"buildTime": int(ts),
|
||||||
|
"buildTimeStr": formatTimeStamp(ts),
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"css": self.getStyleSheet(),
|
||||||
|
"html": [t.replace("\t", "	").rstrip().split("\n") for t in self.fullHTML],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
with open(path, mode="w", encoding="utf-8") as fObj:
|
||||||
|
json.dump(data, fObj, indent=2)
|
||||||
|
|
||||||
|
else:
|
||||||
with open(path, mode="w", encoding="utf-8") as fObj:
|
with open(path, mode="w", encoding="utf-8") as fObj:
|
||||||
fObj.write((
|
fObj.write((
|
||||||
"<!DOCTYPE html>\n"
|
"<!DOCTYPE html>\n"
|
||||||
@@ -314,27 +332,9 @@ class ToHtml(Tokenizer):
|
|||||||
style="\n".join(self.getStyleSheet()),
|
style="\n".join(self.getStyleSheet()),
|
||||||
body=("".join(self._fullHTML)).replace("\t", "	").rstrip(),
|
body=("".join(self._fullHTML)).replace("\t", "	").rstrip(),
|
||||||
))
|
))
|
||||||
logger.info("Wrote file: %s", path)
|
|
||||||
return
|
|
||||||
|
|
||||||
def saveHtmlJson(self, path: str | Path) -> None:
|
|
||||||
"""Save the data to a JSON file."""
|
|
||||||
timeStamp = time()
|
|
||||||
data = {
|
|
||||||
"meta": {
|
|
||||||
"projectName": self._project.data.name,
|
|
||||||
"novelAuthor": self._project.data.author,
|
|
||||||
"buildTime": int(timeStamp),
|
|
||||||
"buildTimeStr": formatTimeStamp(timeStamp),
|
|
||||||
},
|
|
||||||
"text": {
|
|
||||||
"css": self.getStyleSheet(),
|
|
||||||
"html": [t.replace("\t", "	").rstrip().split("\n") for t in self.fullHTML],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
with open(path, mode="w", encoding="utf-8") as fObj:
|
|
||||||
json.dump(data, fObj, indent=2)
|
|
||||||
logger.info("Wrote file: %s", path)
|
logger.info("Wrote file: %s", path)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def replaceTabs(self, nSpaces: int = 8, spaceChar: str = " ") -> None:
|
def replaceTabs(self, nSpaces: int = 8, spaceChar: str = " ") -> None:
|
||||||
|
|||||||
@@ -486,6 +486,10 @@ class Tokenizer(ABC):
|
|||||||
def doConvert(self) -> None:
|
def doConvert(self) -> None:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def saveDocument(self, path: str | Path) -> None:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def addRootHeading(self, tHandle: str) -> None:
|
def addRootHeading(self, tHandle: str) -> None:
|
||||||
"""Add a heading at the start of a new root folder."""
|
"""Add a heading at the start of a new root folder."""
|
||||||
self._text = ""
|
self._text = ""
|
||||||
@@ -1087,22 +1091,16 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def saveRawMarkdown(self, path: str | Path) -> None:
|
def saveRawDocument(self, path: str | Path, asJson: bool = False) -> None:
|
||||||
"""Save the raw text to a plain text file."""
|
"""Save the raw text to a plain text file."""
|
||||||
with open(path, mode="w", encoding="utf-8") as outFile:
|
if asJson:
|
||||||
for nwdPage in self._markdown:
|
ts = time()
|
||||||
outFile.write(nwdPage)
|
|
||||||
return
|
|
||||||
|
|
||||||
def saveRawMarkdownJSON(self, path: str | Path) -> None:
|
|
||||||
"""Save the raw text to a JSON file."""
|
|
||||||
timeStamp = time()
|
|
||||||
data = {
|
data = {
|
||||||
"meta": {
|
"meta": {
|
||||||
"projectName": self._project.data.name,
|
"projectName": self._project.data.name,
|
||||||
"novelAuthor": self._project.data.author,
|
"novelAuthor": self._project.data.author,
|
||||||
"buildTime": int(timeStamp),
|
"buildTime": int(ts),
|
||||||
"buildTimeStr": formatTimeStamp(timeStamp),
|
"buildTimeStr": formatTimeStamp(ts),
|
||||||
},
|
},
|
||||||
"text": {
|
"text": {
|
||||||
"nwd": [page.rstrip("\n").split("\n") for page in self._markdown],
|
"nwd": [page.rstrip("\n").split("\n") for page in self._markdown],
|
||||||
@@ -1110,6 +1108,14 @@ class Tokenizer(ABC):
|
|||||||
}
|
}
|
||||||
with open(path, mode="w", encoding="utf-8") as fObj:
|
with open(path, mode="w", encoding="utf-8") as fObj:
|
||||||
json.dump(data, fObj, indent=2)
|
json.dump(data, fObj, indent=2)
|
||||||
|
|
||||||
|
else:
|
||||||
|
with open(path, mode="w", encoding="utf-8") as outFile:
|
||||||
|
for nwdPage in self._markdown:
|
||||||
|
outFile.write(nwdPage)
|
||||||
|
|
||||||
|
logger.info("Wrote file: %s", path)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ class ToMarkdown(Tokenizer):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def saveMarkdown(self, path: str | Path) -> None:
|
def saveDocument(self, path: str | Path) -> None:
|
||||||
"""Save the data to a plain text file."""
|
"""Save the data to a plain text file."""
|
||||||
with open(path, mode="w", encoding="utf-8") as outFile:
|
with open(path, mode="w", encoding="utf-8") as outFile:
|
||||||
outFile.write("".join(self._fullMD))
|
outFile.write("".join(self._fullMD))
|
||||||
|
|||||||
@@ -543,17 +543,15 @@ class ToOdt(Tokenizer):
|
|||||||
self._xText.insert(0, xFields)
|
self._xText.insert(0, xFields)
|
||||||
return
|
return
|
||||||
|
|
||||||
def saveFlatXML(self, path: str | Path) -> None:
|
def saveDocument(self, path: str | Path) -> None:
|
||||||
"""Save the data to an .fodt file."""
|
"""Save the data to an .fodt or .odt file."""
|
||||||
|
if self._isFlat:
|
||||||
with open(path, mode="wb") as fObj:
|
with open(path, mode="wb") as fObj:
|
||||||
xml = ET.ElementTree(self._dFlat)
|
xml = ET.ElementTree(self._dFlat)
|
||||||
xmlIndent(xml)
|
xmlIndent(xml)
|
||||||
xml.write(fObj, encoding="utf-8", xml_declaration=True)
|
xml.write(fObj, encoding="utf-8", xml_declaration=True)
|
||||||
logger.info("Wrote file: %s", path)
|
|
||||||
return
|
|
||||||
|
|
||||||
def saveOpenDocText(self, path: str | Path) -> None:
|
else:
|
||||||
"""Save the data to an .odt file."""
|
|
||||||
mMani = _mkTag("manifest", "manifest")
|
mMani = _mkTag("manifest", "manifest")
|
||||||
mVers = _mkTag("manifest", "version")
|
mVers = _mkTag("manifest", "version")
|
||||||
mPath = _mkTag("manifest", "full-path")
|
mPath = _mkTag("manifest", "full-path")
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QColor, QFont, QFontMetricsF, QTextBlockFormat, QTextCharFormat,
|
QColor, QFont, QFontMetricsF, QTextBlockFormat, QTextCharFormat,
|
||||||
QTextCursor, QTextDocument
|
QTextCursor, QTextDocument
|
||||||
@@ -273,6 +275,10 @@ class ToQTextDocument(Tokenizer):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def saveDocument(self, path: str | Path) -> None:
|
||||||
|
"""Not implemented."""
|
||||||
|
return
|
||||||
|
|
||||||
def appendFootnotes(self) -> None:
|
def appendFootnotes(self) -> None:
|
||||||
"""Append the footnotes in the buffer."""
|
"""Append the footnotes in the buffer."""
|
||||||
if self._usedNotes:
|
if self._usedNotes:
|
||||||
|
|||||||
@@ -644,12 +644,12 @@ def testFmtToHtml_Save(mockGUI, fncPath):
|
|||||||
)
|
)
|
||||||
|
|
||||||
saveFile = fncPath / "outFile.htm"
|
saveFile = fncPath / "outFile.htm"
|
||||||
html.saveHtml5(saveFile)
|
html.saveDocument(saveFile, asJson=False)
|
||||||
assert saveFile.read_text(encoding="utf-8") == htmlDoc
|
assert saveFile.read_text(encoding="utf-8") == htmlDoc
|
||||||
|
|
||||||
# JSON + HTML
|
# JSON + HTML
|
||||||
saveFile = fncPath / "outFile.json"
|
saveFile = fncPath / "outFile.json"
|
||||||
html.saveHtmlJson(saveFile)
|
html.saveDocument(saveFile, asJson=True)
|
||||||
data = json.loads(saveFile.read_text(encoding="utf-8"))
|
data = json.loads(saveFile.read_text(encoding="utf-8"))
|
||||||
assert data["meta"]["projectName"] == ""
|
assert data["meta"]["projectName"] == ""
|
||||||
assert data["meta"]["novelAuthor"] == ""
|
assert data["meta"]["novelAuthor"] == ""
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ class BareTokenizer(Tokenizer):
|
|||||||
def doConvert(self):
|
def doConvert(self):
|
||||||
super().doConvert() # type: ignore (deliberate check)
|
super().doConvert() # type: ignore (deliberate check)
|
||||||
|
|
||||||
|
def saveDocument(self, path) -> None:
|
||||||
|
super().saveDocument(path) # type: ignore (deliberate check)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testFmtToken_Setters(mockGUI):
|
def testFmtToken_Setters(mockGUI):
|
||||||
@@ -219,12 +222,12 @@ def testFmtToken_TextOps(monkeypatch, mockGUI, mockRnd, fncPath):
|
|||||||
|
|
||||||
# Save File
|
# Save File
|
||||||
savePath = fncPath / "dump.nwd"
|
savePath = fncPath / "dump.nwd"
|
||||||
tokens.saveRawMarkdown(savePath)
|
tokens.saveRawDocument(savePath, asJson=False)
|
||||||
assert readFile(savePath) == (
|
assert readFile(savePath) == (
|
||||||
"#! Notes: Plot\n\n"
|
"#! Notes: Plot\n\n"
|
||||||
"#! Notes: Plot\n\n"
|
"#! Notes: Plot\n\n"
|
||||||
)
|
)
|
||||||
tokens.saveRawMarkdownJSON(savePath)
|
tokens.saveRawDocument(savePath, asJson=True)
|
||||||
assert json.loads(readFile(savePath))["text"] == {
|
assert json.loads(readFile(savePath))["text"] == {
|
||||||
"nwd": [
|
"nwd": [
|
||||||
["#! Notes: Plot"],
|
["#! Notes: Plot"],
|
||||||
@@ -232,10 +235,13 @@ def testFmtToken_TextOps(monkeypatch, mockGUI, mockRnd, fncPath):
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check abstract method
|
# Check abstract methods
|
||||||
with pytest.raises(NotImplementedError):
|
with pytest.raises(NotImplementedError):
|
||||||
tokens.doConvert()
|
tokens.doConvert()
|
||||||
|
|
||||||
|
with pytest.raises(NotImplementedError):
|
||||||
|
tokens.saveDocument(fncPath)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testFmtToken_StripEscape():
|
def testFmtToken_StripEscape():
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ def testFmtToMarkdown_Save(mockGUI, fncPath):
|
|||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
saveFile = fncPath / "outFile.md"
|
saveFile = fncPath / "outFile.md"
|
||||||
toMD.saveMarkdown(saveFile)
|
toMD.saveDocument(saveFile)
|
||||||
assert saveFile.read_text(encoding="utf-8") == "".join(resText)
|
assert saveFile.read_text(encoding="utf-8") == "".join(resText)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -802,7 +802,7 @@ def testFmtToOdt_SaveFlat(mockGUI, fncPath, tstPaths):
|
|||||||
testFile = tstPaths.outDir / "coreToOdt_SaveFlat_document.fodt"
|
testFile = tstPaths.outDir / "coreToOdt_SaveFlat_document.fodt"
|
||||||
compFile = tstPaths.refDir / "coreToOdt_SaveFlat_document.fodt"
|
compFile = tstPaths.refDir / "coreToOdt_SaveFlat_document.fodt"
|
||||||
|
|
||||||
odt.saveFlatXML(flatFile)
|
odt.saveDocument(flatFile)
|
||||||
assert flatFile.exists()
|
assert flatFile.exists()
|
||||||
|
|
||||||
copyfile(flatFile, testFile)
|
copyfile(flatFile, testFile)
|
||||||
@@ -837,7 +837,7 @@ def testFmtToOdt_SaveFull(mockGUI, fncPath, tstPaths):
|
|||||||
|
|
||||||
fullFile = fncPath / "document.odt"
|
fullFile = fncPath / "document.odt"
|
||||||
|
|
||||||
odt.saveOpenDocText(fullFile)
|
odt.saveDocument(fullFile)
|
||||||
assert fullFile.exists()
|
assert fullFile.exists()
|
||||||
assert zipfile.is_zipfile(fullFile)
|
assert zipfile.is_zipfile(fullFile)
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
|
|||||||
project = NWProject()
|
project = NWProject()
|
||||||
qdoc = ToQTextDocument(project)
|
qdoc = ToQTextDocument(project)
|
||||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||||
|
qdoc.saveDocument("") # Doesn't do anything for this format
|
||||||
|
|
||||||
qdoc._isNovel = True
|
qdoc._isNovel = True
|
||||||
qdoc._isFirst = True
|
qdoc._isFirst = True
|
||||||
|
|||||||
Reference in New Issue
Block a user