Complete the first version of the doc builder class and add test

This commit is contained in:
Veronica Berglyd Olsen
2023-01-10 17:59:23 +01:00
parent 87256ee62f
commit 72e11601a0
2 changed files with 164 additions and 4 deletions
+92 -4
View File
@@ -7,7 +7,7 @@ File History:
Created: 2022-12-01 [2.1b1] Created: 2022-12-01 [2.1b1]
This file is a part of novelWriter This file is a part of novelWriter
Copyright 20182022, Veronica Berglyd Olsen Copyright 20182023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -24,11 +24,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
import logging import logging
import novelwriter
from PyQt5.QtGui import QFont, QFontInfo
from novelwriter.error import formatException from novelwriter.error import formatException
from novelwriter.core.tomd import ToMarkdown
from novelwriter.core.toodt import ToOdt from novelwriter.core.toodt import ToOdt
from novelwriter.core.tohtml import ToHtml from novelwriter.core.tohtml import ToHtml
from novelwriter.core.tomd import ToMarkdown
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -37,6 +40,7 @@ class NWBuildDocument:
def __init__(self, project): def __init__(self, project):
self._conf = novelwriter.CONFIG
self._project = project self._project = project
self._build = {} self._build = {}
self._documents = [] self._documents = []
@@ -48,6 +52,10 @@ class NWBuildDocument:
# Properties # Properties
## ##
@property
def error(self):
return self._error
@property @property
def buildLength(self): def buildLength(self):
return len(self._documents) return len(self._documents)
@@ -142,9 +150,89 @@ class NWBuildDocument:
## ##
def _setupBuild(self, bldObj): def _setupBuild(self, bldObj):
pass """Configure the build object.
"""
# Get Settings
fmtTitle = self._build.get("format.fmtTitle", "%title%")
fmtChapter = self._build.get("format.fmtChapter", "%title%")
fmtUnnumbered = self._build.get("format.fmtUnnumbered", "%title%")
fmtScene = self._build.get("format.fmtScene", "%title%")
fmtSection = self._build.get("format.fmtSection", "%title%")
buildLang = self._build.get("format.buildLang", "en_GB")
hideScene = self._build.get("format.hideScene", False)
hideSection = self._build.get("format.hideSection", False)
textFont = self._build.get("format.textFont", self._conf.textFont)
textSize = self._build.get("format.textSize", self._conf.textSize)
lineHeight = self._build.get("format.lineHeight", 1.15)
justifyText = self._build.get("format.justifyText", False)
noStyling = self._build.get("format.noStyling", False)
replaceUCode = self._build.get("format.replaceUCode", False)
incSynopsis = self._build.get("filter.includeSynopsis", False)
incComments = self._build.get("filter.includeComments", False)
incKeywords = self._build.get("filter.includeKeywords", False)
includeBody = self._build.get("filter.includeBody", True)
# The language lookup dict is reloaded if needed
self._project.setProjectLang(buildLang)
# Get font information
fontInfo = QFontInfo(QFont(textFont, textSize))
textFixed = fontInfo.fixedPitch()
bldObj.setTitleFormat(fmtTitle)
bldObj.setChapterFormat(fmtChapter)
bldObj.setUnNumberedFormat(fmtUnnumbered)
bldObj.setSceneFormat(fmtScene, hideScene)
bldObj.setSectionFormat(fmtSection, hideSection)
bldObj.setFont(textFont, textSize, textFixed)
bldObj.setJustify(justifyText)
bldObj.setLineHeight(lineHeight)
bldObj.setSynopsis(incSynopsis)
bldObj.setComments(incComments)
bldObj.setKeywords(incKeywords)
bldObj.setBodyText(includeBody)
if isinstance(bldObj, ToHtml):
bldObj.setStyles(not noStyling)
bldObj.setReplaceUnicode(replaceUCode)
if isinstance(bldObj, ToOdt):
bldObj.setColourHeaders(not noStyling)
bldObj.setLanguage(buildLang)
bldObj.initDocument()
return
def _doBuild(self, bldObj, tHandle): def _doBuild(self, bldObj, tHandle):
pass """Build a single document and add it to the build object.
"""
tItem = self._project.tree[tHandle]
if tItem is None:
self._error = f"Build: Unknown item '{tHandle}'"
logger.error(self._error)
return False
try:
if tItem.isRootType() and not tItem.isNovelLike():
bldObj.addRootHeading(tItem.itemHandle)
bldObj.doConvert()
elif tItem.isFileType():
bldObj.setText(tItem.itemHandle)
bldObj.doPreProcessing()
bldObj.tokenizeText()
bldObj.doHeaders()
bldObj.doConvert()
bldObj.doPostProcessing()
else:
logger.info(f"Build: Skipping '{tHandle}'")
except Exception:
self._error = f"Build: Failed to build '{tHandle}'"
logger.error(self._error)
return False
return True
# END Class NWBuildDocument # END Class NWBuildDocument
+72
View File
@@ -0,0 +1,72 @@
"""
novelWriter Manuscript Builder Class Tests
============================================
This file is a part of novelWriter
Copyright 20182023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import pytest
from novelwriter.core.project import NWProject
from novelwriter.mbuild.docbuild import NWBuildDocument
BUILD_CONF = {
"format.fmtTitle": "Title: %title%",
"format.fmtChapter": "Chapter: %title%",
"format.fmtUnnumbered": "%title%",
"format.fmtScene": "Scene: %title%",
"format.fmtSection": "Section: %title%",
"format.buildLang": "en_GB",
"format.hideScene": False,
"format.hideSection": False,
"format.textFont": "Arial",
"format.textSize": 12,
"format.lineHeight": 1.5,
"format.justifyText": True,
"format.noStyling": False,
"format.replaceUCode": False,
"filter.includeSynopsis": True,
"filter.includeComments": True,
"filter.includeKeywords": True,
"filter.includeBody": True,
}
@pytest.mark.core
def testMBuildDocBuild_OpenDocument(mockGUI, prjLipsum, fncPath, tstPaths):
"""Test builing an open document manuscript.
"""
theProject = NWProject(mockGUI)
theProject.openProject(prjLipsum)
docBuild = NWBuildDocument(theProject)
docBuild.setBuildConfig(BUILD_CONF)
for tItem in theProject.tree:
docBuild.addDocument(tItem.itemHandle)
count = 0
error = []
for _, success in docBuild.buildOpenDocument(fncPath / "Lorem Ipsum.fodt", True):
count += 1 if success else 0
if docBuild.error:
error.append(docBuild.error)
assert count == 21
assert error == []
# END Test testMBuildDocBuild_OpenDocument