Merge pull request #660 from vkbo/build_tool

Build Tool Updates
This commit is contained in:
Veronica K. Berglyd Olsen
2021-02-10 19:30:40 +00:00
committed by GitHub
16 changed files with 461 additions and 310 deletions
+3 -1
View File
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from nw.constants.iso import isoLanguage, isoCountry from nw.constants.iso import isoLanguage, isoCountry
from nw.constants.constants import ( from nw.constants.constants import (
nwConst, nwLists, nwRegEx, nwFiles, nwKeyWords, nwLabels, nwQuotes, nwUnicode nwConst, nwLists, nwRegEx, nwFiles, nwKeyWords, nwLabels, nwQuotes,
nwUnicode, nwHtmlUnicode
) )
from nw.constants.enum import ( from nw.constants.enum import (
nwAlert, nwDocAction, nwItemClass, nwItemLayout, nwItemType, nwOutline, nwAlert, nwDocAction, nwItemClass, nwItemLayout, nwItemType, nwOutline,
@@ -19,6 +20,7 @@ __all__ = [
"nwLabels", "nwLabels",
"nwQuotes", "nwQuotes",
"nwUnicode", "nwUnicode",
"nwHtmlUnicode",
"nwAlert", "nwAlert",
"nwDocAction", "nwDocAction",
"nwItemClass", "nwItemClass",
+59 -2
View File
@@ -265,7 +265,7 @@ class nwUnicode:
U_LCQUO = "\u300c" # Left corner bracket U_LCQUO = "\u300c" # Left corner bracket
U_RCQUO = "\u300d" # Right corner bracket U_RCQUO = "\u300d" # Right corner bracket
U_LWCQUO = "\u300e" # Left white corner bracket U_LWCQUO = "\u300e" # Left white corner bracket
U_RECQUO = "\u300f" # Right white corner bracket U_RWCQUO = "\u300f" # Right white corner bracket
## Punctuation ## Punctuation
U_FGDASH = "\u2012" # Figure dash U_FGDASH = "\u2012" # Figure dash
@@ -331,7 +331,7 @@ class nwUnicode:
H_LCQUO = "「" H_LCQUO = "「"
H_RCQUO = "」" H_RCQUO = "」"
H_LWCQUO = "『" H_LWCQUO = "『"
H_LWCQUO = "『" H_RWCQUO = "』"
## Punctuation ## Punctuation
H_FGDASH = "‒" H_FGDASH = "‒"
@@ -374,3 +374,60 @@ class nwUnicode:
H_LTRIS = "◂" H_LTRIS = "◂"
# END Class nwUnicode # END Class nwUnicode
class nwHtmlUnicode():
U_TO_H = {
## Quotes
nwUnicode.U_QUOT : nwUnicode.H_QUOT,
nwUnicode.U_APOS : nwUnicode.H_APOS,
nwUnicode.U_LAQUO : nwUnicode.H_LAQUO,
nwUnicode.U_RAQUO : nwUnicode.H_RAQUO,
nwUnicode.U_LSQUO : nwUnicode.H_LSQUO,
nwUnicode.U_RSQUO : nwUnicode.H_RSQUO,
nwUnicode.U_SBQUO : nwUnicode.H_SBQUO,
nwUnicode.U_SUQUO : nwUnicode.H_SUQUO,
nwUnicode.U_LDQUO : nwUnicode.H_LDQUO,
nwUnicode.U_RDQUO : nwUnicode.H_RDQUO,
nwUnicode.U_BDQUO : nwUnicode.H_BDQUO,
nwUnicode.U_UDQUO : nwUnicode.H_UDQUO,
nwUnicode.U_LSAQUO : nwUnicode.H_LSAQUO,
nwUnicode.U_RSAQUO : nwUnicode.H_RSAQUO,
nwUnicode.U_BDRQUO : nwUnicode.H_BDRQUO,
nwUnicode.U_LCQUO : nwUnicode.H_LCQUO,
nwUnicode.U_RCQUO : nwUnicode.H_RCQUO,
nwUnicode.U_LWCQUO : nwUnicode.H_LWCQUO,
nwUnicode.U_RWCQUO : nwUnicode.H_RWCQUO,
## Punctuation
nwUnicode.U_FGDASH : nwUnicode.H_FGDASH,
nwUnicode.U_ENDASH : nwUnicode.H_ENDASH,
nwUnicode.U_EMDASH : nwUnicode.H_EMDASH,
nwUnicode.U_HBAR : nwUnicode.H_HBAR,
nwUnicode.U_HELLIP : nwUnicode.H_HELLIP,
nwUnicode.U_MAPOSS : nwUnicode.H_MAPOSS,
nwUnicode.U_PRIME : nwUnicode.H_PRIME,
nwUnicode.U_DPRIME : nwUnicode.H_DPRIME,
## Spaces
nwUnicode.U_NBSP : nwUnicode.H_NBSP,
nwUnicode.U_THSP : nwUnicode.H_THSP,
nwUnicode.U_THNBSP : nwUnicode.H_THNBSP,
nwUnicode.U_ENSP : nwUnicode.H_ENSP,
nwUnicode.U_EMSP : nwUnicode.H_EMSP,
## Symbols
nwUnicode.U_CHECK : nwUnicode.H_CHECK,
nwUnicode.U_CROSS : nwUnicode.H_CROSS,
nwUnicode.U_BULL : nwUnicode.H_BULL,
nwUnicode.U_TRBULL : nwUnicode.H_TRBULL,
nwUnicode.U_HYBULL : nwUnicode.H_HYBULL,
nwUnicode.U_FLOWER : nwUnicode.H_FLOWER,
nwUnicode.U_PERMIL : nwUnicode.H_PERMIL,
nwUnicode.U_DEGREE : nwUnicode.H_DEGREE,
nwUnicode.U_MINUS : nwUnicode.H_MINUS,
nwUnicode.U_TIMES : nwUnicode.H_TIMES,
nwUnicode.U_DIVIDE : nwUnicode.H_DIVIDE,
}
# END Class nwHtmlUnicode
+2
View File
@@ -73,12 +73,14 @@ class OptionState():
"excludeBody", "excludeBody",
"textFont", "textFont",
"textSize", "textSize",
"lineHeight",
"noStyling", "noStyling",
"incSynopsis", "incSynopsis",
"incComments", "incComments",
"incKeywords", "incKeywords",
"incBodyText", "incBodyText",
"replaceTabs", "replaceTabs",
"replaceUCode",
}, },
"GuiOutline": { "GuiOutline": {
"headerOrder", "headerOrder",
+99 -64
View File
@@ -25,10 +25,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
import logging import logging
import re
from nw.core.tokenizer import Tokenizer from nw.core.tokenizer import Tokenizer
from nw.constants import nwUnicode, nwLabels, nwKeyWords from nw.constants import nwLabels, nwKeyWords, nwHtmlUnicode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -41,27 +40,13 @@ class ToHtml(Tokenizer):
def __init__(self, theProject, theParent): def __init__(self, theProject, theParent):
Tokenizer.__init__(self, theProject, theParent) Tokenizer.__init__(self, theProject, theParent)
self.genMode = self.M_EXPORT self.genMode = self.M_EXPORT
self.cssStyles = True self.cssStyles = True
self.fullHTML = []
self.repDict = { # Internals
"<" : "&lt;", self._trMap = {}
">" : "&gt;", self.setReplaceUnicode(False)
"&" : "&amp;",
nwUnicode.U_ENDASH : nwUnicode.H_ENDASH,
nwUnicode.U_EMDASH : nwUnicode.H_EMDASH,
nwUnicode.U_HELLIP : nwUnicode.H_HELLIP,
nwUnicode.U_NBSP : nwUnicode.H_NBSP,
nwUnicode.U_THSP : nwUnicode.H_THSP,
nwUnicode.U_THNBSP : nwUnicode.H_THNBSP,
nwUnicode.U_MAPOSS : nwUnicode.H_RSQUO,
}
self.revDict = {}
self.reReplace = []
self.reReverse = []
self._buildRegEx()
self.fullHTML = []
return return
@@ -88,6 +73,23 @@ class ToHtml(Tokenizer):
self.cssStyles = cssStyles self.cssStyles = cssStyles
return return
def setReplaceUnicode(self, doReplace):
"""Set the translation map to either minimal or full unicode to
html entities replacement.
"""
# Control characters must always be replaced
self._trMap = str.maketrans({
"<" : "&lt;",
">" : "&gt;",
"&" : "&amp;",
})
if doReplace:
# Extend to all relevant Unicode characters
self._trMap.update(str.maketrans(nwHtmlUnicode.U_TO_H))
return
## ##
# Class Methods # Class Methods
## ##
@@ -97,30 +99,12 @@ class ToHtml(Tokenizer):
""" """
return sum([len(x) for x in self.fullHTML]) return sum([len(x) for x in self.fullHTML])
def doAutoReplace(self): def doPreProcessing(self):
"""Extend the auto-replace to also properly encode some unicode """Extend the auto-replace to also properly encode some unicode
characters into their respective HTML entities. characters into their respective HTML entities.
""" """
Tokenizer.doAutoReplace(self) Tokenizer.doPreProcessing(self)
self.theText = self.reReplace.sub( self.theText = self.theText.translate(self._trMap)
lambda x: self.repDict[x.group(0)], self.theText
)
return
def doPostProcessing(self):
"""Reverse the html entities replacement on the markdown text.
Otherwise, all the &something; bits will also be in there.
"""
Tokenizer.doPostProcessing(self)
if self.genMode == self.M_PREVIEW:
# Doesn't matter for preview as we don't use the markdown
return
if self.keepMarkdown:
self.theMarkdown[-1] = self.reReverse.sub(
lambda x: self.revDict[x.group(0)], self.theMarkdown[-1]
)
return return
def doConvert(self): def doConvert(self):
@@ -331,21 +315,84 @@ class ToHtml(Tokenizer):
if not self.cssStyles: if not self.cssStyles:
return theStyles return theStyles
mScale = self.lineHeight/1.15
textAlign = "justify" if self.doJustify else "left" textAlign = "justify" if self.doJustify else "left"
theStyles.append("body {font-family: '%s'; font-size: %dpt}" % ( theStyles.append("body {font-family: '%s'; font-size: %dpt;}" % (
self.textFont, self.textSize) self.textFont, self.textSize
) ))
theStyles.append("p {text-align: %s;}" % textAlign) theStyles.append((
theStyles.append("h1, h2 {color: rgb(66, 113, 174);}") "p {"
theStyles.append("h3, h4 {color: rgb(50, 50, 50);}") "text-align: %s; line-height: %d%%; "
theStyles.append("h1, h2, h3, h4 {page-break-after: avoid;}") "margin-top: %.2fem; margin-bottom: %.2fem;"
"}"
) % (
textAlign,
round(100 * self.lineHeight),
mScale * self.marginText[0],
mScale * self.marginText[1],
))
theStyles.append((
"h1 {"
"color: rgb(66, 113, 174); "
"page-break-after: avoid; "
"margin-top: %.2fem; "
"margin-bottom: %.2fem;"
"}"
) % (
mScale * self.marginHead1[0], mScale * self.marginHead1[1]
))
theStyles.append((
"h2 {"
"color: rgb(66, 113, 174); "
"page-break-after: avoid; "
"margin-top: %.2fem; "
"margin-bottom: %.2fem;"
"}"
) % (
mScale * self.marginHead2[0], mScale * self.marginHead2[1]
))
theStyles.append((
"h3 {"
"color: rgb(50, 50, 50); "
"page-break-after: avoid; "
"margin-top: %.2fem; "
"margin-bottom: %.2fem;"
"}"
) % (
mScale * self.marginHead3[0], mScale * self.marginHead3[1]
))
theStyles.append((
"h4 {"
"color: rgb(50, 50, 50); "
"page-break-after: avoid; "
"margin-top: %.2fem; "
"margin-bottom: %.2fem;"
"}"
) % (
mScale * self.marginHead4[0], mScale * self.marginHead4[1]
))
theStyles.append((
".title {"
"font-size: 2.5em; "
"margin-top: %.2fem; "
"margin-bottom: %.2fem;"
"}"
) % (
mScale * self.marginTitle[0], mScale * self.marginTitle[1]
))
theStyles.append((
".sep, .skip {"
"text-align: center; "
"margin-top: %.2fem; "
"margin-bottom: %.2fem;}"
) % (
mScale, mScale
))
theStyles.append("a {color: rgb(66, 113, 174);}") theStyles.append("a {color: rgb(66, 113, 174);}")
theStyles.append(".title {font-size: 2.5em;}")
theStyles.append(".tags {color: rgb(245, 135, 31); font-weight: bold;}") theStyles.append(".tags {color: rgb(245, 135, 31); font-weight: bold;}")
theStyles.append(".break {text-align: left;}") theStyles.append(".break {text-align: left;}")
theStyles.append(".sep {text-align: center; margin-top: 1em; margin-bottom: 1em;}")
theStyles.append(".skip {margin-top: 1em; margin-bottom: 1em;}")
theStyles.append(".synopsis {font-style: italic;}") theStyles.append(".synopsis {font-style: italic;}")
theStyles.append(".comment {font-style: italic; color: rgb(100, 100, 100);}") theStyles.append(".comment {font-style: italic; color: rgb(100, 100, 100);}")
@@ -403,16 +450,4 @@ class ToHtml(Tokenizer):
return retText return retText
def _buildRegEx(self):
"""Build the regular expressions
"""
self.revDict = dict(map(reversed, self.repDict.items()))
self.reReplace = re.compile(
"|".join([re.escape(k) for k in self.repDict.keys()]), flags=re.DOTALL
)
self.reReverse = re.compile(
"|".join([re.escape(k) for k in self.revDict.keys()]), flags=re.DOTALL
)
return
# END Class ToHtml # END Class ToHtml
+9 -4
View File
@@ -32,7 +32,7 @@ from PyQt5.QtCore import QRegularExpression
from nw.core.document import NWDoc from nw.core.document import NWDoc
from nw.core.tools import numberToWord, numberToRoman from nw.core.tools import numberToWord, numberToRoman
from nw.constants import nwConst, nwItemLayout, nwItemType, nwRegEx from nw.constants import nwConst, nwUnicode, nwItemLayout, nwItemType, nwRegEx
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -86,7 +86,7 @@ class Tokenizer():
self.theResult = "" # The result of the last document self.theResult = "" # The result of the last document
self.keepMarkdown = False # Whether to keep the markdown text self.keepMarkdown = False # Whether to keep the markdown text
self.theMarkdown = [] # The result novelWriter markdown of all documents self.theMarkdown = [] # The result novelWriter markdown of all documents
# User Settings # User Settings
self.textFont = "Serif" # Output text font self.textFont = "Serif" # Output text font
@@ -297,9 +297,10 @@ class Tokenizer():
return True return True
def doAutoReplace(self): def doPreProcessing(self):
"""Run through the user's auto-replace dictionary. """Reun trough the various replace doctionaries.
""" """
# Process the user's auto-replace dictionary
if len(self.theProject.autoReplace) > 0: if len(self.theProject.autoReplace) > 0:
repDict = {} repDict = {}
for aKey, aVal in self.theProject.autoReplace.items(): for aKey, aVal in self.theProject.autoReplace.items():
@@ -307,6 +308,10 @@ class Tokenizer():
xRep = re.compile("|".join([re.escape(k) for k in repDict.keys()]), flags=re.DOTALL) xRep = re.compile("|".join([re.escape(k) for k in repDict.keys()]), flags=re.DOTALL)
self.theText = xRep.sub(lambda x: repDict[x.group(0)], self.theText) self.theText = xRep.sub(lambda x: repDict[x.group(0)], self.theText)
# Process the character translation map
trDict = {nwUnicode.U_MAPOSS: nwUnicode.U_RSQUO}
self.theText = self.theText.translate(str.maketrans(trDict))
return return
def doPostProcessing(self): def doPostProcessing(self):
+18 -16
View File
@@ -194,23 +194,25 @@ class ToOdt(Tokenizer):
self._fSizeHead = f"{round(1.15 * self.textSize):d}pt" self._fSizeHead = f"{round(1.15 * self.textSize):d}pt"
self._fSizeText = f"{self.textSize:d}pt" self._fSizeText = f"{self.textSize:d}pt"
self._mTopTitle = self._emToCm(self.marginTitle[0]) mScale = self.lineHeight/1.15
self._mTopHead1 = self._emToCm(self.marginHead1[0])
self._mTopHead2 = self._emToCm(self.marginHead2[0])
self._mTopHead3 = self._emToCm(self.marginHead3[0])
self._mTopHead4 = self._emToCm(self.marginHead4[0])
self._mTopHead = self._emToCm(self.marginHead4[0])
self._mTopText = self._emToCm(self.marginText[0])
self._mTopMeta = self._emToCm(self.marginMeta[0])
self._mBotTitle = self._emToCm(self.marginTitle[1]) self._mTopTitle = self._emToCm(mScale * self.marginTitle[0])
self._mBotHead1 = self._emToCm(self.marginHead1[1]) self._mTopHead1 = self._emToCm(mScale * self.marginHead1[0])
self._mBotHead2 = self._emToCm(self.marginHead2[1]) self._mTopHead2 = self._emToCm(mScale * self.marginHead2[0])
self._mBotHead3 = self._emToCm(self.marginHead3[1]) self._mTopHead3 = self._emToCm(mScale * self.marginHead3[0])
self._mBotHead4 = self._emToCm(self.marginHead4[1]) self._mTopHead4 = self._emToCm(mScale * self.marginHead4[0])
self._mBotHead = self._emToCm(self.marginHead4[1]) self._mTopHead = self._emToCm(mScale * self.marginHead4[0])
self._mBotText = self._emToCm(self.marginText[1]) self._mTopText = self._emToCm(mScale * self.marginText[0])
self._mBotMeta = self._emToCm(self.marginMeta[1]) self._mTopMeta = self._emToCm(mScale * self.marginMeta[0])
self._mBotTitle = self._emToCm(mScale * self.marginTitle[1])
self._mBotHead1 = self._emToCm(mScale * self.marginHead1[1])
self._mBotHead2 = self._emToCm(mScale * self.marginHead2[1])
self._mBotHead3 = self._emToCm(mScale * self.marginHead3[1])
self._mBotHead4 = self._emToCm(mScale * self.marginHead4[1])
self._mBotHead = self._emToCm(mScale * self.marginHead4[1])
self._mBotText = self._emToCm(mScale * self.marginText[1])
self._mBotMeta = self._emToCm(mScale * self.marginMeta[1])
if self.colourHead: if self.colourHead:
self._colHead12 = "#2a6099" self._colHead12 = "#2a6099"
+185 -144
View File
@@ -41,7 +41,7 @@ from PyQt5.QtWidgets import (
qApp, QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel, qApp, QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel,
QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction, QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction,
QFileDialog, QFontDialog, QSpinBox, QScrollArea, QSplitter, QWidget, QFileDialog, QFontDialog, QSpinBox, QScrollArea, QSplitter, QWidget,
QSizePolicy QSizePolicy, QDoubleSpinBox
) )
from nw.common import fuzzyTime, makeFileNameSafe from nw.common import fuzzyTime, makeFileNameSafe
@@ -55,15 +55,17 @@ logger = logging.getLogger(__name__)
class GuiBuildNovel(QDialog): class GuiBuildNovel(QDialog):
FMT_ODT = 1 FMT_PDF = 1 # Print to PDF
FMT_FODT = 2
FMT_PDF = 3 FMT_ODT = 2 # Open Document file
FMT_HTM = 4 FMT_FODT = 3 # Flat Open Document file
FMT_MD = 5 FMT_HTM = 4 # HTML5
FMT_GH = 6 FMT_NWD = 5 # nW Markdown
FMT_NWD = 7 FMT_MD = 6 # Standard Markdown
FMT_JSON_H = 8 FMT_GH = 7 # GitHub Markdown
FMT_JSON_M = 9
FMT_JSON_H = 8 # HTML5 wrapped in JSON
FMT_JSON_M = 9 # nW Markdown wrapped in JSON
def __init__(self, theParent, theProject): def __init__(self, theParent, theProject):
QDialog.__init__(self, theParent) QDialog.__init__(self, theParent)
@@ -93,6 +95,9 @@ class GuiBuildNovel(QDialog):
self.docView = GuiBuildNovelDocView(self, self.theProject) self.docView = GuiBuildNovelDocView(self, self.theProject)
hS = self.theTheme.fontPixelSize
wS = 2*hS
# Title Formats # Title Formats
# ============= # =============
@@ -164,33 +169,39 @@ class GuiBuildNovel(QDialog):
self.boxTitle.addWidget(self.fmtTitle) self.boxTitle.addWidget(self.fmtTitle)
self.boxChapter = QHBoxLayout() self.boxChapter = QHBoxLayout()
self.boxChapter.addWidget(self.fmtChapter) self.boxChapter.addWidget(self.fmtChapter)
self.boxUnnumbered = QHBoxLayout() self.boxUnnumb = QHBoxLayout()
self.boxUnnumbered.addWidget(self.fmtUnnumbered) self.boxUnnumb.addWidget(self.fmtUnnumbered)
self.boxScene = QHBoxLayout() self.boxScene = QHBoxLayout()
self.boxScene.addWidget(self.fmtScene) self.boxScene.addWidget(self.fmtScene)
self.boxSection = QHBoxLayout() self.boxSection = QHBoxLayout()
self.boxSection.addWidget(self.fmtSection) self.boxSection.addWidget(self.fmtSection)
self.titleForm.addWidget(QLabel("Title"), 0, 0, 1, 1, Qt.AlignLeft) titleLabel = QLabel("Title")
self.titleForm.addLayout(self.boxTitle, 0, 1, 1, 1, Qt.AlignRight) chapterLabel = QLabel("Chapter")
self.titleForm.addWidget(QLabel("Chapter"), 1, 0, 1, 1, Qt.AlignLeft) unnumbLabel = QLabel("Unnumbered")
self.titleForm.addLayout(self.boxChapter, 1, 1, 1, 1, Qt.AlignRight) sceneLabel = QLabel("Scene")
self.titleForm.addWidget(QLabel("Unnumbered"), 2, 0, 1, 1, Qt.AlignLeft) sectionLabel = QLabel("Section")
self.titleForm.addLayout(self.boxUnnumbered, 2, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(QLabel("Scene"), 3, 0, 1, 1, Qt.AlignLeft) self.titleForm.addWidget(titleLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addLayout(self.boxScene, 3, 1, 1, 1, Qt.AlignRight) self.titleForm.addLayout(self.boxTitle, 0, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(QLabel("Section"), 4, 0, 1, 1, Qt.AlignLeft) self.titleForm.addWidget(chapterLabel, 1, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addLayout(self.boxSection, 4, 1, 1, 1, Qt.AlignRight) self.titleForm.addLayout(self.boxChapter, 1, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(unnumbLabel, 2, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addLayout(self.boxUnnumb, 2, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(sceneLabel, 3, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addLayout(self.boxScene, 3, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(sectionLabel, 4, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addLayout(self.boxSection, 4, 1, 1, 1, Qt.AlignRight)
self.titleForm.setColumnStretch(0, 0) self.titleForm.setColumnStretch(0, 0)
self.titleForm.setColumnStretch(1, 1) self.titleForm.setColumnStretch(1, 1)
# Text Options # Font Options
# ============= # ============
self.formatGroup = QGroupBox("Formatting Options", self) self.fontGroup = QGroupBox("Font Options", self)
self.formatForm = QGridLayout(self) self.fontForm = QGridLayout(self)
self.formatGroup.setLayout(self.formatForm) self.fontGroup.setLayout(self.fontForm)
## Font Family ## Font Family
self.textFont = QLineEdit() self.textFont = QLineEdit()
@@ -204,98 +215,111 @@ class GuiBuildNovel(QDialog):
self.fontButton.clicked.connect(self._selectFont) self.fontButton.clicked.connect(self._selectFont)
self.textSize = QSpinBox(self) self.textSize = QSpinBox(self)
self.textSize.setFixedWidth(5*self.theTheme.textNWidth) self.textSize.setFixedWidth(6*self.theTheme.textNWidth)
self.textSize.setMinimum(6) self.textSize.setMinimum(6)
self.textSize.setMaximum(72) self.textSize.setMaximum(72)
self.textSize.setSingleStep(1) self.textSize.setSingleStep(1)
self.textSize.setToolTip(
"The size is used for PDF and printing. Other formats have no size set."
)
self.textSize.setValue( self.textSize.setValue(
self.optState.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize) self.optState.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize)
) )
self.justifyText = QSwitch() self.lineHeight = QDoubleSpinBox(self)
self.justifyText.setToolTip( self.lineHeight.setFixedWidth(6*self.theTheme.textNWidth)
"Applies to PDF, printing, HTML, and Open Document exports." self.lineHeight.setMinimum(0.8)
) self.lineHeight.setMaximum(3.0)
self.justifyText.setChecked( self.lineHeight.setSingleStep(0.05)
self.optState.getBool("GuiBuildNovel", "justifyText", False) self.lineHeight.setDecimals(2)
) self.lineHeight.setValue(
self.optState.getFloat("GuiBuildNovel", "lineHeight", 1.15)
self.noStyling = QSwitch()
self.noStyling.setToolTip(
"Disable all styling of the text."
)
self.noStyling.setChecked(
self.optState.getBool("GuiBuildNovel", "noStyling", False)
) )
# Dummy box due to QGridView and QLineEdit expand bug # Dummy box due to QGridView and QLineEdit expand bug
self.boxFont = QHBoxLayout() self.boxFont = QHBoxLayout()
self.boxFont.addWidget(self.textFont) self.boxFont.addWidget(self.textFont)
self.formatForm.addWidget(QLabel("Font family"), 0, 0, 1, 1, Qt.AlignLeft) fontFamilyLabel = QLabel("Font family")
self.formatForm.addLayout(self.boxFont, 0, 1, 1, 1, Qt.AlignRight) fontSizeLabel = QLabel("Font size")
self.formatForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight) lineHeightLabel = QLabel("Line height")
self.formatForm.addWidget(QLabel("Font size"), 1, 0, 1, 1, Qt.AlignLeft) justifyLabel = QLabel("Justify text")
self.formatForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight) stylingLabel = QLabel("Disable styling")
self.formatForm.addWidget(QLabel("Justify text"), 2, 0, 1, 1, Qt.AlignLeft)
self.formatForm.addWidget(self.justifyText, 2, 1, 1, 2, Qt.AlignRight)
self.formatForm.addWidget(QLabel("Disable styling"), 3, 0, 1, 1, Qt.AlignLeft)
self.formatForm.addWidget(self.noStyling, 3, 1, 1, 2, Qt.AlignRight)
self.formatForm.setColumnStretch(0, 0) self.fontForm.addWidget(fontFamilyLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.formatForm.setColumnStretch(1, 1) self.fontForm.addLayout(self.boxFont, 0, 1, 1, 1, Qt.AlignRight)
self.formatForm.setColumnStretch(2, 0) self.fontForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight)
self.fontForm.addWidget(fontSizeLabel, 1, 0, 1, 1, Qt.AlignLeft)
self.fontForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight)
self.fontForm.addWidget(lineHeightLabel, 2, 0, 1, 1, Qt.AlignLeft)
self.fontForm.addWidget(self.lineHeight, 2, 1, 1, 2, Qt.AlignRight)
# Include Switches self.fontForm.setColumnStretch(0, 0)
# ================ self.fontForm.setColumnStretch(1, 1)
self.fontForm.setColumnStretch(2, 0)
self.textGroup = QGroupBox("Text Options", self) # Styling Options
# ===============
self.styleGroup = QGroupBox("Styling Options", self)
self.styleForm = QGridLayout(self)
self.styleGroup.setLayout(self.styleForm)
self.justifyText = QSwitch(width=wS, height=hS)
self.justifyText.setChecked(
self.optState.getBool("GuiBuildNovel", "justifyText", False)
)
self.noStyling = QSwitch(width=wS, height=hS)
self.noStyling.setChecked(
self.optState.getBool("GuiBuildNovel", "noStyling", False)
)
self.styleForm.addWidget(justifyLabel, 1, 0, 1, 1, Qt.AlignLeft)
self.styleForm.addWidget(self.justifyText, 1, 1, 1, 2, Qt.AlignRight)
self.styleForm.addWidget(stylingLabel, 2, 0, 1, 1, Qt.AlignLeft)
self.styleForm.addWidget(self.noStyling, 2, 1, 1, 2, Qt.AlignRight)
self.styleForm.setColumnStretch(0, 0)
self.styleForm.setColumnStretch(1, 1)
# Include Options
# ===============
self.textGroup = QGroupBox("Include Options", self)
self.textForm = QGridLayout(self) self.textForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm) self.textGroup.setLayout(self.textForm)
self.includeSynopsis = QSwitch() self.includeSynopsis = QSwitch(width=wS, height=hS)
self.includeSynopsis.setToolTip(
"Include synopsis comments in the output."
)
self.includeSynopsis.setChecked( self.includeSynopsis.setChecked(
self.optState.getBool("GuiBuildNovel", "incSynopsis", False) self.optState.getBool("GuiBuildNovel", "incSynopsis", False)
) )
self.includeComments = QSwitch() self.includeComments = QSwitch(width=wS, height=hS)
self.includeComments.setToolTip(
"Include plain comments in the output."
)
self.includeComments.setChecked( self.includeComments.setChecked(
self.optState.getBool("GuiBuildNovel", "incComments", False) self.optState.getBool("GuiBuildNovel", "incComments", False)
) )
self.includeKeywords = QSwitch() self.includeKeywords = QSwitch(width=wS, height=hS)
self.includeKeywords.setToolTip(
"Include meta keywords (tags, references) in the output."
)
self.includeKeywords.setChecked( self.includeKeywords.setChecked(
self.optState.getBool("GuiBuildNovel", "incKeywords", False) self.optState.getBool("GuiBuildNovel", "incKeywords", False)
) )
self.includeBody = QSwitch() self.includeBody = QSwitch(width=wS, height=hS)
self.includeBody.setToolTip(
"Include body text in the output."
)
self.includeBody.setChecked( self.includeBody.setChecked(
self.optState.getBool("GuiBuildNovel", "incBodyText", True) self.optState.getBool("GuiBuildNovel", "incBodyText", True)
) )
self.textForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft) synopsisLabel = QLabel("Include synopsis")
self.textForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight) commentsLabel = QLabel("Include comments")
self.textForm.addWidget(QLabel("Include comments"), 1, 0, 1, 1, Qt.AlignLeft) keywordsLabel = QLabel("Include keywords")
self.textForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight) bodyLabel = QLabel("Include body text")
self.textForm.addWidget(QLabel("Include keywords"), 2, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeKeywords, 2, 1, 1, 1, Qt.AlignRight) self.textForm.addWidget(synopsisLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(QLabel("Include body text"), 3, 0, 1, 1, Qt.AlignLeft) self.textForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(self.includeBody, 3, 1, 1, 1, Qt.AlignRight) self.textForm.addWidget(commentsLabel, 1, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(keywordsLabel, 2, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeKeywords, 2, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(bodyLabel, 3, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeBody, 3, 1, 1, 1, Qt.AlignRight)
self.textForm.setColumnStretch(0, 1) self.textForm.setColumnStretch(0, 1)
self.textForm.setColumnStretch(1, 0) self.textForm.setColumnStretch(1, 0)
@@ -307,7 +331,7 @@ class GuiBuildNovel(QDialog):
self.fileForm = QGridLayout(self) self.fileForm = QGridLayout(self)
self.fileGroup.setLayout(self.fileForm) self.fileGroup.setLayout(self.fileForm)
self.novelFiles = QSwitch() self.novelFiles = QSwitch(width=wS, height=hS)
self.novelFiles.setToolTip( self.novelFiles.setToolTip(
"Include files with layouts 'Book', 'Page', 'Partition', " "Include files with layouts 'Book', 'Page', 'Partition', "
"'Chapter', 'Unnumbered', and 'Scene'." "'Chapter', 'Unnumbered', and 'Scene'."
@@ -316,13 +340,13 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "addNovel", True) self.optState.getBool("GuiBuildNovel", "addNovel", True)
) )
self.noteFiles = QSwitch() self.noteFiles = QSwitch(width=wS, height=hS)
self.noteFiles.setToolTip("Include files with layout 'Note'.") self.noteFiles.setToolTip("Include files with layout 'Note'.")
self.noteFiles.setChecked( self.noteFiles.setChecked(
self.optState.getBool("GuiBuildNovel", "addNotes", False) self.optState.getBool("GuiBuildNovel", "addNotes", False)
) )
self.ignoreFlag = QSwitch() self.ignoreFlag = QSwitch(width=wS, height=hS)
self.ignoreFlag.setToolTip( self.ignoreFlag.setToolTip(
"Ignore the 'Include when building project' setting and include " "Ignore the 'Include when building project' setting and include "
"all files in the output." "all files in the output."
@@ -331,12 +355,16 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "ignoreFlag", False) self.optState.getBool("GuiBuildNovel", "ignoreFlag", False)
) )
self.fileForm.addWidget(QLabel("Include novel files"), 0, 0, 1, 1, Qt.AlignLeft) novelLabel = QLabel("Include novel files")
self.fileForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight) notesLabel = QLabel("Include note files")
self.fileForm.addWidget(QLabel("Include note files"), 1, 0, 1, 1, Qt.AlignLeft) exportLabel = QLabel("Ignore export flag")
self.fileForm.addWidget(self.noteFiles, 1, 1, 1, 1, Qt.AlignRight)
self.fileForm.addWidget(QLabel("Ignore export flag"), 2, 0, 1, 1, Qt.AlignLeft) self.fileForm.addWidget(novelLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.fileForm.addWidget(self.ignoreFlag, 2, 1, 1, 1, Qt.AlignRight) self.fileForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight)
self.fileForm.addWidget(notesLabel, 1, 0, 1, 1, Qt.AlignLeft)
self.fileForm.addWidget(self.noteFiles, 1, 1, 1, 1, Qt.AlignRight)
self.fileForm.addWidget(exportLabel, 2, 0, 1, 1, Qt.AlignLeft)
self.fileForm.addWidget(self.ignoreFlag, 2, 1, 1, 1, Qt.AlignRight)
self.fileForm.setColumnStretch(0, 1) self.fileForm.setColumnStretch(0, 1)
self.fileForm.setColumnStretch(1, 0) self.fileForm.setColumnStretch(1, 0)
@@ -348,16 +376,23 @@ class GuiBuildNovel(QDialog):
self.exportForm = QGridLayout(self) self.exportForm = QGridLayout(self)
self.exportGroup.setLayout(self.exportForm) self.exportGroup.setLayout(self.exportForm)
self.replaceTabs = QSwitch() self.replaceTabs = QSwitch(width=wS, height=hS)
self.replaceTabs.setToolTip(
"Replace all tabs with eight spaces."
)
self.replaceTabs.setChecked( self.replaceTabs.setChecked(
self.optState.getBool("GuiBuildNovel", "replaceTabs", False) self.optState.getBool("GuiBuildNovel", "replaceTabs", False)
) )
self.exportForm.addWidget(QLabel("Replace tabs with spaces"), 0, 0, 1, 1, Qt.AlignLeft) self.replaceUCode = QSwitch(width=wS, height=hS)
self.exportForm.addWidget(self.replaceTabs, 0, 1, 1, 1, Qt.AlignRight) self.replaceUCode.setChecked(
self.optState.getBool("GuiBuildNovel", "replaceUCode", False)
)
tabsLabel = QLabel("Replace tabs with spaces")
uCodeLabel = QLabel("Replace Unicode in HTML")
self.exportForm.addWidget(tabsLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.exportForm.addWidget(self.replaceTabs, 0, 1, 1, 1, Qt.AlignRight)
self.exportForm.addWidget(uCodeLabel, 1, 0, 1, 1, Qt.AlignLeft)
self.exportForm.addWidget(self.replaceUCode, 1, 1, 1, 1, Qt.AlignRight)
self.exportForm.setColumnStretch(0, 1) self.exportForm.setColumnStretch(0, 1)
self.exportForm.setColumnStretch(1, 0) self.exportForm.setColumnStretch(1, 0)
@@ -447,7 +482,8 @@ class GuiBuildNovel(QDialog):
# The Tool Box # The Tool Box
self.toolsBox = QVBoxLayout() self.toolsBox = QVBoxLayout()
self.toolsBox.addWidget(self.titleGroup) self.toolsBox.addWidget(self.titleGroup)
self.toolsBox.addWidget(self.formatGroup) self.toolsBox.addWidget(self.fontGroup)
self.toolsBox.addWidget(self.styleGroup)
self.toolsBox.addWidget(self.textGroup) self.toolsBox.addWidget(self.textGroup)
self.toolsBox.addWidget(self.fileGroup) self.toolsBox.addWidget(self.fileGroup)
self.toolsBox.addWidget(self.exportGroup) self.toolsBox.addWidget(self.exportGroup)
@@ -607,6 +643,7 @@ class GuiBuildNovel(QDialog):
fmtSection = self.fmtSection.text().strip() fmtSection = self.fmtSection.text().strip()
textFont = self.textFont.text() textFont = self.textFont.text()
textSize = self.textSize.value() textSize = self.textSize.value()
lineHeight = self.lineHeight.value()
justifyText = self.justifyText.isChecked() justifyText = self.justifyText.isChecked()
noStyling = self.noStyling.isChecked() noStyling = self.noStyling.isChecked()
incSynopsis = self.includeSynopsis.isChecked() incSynopsis = self.includeSynopsis.isChecked()
@@ -616,6 +653,7 @@ class GuiBuildNovel(QDialog):
noteFiles = self.noteFiles.isChecked() noteFiles = self.noteFiles.isChecked()
ignoreFlag = self.ignoreFlag.isChecked() ignoreFlag = self.ignoreFlag.isChecked()
includeBody = self.includeBody.isChecked() includeBody = self.includeBody.isChecked()
replaceUCode = self.replaceUCode.isChecked()
# Get font information # Get font information
fontInfo = QFontInfo(QFont(textFont, textSize)) fontInfo = QFontInfo(QFont(textFont, textSize))
@@ -632,6 +670,7 @@ class GuiBuildNovel(QDialog):
bldObj.setFont(textFont, textSize, textFixed) bldObj.setFont(textFont, textSize, textFixed)
bldObj.setJustify(justifyText) bldObj.setJustify(justifyText)
bldObj.setLineHeight(lineHeight)
bldObj.setSynopsis(incSynopsis) bldObj.setSynopsis(incSynopsis)
bldObj.setComments(incComments) bldObj.setComments(incComments)
@@ -640,6 +679,7 @@ class GuiBuildNovel(QDialog):
if isHtml: if isHtml:
bldObj.setStyles(not noStyling) bldObj.setStyles(not noStyling)
bldObj.setReplaceUnicode(replaceUCode)
if isOdt: if isOdt:
bldObj.setColourHeaders(not noStyling) bldObj.setColourHeaders(not noStyling)
@@ -668,7 +708,7 @@ class GuiBuildNovel(QDialog):
elif self._checkInclude(tItem, noteFiles, novelFiles, ignoreFlag): elif self._checkInclude(tItem, noteFiles, novelFiles, ignoreFlag):
bldObj.setText(tItem.itemHandle) bldObj.setText(tItem.itemHandle)
bldObj.doAutoReplace() bldObj.doPreProcessing()
bldObj.tokenizeText() bldObj.tokenizeText()
bldObj.doHeaders() bldObj.doHeaders()
if doConvert: if doConvert:
@@ -1012,14 +1052,14 @@ class GuiBuildNovel(QDialog):
nw.logException() nw.logException()
return False return False
if "htmlText" in theData.keys(): if "buildTime" in theData.keys():
self.htmlText = theData["htmlText"] self.buildTime = theData["buildTime"]
dataCount += 1
if "htmlStyle" in theData.keys(): if "htmlStyle" in theData.keys():
self.htmlStyle = theData["htmlStyle"] self.htmlStyle = theData["htmlStyle"]
dataCount += 1 dataCount += 1
if "buildTime" in theData.keys(): if "htmlText" in theData.keys():
self.buildTime = theData["buildTime"] self.htmlText = theData["htmlText"]
dataCount += 1
return dataCount == 2 return dataCount == 2
@@ -1032,9 +1072,9 @@ class GuiBuildNovel(QDialog):
try: try:
with open(buildCache, mode="w+", encoding="utf8") as outFile: with open(buildCache, mode="w+", encoding="utf8") as outFile:
outFile.write(json.dumps({ outFile.write(json.dumps({
"htmlText" : self.htmlText,
"htmlStyle" : self.htmlStyle,
"buildTime" : self.buildTime, "buildTime" : self.buildTime,
"htmlStyle" : self.htmlStyle,
"htmlText" : self.htmlText,
}, indent=2)) }, indent=2))
except Exception: except Exception:
logger.error("Failed to save build cache") logger.error("Failed to save build cache")
@@ -1079,46 +1119,47 @@ class GuiBuildNovel(QDialog):
"section" : self.fmtSection.text().strip(), "section" : self.fmtSection.text().strip(),
}) })
winWidth = self.mainConf.rpxInt(self.width()) winWidth = self.mainConf.rpxInt(self.width())
winHeight = self.mainConf.rpxInt(self.height()) winHeight = self.mainConf.rpxInt(self.height())
justifyText = self.justifyText.isChecked() justifyText = self.justifyText.isChecked()
noStyling = self.noStyling.isChecked() noStyling = self.noStyling.isChecked()
textFont = self.textFont.text() textFont = self.textFont.text()
textSize = self.textSize.value() textSize = self.textSize.value()
novelFiles = self.novelFiles.isChecked() lineHeight = self.lineHeight.value()
noteFiles = self.noteFiles.isChecked() novelFiles = self.novelFiles.isChecked()
ignoreFlag = self.ignoreFlag.isChecked() noteFiles = self.noteFiles.isChecked()
incSynopsis = self.includeSynopsis.isChecked() ignoreFlag = self.ignoreFlag.isChecked()
incComments = self.includeComments.isChecked() incSynopsis = self.includeSynopsis.isChecked()
incKeywords = self.includeKeywords.isChecked() incComments = self.includeComments.isChecked()
incBodyText = self.includeBody.isChecked() incKeywords = self.includeKeywords.isChecked()
replaceTabs = self.replaceTabs.isChecked() incBodyText = self.includeBody.isChecked()
replaceTabs = self.replaceTabs.isChecked()
replaceUCode = self.replaceUCode.isChecked()
mainSplit = self.mainSplit.sizes() mainSplit = self.mainSplit.sizes()
if len(mainSplit) == 2: boxWidth = self.mainConf.rpxInt(mainSplit[0])
boxWidth = self.mainConf.rpxInt(mainSplit[0]) docWidth = self.mainConf.rpxInt(mainSplit[1])
docWidth = self.mainConf.rpxInt(mainSplit[1])
else:
boxWidth = 100
docWidth = 100
# GUI Settings # GUI Settings
self.optState.setValue("GuiBuildNovel", "winWidth", winWidth) self.optState.setValue("GuiBuildNovel", "winWidth", winWidth)
self.optState.setValue("GuiBuildNovel", "winHeight", winHeight) self.optState.setValue("GuiBuildNovel", "winHeight", winHeight)
self.optState.setValue("GuiBuildNovel", "boxWidth", boxWidth) self.optState.setValue("GuiBuildNovel", "boxWidth", boxWidth)
self.optState.setValue("GuiBuildNovel", "docWidth", docWidth) self.optState.setValue("GuiBuildNovel", "docWidth", docWidth)
self.optState.setValue("GuiBuildNovel", "justifyText", justifyText) self.optState.setValue("GuiBuildNovel", "justifyText", justifyText)
self.optState.setValue("GuiBuildNovel", "noStyling", noStyling) self.optState.setValue("GuiBuildNovel", "noStyling", noStyling)
self.optState.setValue("GuiBuildNovel", "textFont", textFont) self.optState.setValue("GuiBuildNovel", "textFont", textFont)
self.optState.setValue("GuiBuildNovel", "textSize", textSize) self.optState.setValue("GuiBuildNovel", "textSize", textSize)
self.optState.setValue("GuiBuildNovel", "addNovel", novelFiles) self.optState.setValue("GuiBuildNovel", "lineHeight", lineHeight)
self.optState.setValue("GuiBuildNovel", "addNotes", noteFiles) self.optState.setValue("GuiBuildNovel", "addNovel", novelFiles)
self.optState.setValue("GuiBuildNovel", "ignoreFlag", ignoreFlag) self.optState.setValue("GuiBuildNovel", "addNotes", noteFiles)
self.optState.setValue("GuiBuildNovel", "incSynopsis", incSynopsis) self.optState.setValue("GuiBuildNovel", "ignoreFlag", ignoreFlag)
self.optState.setValue("GuiBuildNovel", "incComments", incComments) self.optState.setValue("GuiBuildNovel", "incSynopsis", incSynopsis)
self.optState.setValue("GuiBuildNovel", "incKeywords", incKeywords) self.optState.setValue("GuiBuildNovel", "incComments", incComments)
self.optState.setValue("GuiBuildNovel", "incBodyText", incBodyText) self.optState.setValue("GuiBuildNovel", "incKeywords", incKeywords)
self.optState.setValue("GuiBuildNovel", "replaceTabs", replaceTabs) self.optState.setValue("GuiBuildNovel", "incBodyText", incBodyText)
self.optState.setValue("GuiBuildNovel", "replaceTabs", replaceTabs)
self.optState.setValue("GuiBuildNovel", "replaceUCode", replaceUCode)
self.optState.saveSettings() self.optState.saveSettings()
return return
+1 -1
View File
@@ -176,7 +176,7 @@ class GuiDocViewer(QTextBrowser):
# See issue #298 # See issue #298
try: try:
aDoc.setText(tHandle) aDoc.setText(tHandle)
aDoc.doAutoReplace() aDoc.doPreProcessing()
aDoc.tokenizeText() aDoc.tokenizeText()
aDoc.doConvert() aDoc.doConvert()
aDoc.doPostProcessing() aDoc.doPostProcessing()
@@ -5,17 +5,17 @@
<title>Lorem Ipsum</title> <title>Lorem Ipsum</title>
</head> </head>
<style> <style>
body {font-family: 'DejaVu Sans'; font-size: 11pt} body {font-family: 'DejaVu Sans'; font-size: 11pt;}
p {text-align: left;} p {text-align: left; line-height: 115%; margin-top: 0.00em; margin-bottom: 0.58em;}
h1, h2 {color: rgb(66, 113, 174);} h1 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.00em; margin-bottom: 0.50em;}
h3, h4 {color: rgb(50, 50, 50);} h2 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 0.83em; margin-bottom: 0.50em;}
h1, h2, h3, h4 {page-break-after: avoid;} h3 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
h4 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
.title {font-size: 2.5em; margin-top: 1.00em; margin-bottom: 0.50em;}
.sep, .skip {text-align: center; margin-top: 1.00em; margin-bottom: 1.00em;}
a {color: rgb(66, 113, 174);} a {color: rgb(66, 113, 174);}
.title {font-size: 2.5em;}
.tags {color: rgb(245, 135, 31); font-weight: bold;} .tags {color: rgb(245, 135, 31); font-weight: bold;}
.break {text-align: left;} .break {text-align: left;}
.sep {text-align: center; margin-top: 1em; margin-bottom: 1em;}
.skip {margin-top: 1em; margin-bottom: 1em;}
.synopsis {font-style: italic;} .synopsis {font-style: italic;}
.comment {font-style: italic; color: rgb(100, 100, 100);} .comment {font-style: italic; color: rgb(100, 100, 100);}
article {width: 800px; margin: 40px auto;} article {width: 800px; margin: 40px auto;}
@@ -24,8 +24,8 @@ article {width: 800px; margin: 40px auto;}
<article> <article>
<h1 class='title' style='text-align: center; page-break-before: auto;'>Lorem Ipsum</h1> <h1 class='title' style='text-align: center; page-break-before: auto;'>Lorem Ipsum</h1>
<p style='text-align: center;'><strong>By lipsum.com</strong></p> <p style='text-align: center;'><strong>By lipsum.com</strong></p>
<p style='text-align: center;'>“Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&hellip;</p> <p style='text-align: center;'>“Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit</p>
<p style='text-align: center;'>“There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain&hellip;</p> <p style='text-align: center;'>“There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain</p>
<p style='text-align: left;'>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.</p> <p style='text-align: left;'>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.</p>
<p style='text-align: left;'>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.</p> <p style='text-align: left;'>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.</p>
<h1 style='page-break-before: always;'>Prologue</h1> <h1 style='page-break-before: always;'>Prologue</h1>
@@ -5,17 +5,17 @@
<title>Lorem Ipsum</title> <title>Lorem Ipsum</title>
</head> </head>
<style> <style>
body {font-family: 'DejaVu Sans'; font-size: 11pt} body {font-family: 'DejaVu Sans'; font-size: 11pt;}
p {text-align: justify;} p {text-align: justify; line-height: 115%; margin-top: 0.00em; margin-bottom: 0.58em;}
h1, h2 {color: rgb(66, 113, 174);} h1 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.00em; margin-bottom: 0.50em;}
h3, h4 {color: rgb(50, 50, 50);} h2 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 0.83em; margin-bottom: 0.50em;}
h1, h2, h3, h4 {page-break-after: avoid;} h3 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
h4 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
.title {font-size: 2.5em; margin-top: 1.00em; margin-bottom: 0.50em;}
.sep, .skip {text-align: center; margin-top: 1.00em; margin-bottom: 1.00em;}
a {color: rgb(66, 113, 174);} a {color: rgb(66, 113, 174);}
.title {font-size: 2.5em;}
.tags {color: rgb(245, 135, 31); font-weight: bold;} .tags {color: rgb(245, 135, 31); font-weight: bold;}
.break {text-align: left;} .break {text-align: left;}
.sep {text-align: center; margin-top: 1em; margin-bottom: 1em;}
.skip {margin-top: 1em; margin-bottom: 1em;}
.synopsis {font-style: italic;} .synopsis {font-style: italic;}
.comment {font-style: italic; color: rgb(100, 100, 100);} .comment {font-style: italic; color: rgb(100, 100, 100);}
article {width: 800px; margin: 40px auto;} article {width: 800px; margin: 40px auto;}
@@ -24,16 +24,16 @@ article {width: 800px; margin: 40px auto;}
<article> <article>
<h1 class='title' style='text-align: center; page-break-before: auto;'>Lorem Ipsum</h1> <h1 class='title' style='text-align: center; page-break-before: auto;'>Lorem Ipsum</h1>
<p style='text-align: center;'><strong>By lipsum.com</strong></p> <p style='text-align: center;'><strong>By lipsum.com</strong></p>
<p style='text-align: center;'>Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&hellip;</p> <p style='text-align: center;'>&ldquo;Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&hellip;&rdquo;</p>
<p style='text-align: center;'>There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain&hellip;</p> <p style='text-align: center;'>&ldquo;There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain&hellip;&rdquo;</p>
<p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p> <p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p>
<p style='text-align: left;'>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.</p> <p style='text-align: left;'>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 &ldquo;de Finibus Bonorum et Malorum&rdquo; (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, &ldquo;Lorem ipsum dolor sit amet..&rdquo;, comes from a line in section 1.10.32.</p>
<p style='text-align: left;'>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.</p> <p style='text-align: left;'>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 &ldquo;de Finibus Bonorum et Malorum&rdquo; by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.</p>
<h1 style='page-break-before: always;'>Prologue</h1> <h1 style='page-break-before: always;'>Prologue</h1>
<p class='synopsis'><strong>Synopsis:</strong> Explanation from the lipsum.com website.</p> <p class='synopsis'><strong>Synopsis:</strong> Explanation from the lipsum.com website.</p>
<p><em>Lorem Ipsum</em> 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.</p> <p><em>Lorem Ipsum</em> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry&#39;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.</p>
<h1 style='text-align: center; page-break-before: always;'>Act One</h1> <h1 style='text-align: center; page-break-before: always;'>Act One</h1>
<p style='text-align: center;'>Fusce maximus felis libero</p> <p style='text-align: center;'>&ldquo;Fusce maximus felis libero&rdquo;</p>
<h1 style='page-break-before: always;'>Chapter One: Chapter One</h1> <h1 style='page-break-before: always;'>Chapter One: Chapter One</h1>
<p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p> <p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p>
<p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p> <p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p>
@@ -65,8 +65,8 @@ article {width: 800px; margin: 40px auto;}
<h1 style='page-break-before: always;'>Chapter Two: Why do we use it?</h1> <h1 style='page-break-before: always;'>Chapter Two: Why do we use it?</h1>
<p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p> <p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p>
<p>&#09;It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.</p> <p>&#09;It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.</p>
<p>&#09;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.</p> <p>&#09;The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using &#39;Content here, content here&#39;, making it look like readable English.</p>
<p>&#09;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).</p> <p>&#09;Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for &#39;lorem ipsum&#39; 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).</p>
<h1 style='page-break-before: always;'>Chapter Three: Chapter Two</h1> <h1 style='page-break-before: always;'>Chapter Three: Chapter Two</h1>
<p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p> <p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p>
<p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p> <p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p>
@@ -5,17 +5,17 @@
<title>Lorem Ipsum</title> <title>Lorem Ipsum</title>
</head> </head>
<style> <style>
body {font-family: 'DejaVu Sans'; font-size: 11pt} body {font-family: 'DejaVu Sans'; font-size: 11pt;}
p {text-align: justify;} p {text-align: justify; line-height: 115%; margin-top: 0.00em; margin-bottom: 0.58em;}
h1, h2 {color: rgb(66, 113, 174);} h1 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.00em; margin-bottom: 0.50em;}
h3, h4 {color: rgb(50, 50, 50);} h2 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 0.83em; margin-bottom: 0.50em;}
h1, h2, h3, h4 {page-break-after: avoid;} h3 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
h4 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
.title {font-size: 2.5em; margin-top: 1.00em; margin-bottom: 0.50em;}
.sep, .skip {text-align: center; margin-top: 1.00em; margin-bottom: 1.00em;}
a {color: rgb(66, 113, 174);} a {color: rgb(66, 113, 174);}
.title {font-size: 2.5em;}
.tags {color: rgb(245, 135, 31); font-weight: bold;} .tags {color: rgb(245, 135, 31); font-weight: bold;}
.break {text-align: left;} .break {text-align: left;}
.sep {text-align: center; margin-top: 1em; margin-bottom: 1em;}
.skip {margin-top: 1em; margin-bottom: 1em;}
.synopsis {font-style: italic;} .synopsis {font-style: italic;}
.comment {font-style: italic; color: rgb(100, 100, 100);} .comment {font-style: italic; color: rgb(100, 100, 100);}
article {width: 800px; margin: 40px auto;} article {width: 800px; margin: 40px auto;}
@@ -24,16 +24,16 @@ article {width: 800px; margin: 40px auto;}
<article> <article>
<h1 class='title' style='text-align: center; page-break-before: auto;'>Lorem Ipsum</h1> <h1 class='title' style='text-align: center; page-break-before: auto;'>Lorem Ipsum</h1>
<p style='text-align: center;'><strong>By lipsum.com</strong></p> <p style='text-align: center;'><strong>By lipsum.com</strong></p>
<p style='text-align: center;'>Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&hellip;</p> <p style='text-align: center;'>&ldquo;Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&hellip;&rdquo;</p>
<p style='text-align: center;'>There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain&hellip;</p> <p style='text-align: center;'>&ldquo;There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain&hellip;&rdquo;</p>
<p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p> <p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p>
<p style='text-align: left;'>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.</p> <p style='text-align: left;'>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 &ldquo;de Finibus Bonorum et Malorum&rdquo; (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, &ldquo;Lorem ipsum dolor sit amet..&rdquo;, comes from a line in section 1.10.32.</p>
<p style='text-align: left;'>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.</p> <p style='text-align: left;'>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 &ldquo;de Finibus Bonorum et Malorum&rdquo; by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.</p>
<h1 style='page-break-before: always;'>Prologue</h1> <h1 style='page-break-before: always;'>Prologue</h1>
<p class='synopsis'><strong>Synopsis:</strong> Explanation from the lipsum.com website.</p> <p class='synopsis'><strong>Synopsis:</strong> Explanation from the lipsum.com website.</p>
<p><em>Lorem Ipsum</em> 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.</p> <p><em>Lorem Ipsum</em> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry&#39;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.</p>
<h1 style='text-align: center; page-break-before: always;'>Act One</h1> <h1 style='text-align: center; page-break-before: always;'>Act One</h1>
<p style='text-align: center;'>Fusce maximus felis libero</p> <p style='text-align: center;'>&ldquo;Fusce maximus felis libero&rdquo;</p>
<h1 style='page-break-before: always;'>Chapter One: Chapter One</h1> <h1 style='page-break-before: always;'>Chapter One: Chapter One</h1>
<p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p> <p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p>
<p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p> <p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p>
@@ -65,8 +65,8 @@ article {width: 800px; margin: 40px auto;}
<h1 style='page-break-before: always;'>Chapter Two: Why do we use it?</h1> <h1 style='page-break-before: always;'>Chapter Two: Why do we use it?</h1>
<p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p> <p class='comment'><strong>Comment:</strong> Exctracted from the lipsum.com website.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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.</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using &#39;Content here, content here&#39;, making it look like readable English.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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).</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for &#39;lorem ipsum&#39; 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).</p>
<h1 style='page-break-before: always;'>Chapter Three: Chapter Two</h1> <h1 style='page-break-before: always;'>Chapter Three: Chapter Two</h1>
<p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p> <p style='margin-bottom: 0;'><span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a></p>
<p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p> <p style='margin-bottom: 0; margin-top: 0;'><span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a></p>
@@ -5,21 +5,21 @@
"authors": [ "authors": [
"lipsum.com" "lipsum.com"
], ],
"buildTime": 1611863279 "buildTime": 1612954696
}, },
"text": { "text": {
"css": [ "css": [
"body {font-family: 'DejaVu Sans'; font-size: 11pt}", "body {font-family: 'DejaVu Sans'; font-size: 11pt;}",
"p {text-align: justify;}", "p {text-align: justify; line-height: 115%; margin-top: 0.00em; margin-bottom: 0.58em;}",
"h1, h2 {color: rgb(66, 113, 174);}", "h1 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.00em; margin-bottom: 0.50em;}",
"h3, h4 {color: rgb(50, 50, 50);}", "h2 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 0.83em; margin-bottom: 0.50em;}",
"h1, h2, h3, h4 {page-break-after: avoid;}", "h3 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}",
"h4 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}",
".title {font-size: 2.5em; margin-top: 1.00em; margin-bottom: 0.50em;}",
".sep, .skip {text-align: center; margin-top: 1.00em; margin-bottom: 1.00em;}",
"a {color: rgb(66, 113, 174);}", "a {color: rgb(66, 113, 174);}",
".title {font-size: 2.5em;}",
".tags {color: rgb(245, 135, 31); font-weight: bold;}", ".tags {color: rgb(245, 135, 31); font-weight: bold;}",
".break {text-align: left;}", ".break {text-align: left;}",
".sep {text-align: center; margin-top: 1em; margin-bottom: 1em;}",
".skip {margin-top: 1em; margin-bottom: 1em;}",
".synopsis {font-style: italic;}", ".synopsis {font-style: italic;}",
".comment {font-style: italic; color: rgb(100, 100, 100);}" ".comment {font-style: italic; color: rgb(100, 100, 100);}"
], ],
@@ -5,17 +5,17 @@
<title>Lorem Ipsum</title> <title>Lorem Ipsum</title>
</head> </head>
<style> <style>
body {font-family: 'DejaVu Sans'; font-size: 11pt} body {font-family: 'DejaVu Sans'; font-size: 11pt;}
p {text-align: justify;} p {text-align: justify; line-height: 115%; margin-top: 0.00em; margin-bottom: 0.58em;}
h1, h2 {color: rgb(66, 113, 174);} h1 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.00em; margin-bottom: 0.50em;}
h3, h4 {color: rgb(50, 50, 50);} h2 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 0.83em; margin-bottom: 0.50em;}
h1, h2, h3, h4 {page-break-after: avoid;} h3 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
h4 {color: rgb(50, 50, 50); page-break-after: avoid; margin-top: 0.58em; margin-bottom: 0.50em;}
.title {font-size: 2.5em; margin-top: 1.00em; margin-bottom: 0.50em;}
.sep, .skip {text-align: center; margin-top: 1.00em; margin-bottom: 1.00em;}
a {color: rgb(66, 113, 174);} a {color: rgb(66, 113, 174);}
.title {font-size: 2.5em;}
.tags {color: rgb(245, 135, 31); font-weight: bold;} .tags {color: rgb(245, 135, 31); font-weight: bold;}
.break {text-align: left;} .break {text-align: left;}
.sep {text-align: center; margin-top: 1em; margin-bottom: 1em;}
.skip {margin-top: 1em; margin-bottom: 1em;}
.synopsis {font-style: italic;} .synopsis {font-style: italic;}
.comment {font-style: italic; color: rgb(100, 100, 100);} .comment {font-style: italic; color: rgb(100, 100, 100);}
article {width: 800px; margin: 40px auto;} article {width: 800px; margin: 40px auto;}
+22 -17
View File
@@ -374,7 +374,7 @@ def testCoreToHtml_Complex(dummyGUI, fncDir):
for i in range(len(docText)): for i in range(len(docText)):
theHtml.theText = docText[i] theHtml.theText = docText[i]
theHtml.doAutoReplace() theHtml.doPreProcessing()
theHtml.tokenizeText() theHtml.tokenizeText()
theHtml.doConvert() theHtml.doConvert()
assert theHtml.theResult == resText[i] assert theHtml.theResult == resText[i]
@@ -424,27 +424,32 @@ def testCoreToHtml_Methods(dummyGUI):
theHtml = ToHtml(theProject, dummyGUI) theHtml = ToHtml(theProject, dummyGUI)
theHtml.setKeepMarkdown(True) theHtml.setKeepMarkdown(True)
# Auto-Replace # Auto-Replace, keep Unicode
docText = "Text with <brackets> & shortdash, long—dash …\n" docText = "Text with <brackets> & shortdash, long—dash …\n"
theHtml.theText = docText theHtml.theText = docText
theHtml.doAutoReplace() theHtml.setReplaceUnicode(False)
theHtml.doPreProcessing()
theHtml.tokenizeText()
theHtml.doConvert()
assert theHtml.theResult == (
"<p>Text with &lt;brackets&gt; &amp; shortdash, long—dash …</p>\n"
)
# Auto-Replace, replace Unicode
docText = "Text with <brackets> & shortdash, long—dash …\n"
theHtml.theText = docText
theHtml.setReplaceUnicode(True)
theHtml.doPreProcessing()
theHtml.tokenizeText() theHtml.tokenizeText()
theHtml.doConvert() theHtml.doConvert()
assert theHtml.theResult == ( assert theHtml.theResult == (
"<p>Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;</p>\n" "<p>Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;</p>\n"
) )
# Revert on MD # With Preview
assert theHtml.theMarkdown[-1] == (
"Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;\n\n"
)
theHtml.doPostProcessing()
assert theHtml.theMarkdown[-1] == docText + "\n"
# With Preview, No Revert
theHtml.setPreview(True, True) theHtml.setPreview(True, True)
theHtml.theText = docText theHtml.theText = docText
theHtml.doAutoReplace() theHtml.doPreProcessing()
theHtml.tokenizeText() theHtml.tokenizeText()
theHtml.doConvert() theHtml.doConvert()
assert theHtml.theMarkdown[-1] == ( assert theHtml.theMarkdown[-1] == (
@@ -456,18 +461,18 @@ def testCoreToHtml_Methods(dummyGUI):
) )
# Result Size # Result Size
assert theHtml.getFullResultSize() == 83 assert theHtml.getFullResultSize() == 147
# CSS # CSS
# === # ===
assert len(theHtml.getStyleSheet()) > 1 assert len(theHtml.getStyleSheet()) > 1
assert "p {text-align: left;}" in theHtml.getStyleSheet() assert "p {text-align: left;" in " ".join(theHtml.getStyleSheet())
assert "p {text-align: justify;}" not in theHtml.getStyleSheet() assert "p {text-align: justify;" not in " ".join(theHtml.getStyleSheet())
theHtml.setJustify(True) theHtml.setJustify(True)
assert "p {text-align: left;}" not in theHtml.getStyleSheet() assert "p {text-align: left;" not in " ".join(theHtml.getStyleSheet())
assert "p {text-align: justify;}" in theHtml.getStyleSheet() assert "p {text-align: justify;" in " ".join(theHtml.getStyleSheet())
theHtml.setStyles(False) theHtml.setStyles(False)
assert theHtml.getStyleSheet() == [] assert theHtml.getStyleSheet() == []
+2 -2
View File
@@ -176,8 +176,8 @@ def testCoreToken_TextOps(monkeypatch, nwMinimal, dummyGUI):
assert theToken.isNote is False assert theToken.isNote is False
assert theToken.isNovel is True assert theToken.isNovel is True
# Auto replace # Pre Processing
theToken.doAutoReplace() theToken.doPreProcessing()
assert theToken.theText == docTextR assert theToken.theText == docTextR
# Post Processing # Post Processing
+2
View File
@@ -110,6 +110,8 @@ def testGuiBuild_Tool(qtbot, monkeypatch, nwGUI, nwLipsum, refDir, outDir):
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.includeKeywords, Qt.LeftButton) qtbot.mouseClick(nwBuild.includeKeywords, Qt.LeftButton)
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.replaceUCode, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.noteFiles, Qt.LeftButton) qtbot.mouseClick(nwBuild.noteFiles, Qt.LeftButton)
qtbot.wait(stepDelay) qtbot.wait(stepDelay)