From 78a58617c1340618eb3d2e9ba8d97e223560e100 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 10:38:22 +0100
Subject: [PATCH 1/7] Connect line height to Build dialog
---
nw/core/options.py | 1 +
nw/gui/build.py | 141 +++++++++++++++++++++++++--------------------
2 files changed, 79 insertions(+), 63 deletions(-)
diff --git a/nw/core/options.py b/nw/core/options.py
index c7849bb0..c47973e8 100644
--- a/nw/core/options.py
+++ b/nw/core/options.py
@@ -73,6 +73,7 @@ class OptionState():
"excludeBody",
"textFont",
"textSize",
+ "lineHeight",
"noStyling",
"incSynopsis",
"incComments",
diff --git a/nw/gui/build.py b/nw/gui/build.py
index a252fc9d..14ffa0d1 100644
--- a/nw/gui/build.py
+++ b/nw/gui/build.py
@@ -41,7 +41,7 @@ from PyQt5.QtWidgets import (
qApp, QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel,
QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction,
QFileDialog, QFontDialog, QSpinBox, QScrollArea, QSplitter, QWidget,
- QSizePolicy
+ QSizePolicy, QDoubleSpinBox
)
from nw.common import fuzzyTime, makeFileNameSafe
@@ -164,23 +164,29 @@ class GuiBuildNovel(QDialog):
self.boxTitle.addWidget(self.fmtTitle)
self.boxChapter = QHBoxLayout()
self.boxChapter.addWidget(self.fmtChapter)
- self.boxUnnumbered = QHBoxLayout()
- self.boxUnnumbered.addWidget(self.fmtUnnumbered)
+ self.boxUnnumb = QHBoxLayout()
+ self.boxUnnumb.addWidget(self.fmtUnnumbered)
self.boxScene = QHBoxLayout()
self.boxScene.addWidget(self.fmtScene)
self.boxSection = QHBoxLayout()
self.boxSection.addWidget(self.fmtSection)
- self.titleForm.addWidget(QLabel("Title"), 0, 0, 1, 1, Qt.AlignLeft)
- self.titleForm.addLayout(self.boxTitle, 0, 1, 1, 1, Qt.AlignRight)
- self.titleForm.addWidget(QLabel("Chapter"), 1, 0, 1, 1, Qt.AlignLeft)
- self.titleForm.addLayout(self.boxChapter, 1, 1, 1, 1, Qt.AlignRight)
- self.titleForm.addWidget(QLabel("Unnumbered"), 2, 0, 1, 1, Qt.AlignLeft)
- self.titleForm.addLayout(self.boxUnnumbered, 2, 1, 1, 1, Qt.AlignRight)
- self.titleForm.addWidget(QLabel("Scene"), 3, 0, 1, 1, Qt.AlignLeft)
- self.titleForm.addLayout(self.boxScene, 3, 1, 1, 1, Qt.AlignRight)
- self.titleForm.addWidget(QLabel("Section"), 4, 0, 1, 1, Qt.AlignLeft)
- self.titleForm.addLayout(self.boxSection, 4, 1, 1, 1, Qt.AlignRight)
+ titleLabel = QLabel("Title")
+ chapterLabel = QLabel("Chapter")
+ unnumbLabel = QLabel("Unnumbered")
+ sceneLabel = QLabel("Scene")
+ sectionLabel = QLabel("Section")
+
+ self.titleForm.addWidget(titleLabel, 0, 0, 1, 1, Qt.AlignLeft)
+ self.titleForm.addLayout(self.boxTitle, 0, 1, 1, 1, Qt.AlignRight)
+ self.titleForm.addWidget(chapterLabel, 1, 0, 1, 1, Qt.AlignLeft)
+ 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(1, 1)
@@ -204,29 +210,30 @@ class GuiBuildNovel(QDialog):
self.fontButton.clicked.connect(self._selectFont)
self.textSize = QSpinBox(self)
- self.textSize.setFixedWidth(5*self.theTheme.textNWidth)
+ self.textSize.setFixedWidth(6*self.theTheme.textNWidth)
self.textSize.setMinimum(6)
self.textSize.setMaximum(72)
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.optState.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize)
)
- self.justifyText = QSwitch()
- self.justifyText.setToolTip(
- "Applies to PDF, printing, HTML, and Open Document exports."
+ self.lineHeight = QDoubleSpinBox(self)
+ self.lineHeight.setFixedWidth(6*self.theTheme.textNWidth)
+ self.lineHeight.setMinimum(0.8)
+ self.lineHeight.setMaximum(3.0)
+ self.lineHeight.setSingleStep(0.05)
+ self.lineHeight.setDecimals(2)
+ self.lineHeight.setValue(
+ self.optState.getInt("GuiBuildNovel", "lineHeight", 1.15)
)
+
+ self.justifyText = QSwitch()
self.justifyText.setChecked(
self.optState.getBool("GuiBuildNovel", "justifyText", False)
)
self.noStyling = QSwitch()
- self.noStyling.setToolTip(
- "Disable all styling of the text."
- )
self.noStyling.setChecked(
self.optState.getBool("GuiBuildNovel", "noStyling", False)
)
@@ -235,15 +242,23 @@ class GuiBuildNovel(QDialog):
self.boxFont = QHBoxLayout()
self.boxFont.addWidget(self.textFont)
- self.formatForm.addWidget(QLabel("Font family"), 0, 0, 1, 1, Qt.AlignLeft)
- self.formatForm.addLayout(self.boxFont, 0, 1, 1, 1, Qt.AlignRight)
- self.formatForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight)
- self.formatForm.addWidget(QLabel("Font size"), 1, 0, 1, 1, Qt.AlignLeft)
- self.formatForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight)
- 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)
+ fontFamilyLabel = QLabel("Font family")
+ fontSizeLabel = QLabel("Font size")
+ lineHeightLabel = QLabel("Line height")
+ justifyLabel = QLabel("Justify text")
+ stylingLabel = QLabel("Disable styling")
+
+ self.formatForm.addWidget(fontFamilyLabel, 0, 0, 1, 1, Qt.AlignLeft)
+ self.formatForm.addLayout(self.boxFont, 0, 1, 1, 1, Qt.AlignRight)
+ self.formatForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight)
+ self.formatForm.addWidget(fontSizeLabel, 1, 0, 1, 1, Qt.AlignLeft)
+ self.formatForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight)
+ self.formatForm.addWidget(lineHeightLabel, 2, 0, 1, 1, Qt.AlignLeft)
+ self.formatForm.addWidget(self.lineHeight, 2, 1, 1, 2, Qt.AlignRight)
+ self.formatForm.addWidget(justifyLabel, 3, 0, 1, 1, Qt.AlignLeft)
+ self.formatForm.addWidget(self.justifyText, 3, 1, 1, 2, Qt.AlignRight)
+ self.formatForm.addWidget(stylingLabel, 4, 0, 1, 1, Qt.AlignLeft)
+ self.formatForm.addWidget(self.noStyling, 4, 1, 1, 2, Qt.AlignRight)
self.formatForm.setColumnStretch(0, 0)
self.formatForm.setColumnStretch(1, 1)
@@ -257,45 +272,38 @@ class GuiBuildNovel(QDialog):
self.textGroup.setLayout(self.textForm)
self.includeSynopsis = QSwitch()
- self.includeSynopsis.setToolTip(
- "Include synopsis comments in the output."
- )
self.includeSynopsis.setChecked(
self.optState.getBool("GuiBuildNovel", "incSynopsis", False)
)
self.includeComments = QSwitch()
- self.includeComments.setToolTip(
- "Include plain comments in the output."
- )
self.includeComments.setChecked(
self.optState.getBool("GuiBuildNovel", "incComments", False)
)
self.includeKeywords = QSwitch()
- self.includeKeywords.setToolTip(
- "Include meta keywords (tags, references) in the output."
- )
self.includeKeywords.setChecked(
self.optState.getBool("GuiBuildNovel", "incKeywords", False)
)
self.includeBody = QSwitch()
- self.includeBody.setToolTip(
- "Include body text in the output."
- )
self.includeBody.setChecked(
self.optState.getBool("GuiBuildNovel", "incBodyText", True)
)
- self.textForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft)
- self.textForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight)
- self.textForm.addWidget(QLabel("Include comments"), 1, 0, 1, 1, Qt.AlignLeft)
- self.textForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight)
- 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(QLabel("Include body text"), 3, 0, 1, 1, Qt.AlignLeft)
- self.textForm.addWidget(self.includeBody, 3, 1, 1, 1, Qt.AlignRight)
+ synopsisLabel = QLabel("Include synopsis")
+ commentsLabel = QLabel("Include comments")
+ keywordsLabel = QLabel("Include keywords")
+ bodyLabel = QLabel("Include body text")
+
+ self.textForm.addWidget(synopsisLabel, 0, 0, 1, 1, Qt.AlignLeft)
+ self.textForm.addWidget(self.includeSynopsis, 0, 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(1, 0)
@@ -331,12 +339,16 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "ignoreFlag", False)
)
- self.fileForm.addWidget(QLabel("Include novel files"), 0, 0, 1, 1, Qt.AlignLeft)
- self.fileForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight)
- self.fileForm.addWidget(QLabel("Include note files"), 1, 0, 1, 1, Qt.AlignLeft)
- 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(self.ignoreFlag, 2, 1, 1, 1, Qt.AlignRight)
+ novelLabel = QLabel("Include novel files")
+ notesLabel = QLabel("Include note files")
+ exportLabel = QLabel("Ignore export flag")
+
+ self.fileForm.addWidget(novelLabel, 0, 0, 1, 1, Qt.AlignLeft)
+ 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(1, 0)
@@ -349,15 +361,14 @@ class GuiBuildNovel(QDialog):
self.exportGroup.setLayout(self.exportForm)
self.replaceTabs = QSwitch()
- self.replaceTabs.setToolTip(
- "Replace all tabs with eight spaces."
- )
self.replaceTabs.setChecked(
self.optState.getBool("GuiBuildNovel", "replaceTabs", False)
)
- self.exportForm.addWidget(QLabel("Replace tabs with spaces"), 0, 0, 1, 1, Qt.AlignLeft)
- self.exportForm.addWidget(self.replaceTabs, 0, 1, 1, 1, Qt.AlignRight)
+ tabsLabel = QLabel("Replace tabs with spaces")
+
+ self.exportForm.addWidget(tabsLabel, 0, 0, 1, 1, Qt.AlignLeft)
+ self.exportForm.addWidget(self.replaceTabs, 0, 1, 1, 1, Qt.AlignRight)
self.exportForm.setColumnStretch(0, 1)
self.exportForm.setColumnStretch(1, 0)
@@ -607,6 +618,7 @@ class GuiBuildNovel(QDialog):
fmtSection = self.fmtSection.text().strip()
textFont = self.textFont.text()
textSize = self.textSize.value()
+ lineHeight = self.lineHeight.value()
justifyText = self.justifyText.isChecked()
noStyling = self.noStyling.isChecked()
incSynopsis = self.includeSynopsis.isChecked()
@@ -632,6 +644,7 @@ class GuiBuildNovel(QDialog):
bldObj.setFont(textFont, textSize, textFixed)
bldObj.setJustify(justifyText)
+ bldObj.setLineHeight(lineHeight)
bldObj.setSynopsis(incSynopsis)
bldObj.setComments(incComments)
@@ -1085,6 +1098,7 @@ class GuiBuildNovel(QDialog):
noStyling = self.noStyling.isChecked()
textFont = self.textFont.text()
textSize = self.textSize.value()
+ lineHeight = self.lineHeight.value()
novelFiles = self.novelFiles.isChecked()
noteFiles = self.noteFiles.isChecked()
ignoreFlag = self.ignoreFlag.isChecked()
@@ -1111,6 +1125,7 @@ class GuiBuildNovel(QDialog):
self.optState.setValue("GuiBuildNovel", "noStyling", noStyling)
self.optState.setValue("GuiBuildNovel", "textFont", textFont)
self.optState.setValue("GuiBuildNovel", "textSize", textSize)
+ self.optState.setValue("GuiBuildNovel", "lineHeight", lineHeight)
self.optState.setValue("GuiBuildNovel", "addNovel", novelFiles)
self.optState.setValue("GuiBuildNovel", "addNotes", noteFiles)
self.optState.setValue("GuiBuildNovel", "ignoreFlag", ignoreFlag)
From 7ea45ac3d208ac7a9af430033e948d54046feb2d Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 10:39:25 +0100
Subject: [PATCH 2/7] Cleanup Build dialog and add line height to HTML
---
nw/core/tohtml.py | 10 +++--
nw/core/toodt.py | 34 ++++++++--------
nw/gui/build.py | 99 +++++++++++++++++++++++++++--------------------
3 files changed, 81 insertions(+), 62 deletions(-)
diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py
index 3aa6f5fc..2434b55c 100644
--- a/nw/core/tohtml.py
+++ b/nw/core/tohtml.py
@@ -333,10 +333,12 @@ class ToHtml(Tokenizer):
textAlign = "justify" if self.doJustify else "left"
- theStyles.append("body {font-family: '%s'; font-size: %dpt}" % (
- self.textFont, self.textSize)
- )
- theStyles.append("p {text-align: %s;}" % textAlign)
+ theStyles.append("body {font-family: '%s'; font-size: %dpt;}" % (
+ self.textFont, self.textSize
+ ))
+ theStyles.append("p {text-align: %s; line-height: %d%%;}" % (
+ textAlign, round(100 * self.lineHeight)
+ ))
theStyles.append("h1, h2 {color: rgb(66, 113, 174);}")
theStyles.append("h3, h4 {color: rgb(50, 50, 50);}")
theStyles.append("h1, h2, h3, h4 {page-break-after: avoid;}")
diff --git a/nw/core/toodt.py b/nw/core/toodt.py
index ee83673c..b9cffc3c 100644
--- a/nw/core/toodt.py
+++ b/nw/core/toodt.py
@@ -194,23 +194,25 @@ class ToOdt(Tokenizer):
self._fSizeHead = f"{round(1.15 * self.textSize):d}pt"
self._fSizeText = f"{self.textSize:d}pt"
- self._mTopTitle = self._emToCm(self.marginTitle[0])
- 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])
+ mScale = self.lineHeight/1.15
- self._mBotTitle = self._emToCm(self.marginTitle[1])
- self._mBotHead1 = self._emToCm(self.marginHead1[1])
- self._mBotHead2 = self._emToCm(self.marginHead2[1])
- self._mBotHead3 = self._emToCm(self.marginHead3[1])
- self._mBotHead4 = self._emToCm(self.marginHead4[1])
- self._mBotHead = self._emToCm(self.marginHead4[1])
- self._mBotText = self._emToCm(self.marginText[1])
- self._mBotMeta = self._emToCm(self.marginMeta[1])
+ self._mTopTitle = self._emToCm(mScale * self.marginTitle[0])
+ self._mTopHead1 = self._emToCm(mScale * self.marginHead1[0])
+ self._mTopHead2 = self._emToCm(mScale * self.marginHead2[0])
+ self._mTopHead3 = self._emToCm(mScale * self.marginHead3[0])
+ self._mTopHead4 = self._emToCm(mScale * self.marginHead4[0])
+ self._mTopHead = self._emToCm(mScale * self.marginHead4[0])
+ self._mTopText = self._emToCm(mScale * self.marginText[0])
+ 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:
self._colHead12 = "#2a6099"
diff --git a/nw/gui/build.py b/nw/gui/build.py
index 14ffa0d1..38fbd727 100644
--- a/nw/gui/build.py
+++ b/nw/gui/build.py
@@ -93,6 +93,9 @@ class GuiBuildNovel(QDialog):
self.docView = GuiBuildNovelDocView(self, self.theProject)
+ hS = self.theTheme.fontPixelSize
+ wS = 2*hS
+
# Title Formats
# =============
@@ -191,12 +194,12 @@ class GuiBuildNovel(QDialog):
self.titleForm.setColumnStretch(0, 0)
self.titleForm.setColumnStretch(1, 1)
- # Text Options
- # =============
+ # Font Options
+ # ============
- self.formatGroup = QGroupBox("Formatting Options", self)
- self.formatForm = QGridLayout(self)
- self.formatGroup.setLayout(self.formatForm)
+ self.fontGroup = QGroupBox("Font Options", self)
+ self.fontForm = QGridLayout(self)
+ self.fontGroup.setLayout(self.fontForm)
## Font Family
self.textFont = QLineEdit()
@@ -225,17 +228,7 @@ class GuiBuildNovel(QDialog):
self.lineHeight.setSingleStep(0.05)
self.lineHeight.setDecimals(2)
self.lineHeight.setValue(
- self.optState.getInt("GuiBuildNovel", "lineHeight", 1.15)
- )
-
- self.justifyText = QSwitch()
- self.justifyText.setChecked(
- self.optState.getBool("GuiBuildNovel", "justifyText", False)
- )
-
- self.noStyling = QSwitch()
- self.noStyling.setChecked(
- self.optState.getBool("GuiBuildNovel", "noStyling", False)
+ self.optState.getFloat("GuiBuildNovel", "lineHeight", 1.15)
)
# Dummy box due to QGridView and QLineEdit expand bug
@@ -248,45 +241,66 @@ class GuiBuildNovel(QDialog):
justifyLabel = QLabel("Justify text")
stylingLabel = QLabel("Disable styling")
- self.formatForm.addWidget(fontFamilyLabel, 0, 0, 1, 1, Qt.AlignLeft)
- self.formatForm.addLayout(self.boxFont, 0, 1, 1, 1, Qt.AlignRight)
- self.formatForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight)
- self.formatForm.addWidget(fontSizeLabel, 1, 0, 1, 1, Qt.AlignLeft)
- self.formatForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight)
- self.formatForm.addWidget(lineHeightLabel, 2, 0, 1, 1, Qt.AlignLeft)
- self.formatForm.addWidget(self.lineHeight, 2, 1, 1, 2, Qt.AlignRight)
- self.formatForm.addWidget(justifyLabel, 3, 0, 1, 1, Qt.AlignLeft)
- self.formatForm.addWidget(self.justifyText, 3, 1, 1, 2, Qt.AlignRight)
- self.formatForm.addWidget(stylingLabel, 4, 0, 1, 1, Qt.AlignLeft)
- self.formatForm.addWidget(self.noStyling, 4, 1, 1, 2, Qt.AlignRight)
+ self.fontForm.addWidget(fontFamilyLabel, 0, 0, 1, 1, Qt.AlignLeft)
+ self.fontForm.addLayout(self.boxFont, 0, 1, 1, 1, Qt.AlignRight)
+ 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)
- self.formatForm.setColumnStretch(0, 0)
- self.formatForm.setColumnStretch(1, 1)
- self.formatForm.setColumnStretch(2, 0)
+ self.fontForm.setColumnStretch(0, 0)
+ self.fontForm.setColumnStretch(1, 1)
+ self.fontForm.setColumnStretch(2, 0)
- # Include Switches
- # ================
+ # Styling Options
+ # ===============
- self.textGroup = QGroupBox("Text Options", self)
+ 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.textGroup.setLayout(self.textForm)
- self.includeSynopsis = QSwitch()
+ self.includeSynopsis = QSwitch(width=wS, height=hS)
self.includeSynopsis.setChecked(
self.optState.getBool("GuiBuildNovel", "incSynopsis", False)
)
- self.includeComments = QSwitch()
+ self.includeComments = QSwitch(width=wS, height=hS)
self.includeComments.setChecked(
self.optState.getBool("GuiBuildNovel", "incComments", False)
)
- self.includeKeywords = QSwitch()
+ self.includeKeywords = QSwitch(width=wS, height=hS)
self.includeKeywords.setChecked(
self.optState.getBool("GuiBuildNovel", "incKeywords", False)
)
- self.includeBody = QSwitch()
+ self.includeBody = QSwitch(width=wS, height=hS)
self.includeBody.setChecked(
self.optState.getBool("GuiBuildNovel", "incBodyText", True)
)
@@ -315,7 +329,7 @@ class GuiBuildNovel(QDialog):
self.fileForm = QGridLayout(self)
self.fileGroup.setLayout(self.fileForm)
- self.novelFiles = QSwitch()
+ self.novelFiles = QSwitch(width=wS, height=hS)
self.novelFiles.setToolTip(
"Include files with layouts 'Book', 'Page', 'Partition', "
"'Chapter', 'Unnumbered', and 'Scene'."
@@ -324,13 +338,13 @@ class GuiBuildNovel(QDialog):
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.setChecked(
self.optState.getBool("GuiBuildNovel", "addNotes", False)
)
- self.ignoreFlag = QSwitch()
+ self.ignoreFlag = QSwitch(width=wS, height=hS)
self.ignoreFlag.setToolTip(
"Ignore the 'Include when building project' setting and include "
"all files in the output."
@@ -360,7 +374,7 @@ class GuiBuildNovel(QDialog):
self.exportForm = QGridLayout(self)
self.exportGroup.setLayout(self.exportForm)
- self.replaceTabs = QSwitch()
+ self.replaceTabs = QSwitch(width=wS, height=hS)
self.replaceTabs.setChecked(
self.optState.getBool("GuiBuildNovel", "replaceTabs", False)
)
@@ -458,7 +472,8 @@ class GuiBuildNovel(QDialog):
# The Tool Box
self.toolsBox = QVBoxLayout()
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.fileGroup)
self.toolsBox.addWidget(self.exportGroup)
From a0fba34ff6da0135c517d9536b642b648e3c1dab Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 16:55:46 +0100
Subject: [PATCH 3/7] Apply line height and margins to HTML output
---
nw/core/tohtml.py | 77 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 69 insertions(+), 8 deletions(-)
diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py
index 2434b55c..1198ea1b 100644
--- a/nw/core/tohtml.py
+++ b/nw/core/tohtml.py
@@ -331,23 +331,84 @@ class ToHtml(Tokenizer):
if not self.cssStyles:
return theStyles
+ mScale = self.lineHeight/1.15
textAlign = "justify" if self.doJustify else "left"
theStyles.append("body {font-family: '%s'; font-size: %dpt;}" % (
self.textFont, self.textSize
))
- theStyles.append("p {text-align: %s; line-height: %d%%;}" % (
- textAlign, round(100 * self.lineHeight)
+ theStyles.append((
+ "p {"
+ "text-align: %s; line-height: %d%%; "
+ "margin-top: %.2fem; margin-bottom: %.2fem;"
+ "}"
+ ) % (
+ textAlign,
+ round(100 * self.lineHeight),
+ mScale * self.marginText[0],
+ mScale * self.marginText[1],
))
- theStyles.append("h1, h2 {color: rgb(66, 113, 174);}")
- theStyles.append("h3, h4 {color: rgb(50, 50, 50);}")
- theStyles.append("h1, h2, h3, h4 {page-break-after: avoid;}")
+ 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(".title {font-size: 2.5em;}")
theStyles.append(".tags {color: rgb(245, 135, 31); font-weight: bold;}")
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(".comment {font-style: italic; color: rgb(100, 100, 100);}")
From f67a50c064d9db68b996a9fec93f907014955a9d Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Wed, 10 Feb 2021 16:56:52 +0100
Subject: [PATCH 4/7] Change the way Unicode is handled in HTML, and clean up
the class a bit
---
nw/constants/__init__.py | 4 +-
nw/constants/constants.py | 61 ++++++++++++++++++++++++++++-
nw/core/tohtml.py | 80 +++++++++++++--------------------------
nw/core/tokenizer.py | 13 +++++--
nw/gui/docviewer.py | 2 +-
5 files changed, 98 insertions(+), 62 deletions(-)
diff --git a/nw/constants/__init__.py b/nw/constants/__init__.py
index b58b56c3..1a6748a1 100644
--- a/nw/constants/__init__.py
+++ b/nw/constants/__init__.py
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from nw.constants.iso import isoLanguage, isoCountry
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 (
nwAlert, nwDocAction, nwItemClass, nwItemLayout, nwItemType, nwOutline,
@@ -19,6 +20,7 @@ __all__ = [
"nwLabels",
"nwQuotes",
"nwUnicode",
+ "nwHtmlUnicode",
"nwAlert",
"nwDocAction",
"nwItemClass",
diff --git a/nw/constants/constants.py b/nw/constants/constants.py
index 5e4581b9..0909b1f2 100644
--- a/nw/constants/constants.py
+++ b/nw/constants/constants.py
@@ -265,7 +265,7 @@ class nwUnicode:
U_LCQUO = "\u300c" # Left corner bracket
U_RCQUO = "\u300d" # Right corner bracket
U_LWCQUO = "\u300e" # Left white corner bracket
- U_RECQUO = "\u300f" # Right white corner bracket
+ U_RWCQUO = "\u300f" # Right white corner bracket
## Punctuation
U_FGDASH = "\u2012" # Figure dash
@@ -331,7 +331,7 @@ class nwUnicode:
H_LCQUO = "「"
H_RCQUO = "」"
H_LWCQUO = "『"
- H_LWCQUO = "『"
+ H_RWCQUO = "』"
## Punctuation
H_FGDASH = "‒"
@@ -374,3 +374,60 @@ class nwUnicode:
H_LTRIS = "◂"
# 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
diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py
index 1198ea1b..67ebcc0f 100644
--- a/nw/core/tohtml.py
+++ b/nw/core/tohtml.py
@@ -25,10 +25,9 @@ along with this program. If not, see