Merge branch 'main' into feature/preview_generator

This commit is contained in:
Veronica Berglyd Olsen
2024-05-23 18:50:38 +02:00
36 changed files with 317 additions and 262 deletions
@@ -59,6 +59,7 @@ fmt_strike-md = nw_tb-strike-md.svg
fmt_subscript = nw_tb-subscript.svg
fmt_superscript = nw_tb-superscript.svg
fmt_underline = nw_tb-underline.svg
font = nw_font.svg
forward = typ_chevron-right.svg
import = mixed_import.svg
list = typ_th-list.svg
@@ -78,6 +79,7 @@ proj_scene = mixed_document-scene.svg
proj_section = mixed_document-section.svg
proj_stats = typ_chart-bar-grey.svg
proj_title = mixed_document-title.svg
quote = nw_quote.svg
refresh = typ_refresh.svg
remove = typ_minus.svg
revert = typ_refresh-flipped.svg
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<path d="m2.5744 5.8208v-4.2853h-1.4527v-1.0064h4.1067v1.0064h-1.4527v4.2853z" fill="#aeaeae" stroke-width="1.1503"/>
</svg>

After

Width:  |  Height:  |  Size: 267 B

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<path d="m1.3715 3.0659q-0.32092-0.25674-0.44928-0.44928-0.12836-0.19255-0.12837-0.44928 0-0.42361 0.28241-0.69319 0.28241-0.28241 0.68035-0.28241 0.25674 0 0.44928 0.10269 0.19255 0.089858 0.3466 0.23106 0.24391 0.4878 0.24391 1.0141 0 0.42361-0.14121 0.82157-0.12837 0.38511-0.37227 0.71886-0.23106 0.33377-0.55199 0.61618-0.30808 0.26958-0.65467 0.46213l-0.25674-0.41078q0.29525-0.21822 0.57766-0.53914 0.28241-0.33375 0.46213-0.73171zm2.7598 0q-0.32092-0.25674-0.44928-0.44928-0.12837-0.19255-0.12837-0.44928 0-0.42361 0.28241-0.69319 0.28241-0.28241 0.68035-0.28241 0.25674 0 0.44928 0.10269 0.19255 0.089858 0.3466 0.23106 0.24391 0.4878 0.24391 1.0141 0 0.42361-0.14121 0.82157-0.12837 0.38511-0.37227 0.71886-0.23106 0.33377-0.55199 0.61618-0.30808 0.26958-0.65467 0.46213l-0.25674-0.41078q0.29525-0.21822 0.57766-0.53914 0.28241-0.33375 0.46213-0.73171z" fill="#aeaeae" fill-opacity=".78039" stroke-width="1.8194"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -59,6 +59,7 @@ fmt_strike-md = nw_tb-strike-md.svg
fmt_subscript = nw_tb-subscript.svg
fmt_superscript = nw_tb-superscript.svg
fmt_underline = nw_tb-underline.svg
font = nw_font.svg
forward = typ_chevron-right.svg
import = mixed_import.svg
list = typ_th-list.svg
@@ -78,6 +79,7 @@ proj_scene = mixed_document-scene.svg
proj_section = mixed_document-section.svg
proj_stats = typ_chart-bar-grey.svg
proj_title = mixed_document-title.svg
quote = nw_quote.svg
refresh = typ_refresh.svg
remove = typ_minus.svg
revert = typ_refresh-flipped.svg
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<path d="m2.5744 5.8208v-4.2853h-1.4527v-1.0064h4.1067v1.0064h-1.4527v4.2853z" fill-opacity=".78039" stroke-width="1.1503"/>
</svg>

After

Width:  |  Height:  |  Size: 274 B

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<path d="m1.3715 3.0659q-0.32092-0.25674-0.44928-0.44928-0.12836-0.19255-0.12837-0.44928 0-0.42361 0.28241-0.69319 0.28241-0.28241 0.68035-0.28241 0.25674 0 0.44928 0.10269 0.19255 0.089858 0.3466 0.23106 0.24391 0.4878 0.24391 1.0141 0 0.42361-0.14121 0.82157-0.12837 0.38511-0.37227 0.71886-0.23106 0.33377-0.55199 0.61618-0.30808 0.26958-0.65467 0.46213l-0.25674-0.41078q0.29525-0.21822 0.57766-0.53914 0.28241-0.33375 0.46213-0.73171zm2.7598 0q-0.32092-0.25674-0.44928-0.44928-0.12837-0.19255-0.12837-0.44928 0-0.42361 0.28241-0.69319 0.28241-0.28241 0.68035-0.28241 0.25674 0 0.44928 0.10269 0.19255 0.089858 0.3466 0.23106 0.24391 0.4878 0.24391 1.0141 0 0.42361-0.14121 0.82157-0.12837 0.38511-0.37227 0.71886-0.23106 0.33377-0.55199 0.61618-0.30808 0.26958-0.65467 0.46213l-0.25674-0.41078q0.29525-0.21822 0.57766-0.53914 0.28241-0.33375 0.46213-0.73171z" fill-opacity=".78039" stroke-width="1.8194"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+3 -1
View File
@@ -405,7 +405,9 @@ def describeFont(font: QFont) -> str:
"""Describe a font in a way that can be displayed on the GUI."""
if isinstance(font, QFont):
info = QFontInfo(font)
return f"{font.family()} {info.styleName()} @ {font.pointSize()} pt"
family = info.family()
styles = [v for v in info.styleName().split() if v not in family]
return " ".join([f"{info.pointSize()} pt", family] + styles)
return "Error"
+3
View File
@@ -114,6 +114,7 @@ class Config:
self.hideVScroll = False # Hide vertical scroll bars on main widgets
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
self.lastNotes = "0x0" # The latest release notes that have been shown
self.nativeFont = True # Use native font dialog
# Size Settings
self._mainWinSize = [1200, 650] # Last size of the main GUI window
@@ -598,6 +599,7 @@ class Config:
self.hideVScroll = conf.rdBool(sec, "hidevscroll", self.hideVScroll)
self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll)
self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes)
self.nativeFont = conf.rdBool(sec, "nativefont", self.nativeFont)
self._lastPath = conf.rdPath(sec, "lastpath", self._lastPath)
# Sizes
@@ -707,6 +709,7 @@ class Config:
"hidevscroll": str(self.hideVScroll),
"hidehscroll": str(self.hideHScroll),
"lastnotes": str(self.lastNotes),
"nativefont": str(self.nativeFont),
"lastpath": str(self._lastPath),
}
+4 -8
View File
@@ -76,12 +76,12 @@ SETTINGS_TEMPLATE = {
"text.includeBodyText": (bool, True),
"text.ignoredKeywords": (str, ""),
"text.addNoteHeadings": (bool, True),
"format.textFont": (str, CONFIG.textFont.family()),
"format.textSize": (int, 12),
"format.textFont": (str, CONFIG.textFont.toString()),
"format.lineHeight": (float, 1.15, 0.75, 3.0),
"format.justifyText": (bool, False),
"format.stripUnicode": (bool, False),
"format.replaceTabs": (bool, False),
"format.keepBreaks": (bool, True),
"format.firstLineIndent": (bool, False),
"format.firstIndentWidth": (float, 1.4),
"format.indentFirstPar": (bool, False),
@@ -96,7 +96,6 @@ SETTINGS_TEMPLATE = {
"odt.addColours": (bool, True),
"odt.pageHeader": (str, nwHeadFmt.ODT_AUTO),
"odt.pageCountOffset": (int, 0),
"md.preserveBreaks": (bool, True),
"html.addStyles": (bool, True),
"html.preserveTabs": (bool, False),
}
@@ -125,13 +124,13 @@ SETTINGS_LABELS = {
"text.addNoteHeadings": QT_TRANSLATE_NOOP("Builds", "Add Titles for Notes"),
"format.grpFormat": QT_TRANSLATE_NOOP("Builds", "Text Format"),
"format.textFont": QT_TRANSLATE_NOOP("Builds", "Font Family"),
"format.textSize": QT_TRANSLATE_NOOP("Builds", "Font Size"),
"format.textFont": QT_TRANSLATE_NOOP("Builds", "Text Font"),
"format.lineHeight": QT_TRANSLATE_NOOP("Builds", "Line Height"),
"format.grpOptions": QT_TRANSLATE_NOOP("Builds", "Text Options"),
"format.justifyText": QT_TRANSLATE_NOOP("Builds", "Justify Text Margins"),
"format.stripUnicode": QT_TRANSLATE_NOOP("Builds", "Replace Unicode Characters"),
"format.replaceTabs": QT_TRANSLATE_NOOP("Builds", "Replace Tabs with Spaces"),
"format.keepBreaks": QT_TRANSLATE_NOOP("Builds", "Preserve Hard Line Breaks"),
"format.grpParIndent": QT_TRANSLATE_NOOP("Builds", "First Line Indent"),
"format.firstLineIndent": QT_TRANSLATE_NOOP("Builds", "Enable Indent"),
@@ -153,9 +152,6 @@ SETTINGS_LABELS = {
"odt.pageHeader": QT_TRANSLATE_NOOP("Builds", "Page Header"),
"odt.pageCountOffset": QT_TRANSLATE_NOOP("Builds", "Page Counter Offset"),
"md": QT_TRANSLATE_NOOP("Builds", "Markdown (.md)"),
"md.preserveBreaks": QT_TRANSLATE_NOOP("Builds", "Preserve Hard Line Breaks"),
"html": QT_TRANSLATE_NOOP("Builds", "HTML (.html)"),
"html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"),
"html.preserveTabs": QT_TRANSLATE_NOOP("Builds", "Preserve Tab Characters"),
+6 -16
View File
@@ -28,7 +28,7 @@ import logging
from collections.abc import Iterable
from pathlib import Path
from PyQt5.QtGui import QFont, QFontInfo
from PyQt5.QtGui import QFont
from novelwriter import CONFIG
from novelwriter.constants import nwLabels
@@ -216,16 +216,10 @@ class NWBuildDocument:
makeObj = ToMarkdown(self._project)
filtered = self._setupBuild(makeObj)
if extendedMd:
makeObj.setExtendedMarkdown()
else:
makeObj.setStandardMarkdown()
makeObj.setExtendedMarkdown(extendedMd)
if self._build.getBool("format.replaceTabs"):
makeObj.replaceTabs(nSpaces=4, spaceChar=" ")
makeObj.setPreserveBreaks(self._build.getBool("md.preserveBreaks"))
for i, tHandle in enumerate(self._queue):
self._error = None
if filtered.get(tHandle, (False, 0))[0]:
@@ -285,13 +279,9 @@ class NWBuildDocument:
def _setupBuild(self, bldObj: Tokenizer) -> dict:
"""Configure the build object."""
# Get Settings
textFont = self._build.getStr("format.textFont")
textSize = self._build.getInt("format.textSize")
fontFamily = textFont or CONFIG.textFont.family()
bldFont = QFont(fontFamily, textSize)
fontInfo = QFontInfo(bldFont)
textFixed = fontInfo.fixedPitch()
textFont = QFont(CONFIG.textFont)
textFont.fromString(self._build.getStr("format.textFont"))
bldObj.setFont(textFont)
bldObj.setTitleFormat(
self._build.getStr("headings.fmtTitle"),
@@ -330,9 +320,9 @@ class NWBuildDocument:
self._build.getBool("headings.breakScene")
)
bldObj.setFont(fontFamily, textSize, textFixed)
bldObj.setJustify(self._build.getBool("format.justifyText"))
bldObj.setLineHeight(self._build.getFloat("format.lineHeight"))
bldObj.setKeepLineBreaks(self._build.getBool("format.keepBreaks"))
bldObj.setFirstLineIndent(
self._build.getBool("format.firstLineIndent"),
self._build.getFloat("format.firstIndentWidth"),
+11 -2
View File
@@ -34,6 +34,7 @@ from novelwriter.common import formatTimeStamp
from novelwriter.constants import nwHeadFmt, nwHtmlUnicode, nwKeyWords, nwLabels
from novelwriter.core.project import NWProject
from novelwriter.core.tokenizer import T_Formats, Tokenizer, stripEscape
from novelwriter.types import FONT_STYLE, FONT_WEIGHTS
logger = logging.getLogger(__name__)
@@ -373,8 +374,16 @@ class ToHtml(Tokenizer):
mScale = self._lineHeight/1.15
styles = []
styles.append("body {{font-family: '{0:s}'; font-size: {1:d}pt;}}".format(
self._textFont, self._textSize
font = self._textFont
styles.append((
"body {{"
"font-family: '{0:s}'; font-size: {1:d}pt; "
"font-weight: {2:d}; font-style: {3:s};"
"}}"
).format(
font.family(), font.pointSize(),
FONT_WEIGHTS.get(font.weight(), 400),
FONT_STYLE.get(font.style(), "normal"),
))
styles.append((
"p {{"
+4 -7
View File
@@ -34,6 +34,7 @@ from pathlib import Path
from time import time
from PyQt5.QtCore import QCoreApplication, QRegularExpression
from PyQt5.QtGui import QFont
from novelwriter.common import checkInt, formatTimeStamp, numberToRoman
from novelwriter.constants import (
@@ -139,9 +140,7 @@ class Tokenizer(ABC):
self._markdown: list[str] = []
# User Settings
self._textFont = "Serif" # Output text font
self._textSize = 11 # Output text size
self._textFixed = False # Fixed width text
self._textFont = QFont("Serif", 11) # Output text font
self._lineHeight = 1.15 # Line height in units of em
self._blockIndent = 4.00 # Block indent in units of em
self._firstIndent = False # Enable first line indent
@@ -315,11 +314,9 @@ class Tokenizer(ABC):
)
return
def setFont(self, family: str, size: int, isFixed: bool = False) -> None:
def setFont(self, font: QFont) -> None:
"""Set the build font."""
self._textFont = family
self._textSize = round(int(size))
self._textFixed = isFixed
self._textFont = font
return
def setLineHeight(self, height: float) -> None:
+8 -22
View File
@@ -81,15 +81,11 @@ class ToMarkdown(Tokenizer):
supports concatenating novelWriter markup files.
"""
M_STD = 0 # Standard Markdown
M_EXT = 1 # Extended Markdown
def __init__(self, project: NWProject) -> None:
super().__init__(project)
self._genMode = self.M_STD
self._fullMD: list[str] = []
self._preserveBreaks = True
self._usedNotes: dict[str, int] = {}
self._extended = True
return
##
@@ -105,19 +101,9 @@ class ToMarkdown(Tokenizer):
# Setters
##
def setStandardMarkdown(self) -> None:
"""Set the converter to use standard Markdown formatting."""
self._genMode = self.M_STD
return
def setExtendedMarkdown(self) -> None:
def setExtendedMarkdown(self, state: bool) -> None:
"""Set the converter to use Extended Markdown formatting."""
self._genMode = self.M_EXT
return
def setPreserveBreaks(self, state: bool) -> None:
"""Preserve line breaks in paragraphs."""
self._preserveBreaks = state
self._extended = state
return
##
@@ -132,12 +118,12 @@ class ToMarkdown(Tokenizer):
"""Convert the list of text tokens into a Markdown document."""
self._result = ""
if self._genMode == self.M_STD:
mTags = STD_MD
cSkip = ""
else:
if self._extended:
mTags = EXT_MD
cSkip = nwUnicode.U_MMSP
else:
mTags = STD_MD
cSkip = ""
lines = []
for tType, _, tText, tFormat, tStyle in self._tokens:
@@ -195,7 +181,7 @@ class ToMarkdown(Tokenizer):
def appendFootnotes(self) -> None:
"""Append the footnotes in the buffer."""
if self._usedNotes:
tags = STD_MD if self._genMode == self.M_STD else EXT_MD
tags = EXT_MD if self._extended else STD_MD
footnotes = self._localLookup("Footnotes")
lines = []
+62 -38
View File
@@ -35,11 +35,14 @@ from hashlib import sha256
from pathlib import Path
from zipfile import ZipFile
from PyQt5.QtGui import QFont
from novelwriter import __version__
from novelwriter.common import xmlIndent
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels
from novelwriter.core.project import NWProject
from novelwriter.core.tokenizer import T_Formats, Tokenizer, stripEscape
from novelwriter.types import FONT_STYLE, FONT_WEIGHTS
logger = logging.getLogger(__name__)
@@ -108,6 +111,10 @@ S_TEXT = "Text_20_body"
S_META = "Text_20_Meta"
S_HNF = "Header_20_and_20_Footer"
# Font Data
FONT_WEIGHT_NUM = ["100", "200", "300", "400", "500", "600", "700", "800", "900"]
FONT_WEIGHT_MAP = {"400": "normal", "700": "bold"}
class ToOdt(Tokenizer):
"""Core: Open Document Writer
@@ -149,16 +156,18 @@ class ToOdt(Tokenizer):
self._errData = [] # List of errors encountered
# Properties
self._textFont = "Liberation Serif"
self._textSize = 12
self._textFixed = False
self._textFont = QFont("Liberation Serif", 12)
self._colourHead = False
self._headerFormat = ""
self._pageOffset = 0
# Internal
self._fontFamily = "&apos;Liberation Serif&apos;"
self._fontFamily = "Liberation Serif"
self._fontSize = 12
self._fontWeight = "normal"
self._fontStyle = "normal"
self._fontPitch = "variable"
self._fontBold = "bold"
self._fSizeTitle = "30pt"
self._fSizeHead1 = "24pt"
self._fSizeHead2 = "20pt"
@@ -260,19 +269,25 @@ class ToOdt(Tokenizer):
# Initialise Variables
# ====================
self._fontFamily = self._textFont
if len(self._textFont.split()) > 1:
self._fontFamily = f"'{self._textFont}'"
self._fontPitch = "fixed" if self._textFixed else "variable"
intWeight = FONT_WEIGHTS.get(self._textFont.weight(), 400)
fontWeight = str(intWeight)
fontBold = str(min(intWeight + 300, 900))
self._fSizeTitle = f"{round(2.50 * self._textSize):d}pt"
self._fSizeHead1 = f"{round(2.00 * self._textSize):d}pt"
self._fSizeHead2 = f"{round(1.60 * self._textSize):d}pt"
self._fSizeHead3 = f"{round(1.30 * self._textSize):d}pt"
self._fSizeHead4 = 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._fSizeFoot = f"{round(0.8*self._textSize):d}pt"
self._fontFamily = self._textFont.family()
self._fontSize = self._textFont.pointSize()
self._fontWeight = FONT_WEIGHT_MAP.get(fontWeight, fontWeight)
self._fontStyle = FONT_STYLE.get(self._textFont.style(), "normal")
self._fontPitch = "fixed" if self._textFont.fixedPitch() else "variable"
self._fontBold = FONT_WEIGHT_MAP.get(fontBold, fontBold)
self._fSizeTitle = f"{round(2.50 * self._fontSize):d}pt"
self._fSizeHead1 = f"{round(2.00 * self._fontSize):d}pt"
self._fSizeHead2 = f"{round(1.60 * self._fontSize):d}pt"
self._fSizeHead3 = f"{round(1.30 * self._fontSize):d}pt"
self._fSizeHead4 = f"{round(1.15 * self._fontSize):d}pt"
self._fSizeHead = f"{round(1.15 * self._fontSize):d}pt"
self._fSizeText = f"{self._fontSize:d}pt"
self._fSizeFoot = f"{round(0.8*self._fontSize):d}pt"
mScale = self._lineHeight/1.15
@@ -320,7 +335,7 @@ class ToOdt(Tokenizer):
tAttr[_mkTag("office", "version")] = X_VERS
fAttr = {}
fAttr[_mkTag("style", "name")] = self._textFont
fAttr[_mkTag("style", "name")] = self._fontFamily
fAttr[_mkTag("style", "font-pitch")] = self._fontPitch
if self._isFlat:
@@ -726,7 +741,7 @@ class ToOdt(Tokenizer):
style = ODTTextStyle(f"T{len(self._autoText)+1:d}")
if hFmt & X_BLD:
style.setFontWeight("bold")
style.setFontWeight(self._fontBold)
if hFmt & X_ITA:
style.setFontStyle("italic")
if hFmt & X_DEL:
@@ -764,7 +779,7 @@ class ToOdt(Tokenizer):
def _emToCm(self, value: float) -> str:
"""Converts an em value to centimetres."""
return f"{value*2.54/72*self._textSize:.3f}cm"
return f"{value*2.54/72*self._fontSize:.3f}cm"
##
# Style Elements
@@ -808,8 +823,10 @@ class ToOdt(Tokenizer):
_mkTag("style", "writing-mode"): "page",
})
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib={
_mkTag("style", "font-name"): self._textFont,
_mkTag("style", "font-name"): self._fontFamily,
_mkTag("fo", "font-family"): self._fontFamily,
_mkTag("fo", "font-weight"): self._fontWeight,
_mkTag("fo", "font-style"): self._fontStyle,
_mkTag("fo", "font-size"): self._fSizeText,
_mkTag("fo", "language"): self._dLanguage,
_mkTag("fo", "country"): self._dCountry,
@@ -822,8 +839,10 @@ class ToOdt(Tokenizer):
_mkTag("style", "class"): "text",
})
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib={
_mkTag("style", "font-name"): self._textFont,
_mkTag("style", "font-name"): self._fontFamily,
_mkTag("fo", "font-family"): self._fontFamily,
_mkTag("fo", "font-weight"): self._fontWeight,
_mkTag("fo", "font-style"): self._fontStyle,
_mkTag("fo", "font-size"): self._fSizeText,
})
@@ -841,8 +860,10 @@ class ToOdt(Tokenizer):
_mkTag("fo", "keep-with-next"): "always",
})
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib={
_mkTag("style", "font-name"): self._textFont,
_mkTag("style", "font-name"): self._fontFamily,
_mkTag("fo", "font-family"): self._fontFamily,
_mkTag("fo", "font-weight"): self._fontWeight,
_mkTag("fo", "font-style"): self._fontStyle,
_mkTag("fo", "font-size"): self._fSizeHead,
})
@@ -868,9 +889,10 @@ class ToOdt(Tokenizer):
style.setMarginBottom(self._mBotText)
style.setLineHeight(self._fLineHeight)
style.setTextAlign(self._textAlign)
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeText)
style.setFontWeight(self._fontWeight)
style.packXML(self._xStyl)
self._mainPara[style.name] = style
@@ -891,9 +913,10 @@ class ToOdt(Tokenizer):
style.setMarginTop(self._mTopMeta)
style.setMarginBottom(self._mBotMeta)
style.setLineHeight(self._fLineHeight)
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeText)
style.setFontWeight(self._fontWeight)
style.setColour(self._colMetaTx)
style.setOpacity(self._opaMetaTx)
style.packXML(self._xStyl)
@@ -908,10 +931,10 @@ class ToOdt(Tokenizer):
style.setMarginTop(self._mTopTitle)
style.setMarginBottom(self._mBotTitle)
style.setTextAlign("center")
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeTitle)
style.setFontWeight("bold")
style.setFontWeight(self._fontBold)
style.packXML(self._xStyl)
self._mainPara[style.name] = style
@@ -925,9 +948,10 @@ class ToOdt(Tokenizer):
style.setMarginBottom(self._mBotText)
style.setLineHeight(self._fLineHeight)
style.setTextAlign("center")
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeText)
style.setFontWeight(self._fontWeight)
style.packXML(self._xStyl)
self._mainPara[style.name] = style
@@ -940,10 +964,10 @@ class ToOdt(Tokenizer):
style.setClass("text")
style.setMarginTop(self._mTopHead1)
style.setMarginBottom(self._mBotHead1)
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead1)
style.setFontWeight("bold")
style.setFontWeight(self._fontBold)
style.setColour(self._colHead12)
style.setOpacity(self._opaHead12)
style.packXML(self._xStyl)
@@ -958,10 +982,10 @@ class ToOdt(Tokenizer):
style.setClass("text")
style.setMarginTop(self._mTopHead2)
style.setMarginBottom(self._mBotHead2)
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead2)
style.setFontWeight("bold")
style.setFontWeight(self._fontBold)
style.setColour(self._colHead12)
style.setOpacity(self._opaHead12)
style.packXML(self._xStyl)
@@ -976,10 +1000,10 @@ class ToOdt(Tokenizer):
style.setClass("text")
style.setMarginTop(self._mTopHead3)
style.setMarginBottom(self._mBotHead3)
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead3)
style.setFontWeight("bold")
style.setFontWeight(self._fontBold)
style.setColour(self._colHead34)
style.setOpacity(self._opaHead34)
style.packXML(self._xStyl)
@@ -994,10 +1018,10 @@ class ToOdt(Tokenizer):
style.setClass("text")
style.setMarginTop(self._mTopHead4)
style.setMarginBottom(self._mBotHead4)
style.setFontName(self._textFont)
style.setFontName(self._fontFamily)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead4)
style.setFontWeight("bold")
style.setFontWeight(self._fontBold)
style.setColour(self._colHead34)
style.setOpacity(self._opaHead34)
style.packXML(self._xStyl)
@@ -1077,7 +1101,7 @@ class ODTParagraphStyle:
VALID_BREAK = ["auto", "column", "page", "even-page", "odd-page", "inherit"]
VALID_LEVEL = ["1", "2", "3", "4"]
VALID_CLASS = ["text", "chapter", "extra"]
VALID_WEIGHT = ["normal", "inherit", "bold"]
VALID_WEIGHT = ["normal", "bold"] + FONT_WEIGHT_NUM
def __init__(self, name: str) -> None:
@@ -1320,8 +1344,8 @@ class ODTTextStyle:
Only the used settings are exposed here to keep the class minimal
and fast.
"""
VALID_WEIGHT = ["normal", "inherit", "bold"]
VALID_STYLE = ["normal", "inherit", "italic"]
VALID_WEIGHT = ["normal", "bold"] + FONT_WEIGHT_NUM
VALID_STYLE = ["normal", "italic", "oblique"]
VALID_POS = ["super", "sub"]
VALID_LSTYLE = ["none", "solid"]
VALID_LTYPE = ["single", "double"]
+18 -10
View File
@@ -30,8 +30,7 @@ from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent, QKeyEvent, QKeySequence
from PyQt5.QtWidgets import (
QAbstractButton, QApplication, QCompleter, QDialog, QDialogButtonBox,
QFileDialog, QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout,
QWidget
QFileDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout, QWidget
)
from novelwriter import CONFIG, SHARED
@@ -183,7 +182,7 @@ class GuiPreferences(QDialog):
self.guiFont.setMinimumWidth(fontWidth)
self.guiFont.setText(describeFont(self._guiFont))
self.guiFont.setCursorPosition(0)
self.guiFontButton = NIconToolButton(self, iSz, "more")
self.guiFontButton = NIconToolButton(self, iSz, "font")
self.guiFontButton.clicked.connect(self._selectGuiFont)
self.mainForm.addRow(
self.tr("Application font"), self.guiFont,
@@ -207,6 +206,14 @@ class GuiPreferences(QDialog):
self.tr("Scrolling available with mouse wheel and keys only.")
)
# Native Font Dialog
self.nativeFont = NSwitch(self)
self.nativeFont.setChecked(CONFIG.nativeFont)
self.mainForm.addRow(
self.tr("Use the system's font selection dialog"), self.nativeFont,
self.tr("Turn off to use the Qt font dialog, which may have more options.")
)
# Document Style
# ==============
@@ -233,7 +240,7 @@ class GuiPreferences(QDialog):
self.textFont.setMinimumWidth(fontWidth)
self.textFont.setText(describeFont(CONFIG.textFont))
self.textFont.setCursorPosition(0)
self.textFontButton = NIconToolButton(self, iSz, "more")
self.textFontButton = NIconToolButton(self, iSz, "font")
self.textFontButton.clicked.connect(self._selectTextFont)
self.mainForm.addRow(
self.tr("Document font"), self.textFont,
@@ -695,7 +702,7 @@ class GuiPreferences(QDialog):
self.quoteSym["SO"].setFixedWidth(boxFixed)
self.quoteSym["SO"].setAlignment(QtAlignCenter)
self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen)
self.btnSingleStyleO = NIconToolButton(self, iSz, "more")
self.btnSingleStyleO = NIconToolButton(self, iSz, "quote")
self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO"))
self.mainForm.addRow(
self.tr("Single quote open style"), self.quoteSym["SO"],
@@ -709,7 +716,7 @@ class GuiPreferences(QDialog):
self.quoteSym["SC"].setFixedWidth(boxFixed)
self.quoteSym["SC"].setAlignment(QtAlignCenter)
self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose)
self.btnSingleStyleC = NIconToolButton(self, iSz, "more")
self.btnSingleStyleC = NIconToolButton(self, iSz, "quote")
self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC"))
self.mainForm.addRow(
self.tr("Single quote close style"), self.quoteSym["SC"],
@@ -724,7 +731,7 @@ class GuiPreferences(QDialog):
self.quoteSym["DO"].setFixedWidth(boxFixed)
self.quoteSym["DO"].setAlignment(QtAlignCenter)
self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen)
self.btnDoubleStyleO = NIconToolButton(self, iSz, "more")
self.btnDoubleStyleO = NIconToolButton(self, iSz, "quote")
self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO"))
self.mainForm.addRow(
self.tr("Double quote open style"), self.quoteSym["DO"],
@@ -738,7 +745,7 @@ class GuiPreferences(QDialog):
self.quoteSym["DC"].setFixedWidth(boxFixed)
self.quoteSym["DC"].setAlignment(QtAlignCenter)
self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose)
self.btnDoubleStyleC = NIconToolButton(self, iSz, "more")
self.btnDoubleStyleC = NIconToolButton(self, iSz, "quote")
self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC"))
self.mainForm.addRow(
self.tr("Double quote close style"), self.quoteSym["DC"],
@@ -804,7 +811,7 @@ class GuiPreferences(QDialog):
@pyqtSlot()
def _selectGuiFont(self) -> None:
"""Open the QFontDialog and set a font for the font style."""
font, status = QFontDialog.getFont(self._guiFont, self)
font, status = SHARED.getFont(self._guiFont, self.nativeFont.isChecked())
if status:
self.guiFont.setText(describeFont(font))
self.guiFont.setCursorPosition(0)
@@ -814,7 +821,7 @@ class GuiPreferences(QDialog):
@pyqtSlot()
def _selectTextFont(self) -> None:
"""Open the QFontDialog and set a font for the font style."""
font, status = QFontDialog.getFont(CONFIG.textFont, self)
font, status = SHARED.getFont(self._textFont, self.nativeFont.isChecked())
if status:
self.textFont.setText(describeFont(font))
self.textFont.setCursorPosition(0)
@@ -883,6 +890,7 @@ class GuiPreferences(QDialog):
CONFIG.guiTheme = guiTheme
CONFIG.hideVScroll = self.hideVScroll.isChecked()
CONFIG.hideHScroll = self.hideHScroll.isChecked()
CONFIG.nativeFont = self.nativeFont.isChecked()
CONFIG.setGuiFont(self._guiFont)
# Document Style
+1
View File
@@ -50,6 +50,7 @@ class GuiQuoteSelect(QDialog):
logger.debug("Create: GuiQuoteSelect")
self.setObjectName("GuiQuoteSelect")
self.setWindowTitle(self.tr("Select Quote Style"))
self.outerBox = QVBoxLayout()
self.innerBox = QHBoxLayout()
+3 -3
View File
@@ -501,9 +501,9 @@ class GuiIcons:
# General Button Icons
"add", "add_document", "backward", "bookmark", "browse", "checked", "close", "cross",
"document", "down", "edit", "export", "forward", "import", "list", "maximise", "menu",
"minimise", "more", "noncheckable", "open", "panel", "refresh", "remove", "revert",
"search_replace", "search", "settings", "star", "unchecked", "up", "view",
"document", "down", "edit", "export", "font", "forward", "import", "list", "maximise",
"menu", "minimise", "more", "noncheckable", "open", "panel", "quote", "refresh", "remove",
"revert", "search_replace", "search", "settings", "star", "unchecked", "up", "view",
# Switches
"sticky-on", "sticky-off",
+14 -3
View File
@@ -31,7 +31,8 @@ from time import time
from typing import TYPE_CHECKING, TypeVar
from PyQt5.QtCore import QObject, QRunnable, QThreadPool, QTimer, pyqtSignal
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QWidget
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QFileDialog, QFontDialog, QMessageBox, QWidget
from novelwriter.common import formatFileFilter
from novelwriter.constants import nwFiles
@@ -255,8 +256,11 @@ class SharedData(QObject):
QThreadPool.globalInstance().start(runnable, priority=priority)
return
def getProjectPath(self, parent: QWidget, path: str | Path | None = None,
allowZip: bool = False) -> Path | None:
def getProjectPath(
self, parent: QWidget,
path: str | Path | None = None,
allowZip: bool = False
) -> Path | None:
"""Open the file dialog and select a novelWriter project file."""
label = (self.tr("novelWriter Project File or Zip File")
if allowZip else self.tr("novelWriter Project File"))
@@ -267,6 +271,13 @@ class SharedData(QObject):
)
return Path(selected) if selected else None
def getFont(self, current: QFont, native: bool) -> tuple[QFont, bool]:
"""Open the font dialog and select a font."""
kwargs = {}
if not native:
kwargs["options"] = QFontDialog.FontDialogOption.DontUseNativeDialog
return QFontDialog.getFont(current, self.mainGui, self.tr("Select Font"), **kwargs)
def findTopLevelWidget(self, kind: type[NWWidget]) -> NWWidget | None:
"""Find a top level widget."""
for widget in self.mainGui.children():
+10 -14
View File
@@ -31,7 +31,7 @@ from time import time
from typing import TYPE_CHECKING
from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QPalette, QResizeEvent
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from PyQt5.QtWidgets import (
QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
@@ -402,12 +402,12 @@ class GuiManuscript(NToolDialog):
def _updatePreview(self, data: dict, build: BuildSettings) -> None:
"""Update the preview widget and set relevant values."""
textFont = QFont()
textFont.fromString(build.getStr("format.textFont"))
self.docPreview.setContent(data)
self.docPreview.setBuildName(build.name)
self.docPreview.setTextFont(
build.getStr("format.textFont"),
build.getInt("format.textSize")
)
self.docPreview.setTextFont(textFont)
self.docPreview.setJustify(
build.getBool("format.justifyText")
)
@@ -787,7 +787,7 @@ class _PreviewWidget(QTextBrowser):
self._updateDocMargins()
self._updateBuildAge()
self.setTextFont(CONFIG.textFont.family(), CONFIG.textFont.pointSize())
self.setTextFont(CONFIG.textFont)
# Age Timer
self.ageTimer = QTimer(self)
@@ -817,18 +817,14 @@ class _PreviewWidget(QTextBrowser):
self.document().setDefaultTextOption(pOptions)
return
def setTextFont(self, family: str, size: int) -> None:
def setTextFont(self, font: QFont) -> None:
"""Set the text font properties and then reset for sub-widgets.
This needs special attention since there appears to be a bug in
Qt 5.15.3. See issues #1862 and #1875.
"""
if family and size > 4:
font = self.font()
font.setFamily(family)
font.setPointSize(size)
self.setFont(font)
self.buildProgress.setFont(SHARED.theme.guiFont)
self.ageLabel.setFont(SHARED.theme.guiFontSmall)
self.setFont(font)
self.buildProgress.setFont(SHARED.theme.guiFont)
self.ageLabel.setFont(SHARED.theme.guiFontSmall)
return
##
+23 -37
View File
@@ -30,13 +30,14 @@ from typing import TYPE_CHECKING
from PyQt5.QtCore import QEvent, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
from PyQt5.QtWidgets import (
QAbstractButton, QAbstractItemView, QDialogButtonBox, QFontDialog, QFrame,
QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu,
QPlainTextEdit, QPushButton, QSplitter, QStackedWidget, QTreeWidget,
QTreeWidgetItem, QVBoxLayout, QWidget
QAbstractButton, QAbstractItemView, QDialogButtonBox, QFrame, QGridLayout,
QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu, QPlainTextEdit,
QPushButton, QSplitter, QStackedWidget, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import describeFont
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst
from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.extensions.configlayout import (
@@ -1052,6 +1053,7 @@ class _FormatTab(NScrollableForm):
self._build = build
self._unitScale = 1.0
self._textFont = QFont(CONFIG.textFont)
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
@@ -1063,24 +1065,16 @@ class _FormatTab(NScrollableForm):
self.addGroupLabel(self._build.getLabel("format.grpFormat"))
# Font Family
# Text Font
self.textFont = QLineEdit(self)
self.textFont.setReadOnly(True)
self.btnTextFont = NIconToolButton(self, iSz, "more")
self.btnTextFont = NIconToolButton(self, iSz, "font")
self.btnTextFont.clicked.connect(self._selectFont)
self.addRow(
self._build.getLabel("format.textFont"), self.textFont,
button=self.btnTextFont, stretch=(3, 2)
button=self.btnTextFont, stretch=(1, 1)
)
# Font Size
self.textSize = NSpinBox(self)
self.textSize.setMinimum(8)
self.textSize.setMaximum(60)
self.textSize.setSingleStep(1)
self.textSize.setMinimumWidth(spW)
self.addRow(self._build.getLabel("format.textSize"), self.textSize, unit="pt")
# Line Height
self.lineHeight = NDoubleSpinBox(self)
self.lineHeight.setFixedWidth(spW)
@@ -1098,10 +1092,12 @@ class _FormatTab(NScrollableForm):
self.justifyText = NSwitch(self, height=iPx)
self.stripUnicode = NSwitch(self, height=iPx)
self.replaceTabs = NSwitch(self, height=iPx)
self.keepBreaks = NSwitch(self, height=iPx)
self.addRow(self._build.getLabel("format.justifyText"), self.justifyText)
self.addRow(self._build.getLabel("format.stripUnicode"), self.stripUnicode)
self.addRow(self._build.getLabel("format.replaceTabs"), self.replaceTabs)
self.addRow(self._build.getLabel("format.keepBreaks"), self.keepBreaks)
# First Line Indent
# =================
@@ -1173,17 +1169,17 @@ class _FormatTab(NScrollableForm):
def loadContent(self) -> None:
"""Populate the widgets."""
textFont = self._build.getStr("format.textFont")
if not textFont:
textFont = str(CONFIG.textFont.family())
self._textFont = QFont()
self._textFont.fromString(self._build.getStr("format.textFont"))
self.textFont.setText(describeFont(self._textFont))
self.textFont.setCursorPosition(0)
self.textFont.setText(textFont)
self.textSize.setValue(self._build.getInt("format.textSize"))
self.lineHeight.setValue(self._build.getFloat("format.lineHeight"))
self.justifyText.setChecked(self._build.getBool("format.justifyText"))
self.stripUnicode.setChecked(self._build.getBool("format.stripUnicode"))
self.replaceTabs.setChecked(self._build.getBool("format.replaceTabs"))
self.keepBreaks.setChecked(self._build.getBool("format.keepBreaks"))
self.firstIndent.setChecked(self._build.getBool("format.firstLineIndent"))
self.indentWidth.setValue(self._build.getFloat("format.firstIndentWidth"))
@@ -1216,13 +1212,13 @@ class _FormatTab(NScrollableForm):
def saveContent(self) -> None:
"""Save choices back into build object."""
self._build.setValue("format.textFont", self.textFont.text())
self._build.setValue("format.textSize", self.textSize.value())
self._build.setValue("format.textFont", self._textFont.toString())
self._build.setValue("format.lineHeight", self.lineHeight.value())
self._build.setValue("format.justifyText", self.justifyText.isChecked())
self._build.setValue("format.stripUnicode", self.stripUnicode.isChecked())
self._build.setValue("format.replaceTabs", self.replaceTabs.isChecked())
self._build.setValue("format.keepBreaks", self.keepBreaks.isChecked())
self._build.setValue("format.firstLineIndent", self.firstIndent.isChecked())
self._build.setValue("format.firstIndentWidth", self.indentWidth.value())
@@ -1245,13 +1241,11 @@ class _FormatTab(NScrollableForm):
@pyqtSlot()
def _selectFont(self) -> None:
"""Open the QFontDialog and set a font for the font style."""
currFont = QFont()
currFont.setFamily(self.textFont.text())
currFont.setPointSize(self.textSize.value())
newFont, status = QFontDialog.getFont(currFont, self)
font, status = SHARED.getFont(self._textFont, CONFIG.nativeFont)
if status:
self.textFont.setText(newFont.family())
self.textSize.setValue(newFont.pointSize())
self.textFont.setText(describeFont(font))
self.textFont.setCursorPosition(0)
self._textFont = font
return
@pyqtSlot(int)
@@ -1379,12 +1373,6 @@ class _OutputTab(NScrollableForm):
self.htmlPreserveTabs = NSwitch(self, height=iPx)
self.addRow(self._build.getLabel("html.preserveTabs"), self.htmlPreserveTabs)
# Markdown Document
self.addGroupLabel(self._build.getLabel("md"))
self.mdPreserveBreaks = NSwitch(self, height=iPx)
self.addRow(self._build.getLabel("md.preserveBreaks"), self.mdPreserveBreaks)
# Finalise
self.finalise()
@@ -1397,7 +1385,6 @@ class _OutputTab(NScrollableForm):
self.odtPageCountOffset.setValue(self._build.getInt("odt.pageCountOffset"))
self.htmlAddStyles.setChecked(self._build.getBool("html.addStyles"))
self.htmlPreserveTabs.setChecked(self._build.getBool("html.preserveTabs"))
self.mdPreserveBreaks.setChecked(self._build.getBool("md.preserveBreaks"))
self.odtPageHeader.setCursorPosition(0)
return
@@ -1408,7 +1395,6 @@ class _OutputTab(NScrollableForm):
self._build.setValue("odt.pageCountOffset", self.odtPageCountOffset.value())
self._build.setValue("html.addStyles", self.htmlAddStyles.isChecked())
self._build.setValue("html.preserveTabs", self.htmlPreserveTabs.isChecked())
self._build.setValue("md.preserveBreaks", self.mdPreserveBreaks.isChecked())
return
##
+21 -1
View File
@@ -24,7 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations
from PyQt5.QtCore import QRegularExpression, Qt
from PyQt5.QtGui import QColor, QPainter, QTextCursor, QTextFormat
from PyQt5.QtGui import QColor, QFont, QPainter, QTextCursor, QTextFormat
from PyQt5.QtWidgets import QDialogButtonBox, QSizePolicy, QStyle
# Qt Alignment Flags
@@ -105,3 +105,23 @@ QtSizeMinimumExpanding = QSizePolicy.Policy.MinimumExpanding
# Other
QRegExUnicode = QRegularExpression.PatternOption.UseUnicodePropertiesOption
# Maps
FONT_WEIGHTS: dict[int, int] = {
QFont.Weight.Thin: 100,
QFont.Weight.ExtraLight: 200,
QFont.Weight.Light: 300,
QFont.Weight.Normal: 400,
QFont.Weight.Medium: 500,
QFont.Weight.DemiBold: 600,
QFont.Weight.Bold: 700,
QFont.Weight.ExtraBold: 800,
QFont.Weight.Black: 900,
}
FONT_STYLE: dict[int, str] = {
QFont.Style.StyleNormal: "normal",
QFont.Style.StyleItalic: "italic",
QFont.Style.StyleOblique: "oblique",
}
@@ -9,6 +9,7 @@ localisation = en_GB
hidevscroll = False
hidehscroll = False
lastnotes = 0x0
nativefont = True
lastpath =
[Sizes]
@@ -1,13 +1,13 @@
<?xml version='1.0' encoding='utf-8'?>
<office:document xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:meta>
<meta:creation-date>2024-04-24T18:30:38</meta:creation-date>
<meta:generator>novelWriter/2.5a2</meta:generator>
<meta:creation-date>2024-05-22T23:05:27</meta:creation-date>
<meta:generator>novelWriter/2.5a4</meta:generator>
<meta:initial-creator>Jane Smith</meta:initial-creator>
<meta:editing-cycles>1234</meta:editing-cycles>
<meta:editing-duration>P42DT12H34M56S</meta:editing-duration>
<dc:title>Test Project</dc:title>
<dc:date>2024-04-24T18:30:38</dc:date>
<dc:date>2024-05-22T23:05:27</dc:date>
<dc:creator>Jane Smith</dc:creator>
</office:meta>
<office:font-face-decls>
@@ -16,50 +16,50 @@
<office:styles>
<style:default-style style:family="paragraph">
<style:paragraph-properties style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" fo:language="nb" fo:country="NO" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-weight="normal" fo:font-style="normal" fo:font-size="12pt" fo:language="nb" fo:country="NO" />
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text">
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-weight="normal" fo:font-style="normal" fo:font-size="12pt" />
</style:style>
<style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.247cm" fo:margin-bottom="0.212cm" fo:keep-with-next="always" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="14pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-weight="normal" fo:font-style="normal" fo:font-size="14pt" />
</style:style>
<style:style style:name="Header_20_and_20_Footer" style:display-name="Header and Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra" />
<style:style style:name="Text_20_body" style:family="paragraph" style:display-name="Text body" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.247cm" fo:line-height="115%" fo:text-align="left" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="12pt" fo:font-weight="normal" />
</style:style>
<style:style style:name="First_20_line_20_indent" style:family="paragraph" style:display-name="First line indent" style:parent-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:text-indent="0.593cm" />
</style:style>
<style:style style:name="Text_20_Meta" style:family="paragraph" style:display-name="Text Meta" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.247cm" fo:line-height="115%" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" fo:color="#813709" loext:opacity="100%" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="12pt" fo:font-weight="normal" fo:color="#813709" loext:opacity="100%" />
</style:style>
<style:style style:name="Title" style:family="paragraph" style:display-name="Title" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="chapter">
<style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" fo:text-align="center" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="30pt" fo:font-weight="bold" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="30pt" fo:font-weight="bold" />
</style:style>
<style:style style:name="Separator" style:family="paragraph" style:display-name="Separator" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.247cm" fo:line-height="115%" fo:text-align="center" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="12pt" fo:font-weight="normal" />
</style:style>
<style:style style:name="Heading_20_1" style:family="paragraph" style:display-name="Heading 1" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="1" style:class="text">
<style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="24pt" fo:font-weight="bold" fo:color="#2a6099" loext:opacity="100%" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="24pt" fo:font-weight="bold" fo:color="#2a6099" loext:opacity="100%" />
</style:style>
<style:style style:name="Heading_20_2" style:family="paragraph" style:display-name="Heading 2" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="2" style:class="text">
<style:paragraph-properties fo:margin-top="0.353cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="19pt" fo:font-weight="bold" fo:color="#2a6099" loext:opacity="100%" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="19pt" fo:font-weight="bold" fo:color="#2a6099" loext:opacity="100%" />
</style:style>
<style:style style:name="Heading_20_3" style:family="paragraph" style:display-name="Heading 3" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="3" style:class="text">
<style:paragraph-properties fo:margin-top="0.247cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="16pt" fo:font-weight="bold" fo:color="#444444" loext:opacity="100%" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="16pt" fo:font-weight="bold" fo:color="#444444" loext:opacity="100%" />
</style:style>
<style:style style:name="Heading_20_4" style:family="paragraph" style:display-name="Heading 4" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="4" style:class="text">
<style:paragraph-properties fo:margin-top="0.247cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="14pt" fo:font-weight="bold" fo:color="#444444" loext:opacity="100%" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="14pt" fo:font-weight="bold" fo:color="#444444" loext:opacity="100%" />
</style:style>
<style:style style:name="Header" style:family="paragraph" style:display-name="Header" style:parent-style-name="Header_20_and_20_Footer">
<style:paragraph-properties fo:text-align="right" />
+11 -11
View File
@@ -6,50 +6,50 @@
<office:styles>
<style:default-style style:family="paragraph">
<style:paragraph-properties style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" fo:language="en" fo:country="GB" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-weight="normal" fo:font-style="normal" fo:font-size="12pt" fo:language="en" fo:country="GB" />
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text">
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-weight="normal" fo:font-style="normal" fo:font-size="12pt" />
</style:style>
<style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.247cm" fo:margin-bottom="0.212cm" fo:keep-with-next="always" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="14pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-weight="normal" fo:font-style="normal" fo:font-size="14pt" />
</style:style>
<style:style style:name="Header_20_and_20_Footer" style:display-name="Header and Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra" />
<style:style style:name="Text_20_body" style:family="paragraph" style:display-name="Text body" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.247cm" fo:line-height="115%" fo:text-align="left" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="12pt" fo:font-weight="normal" />
</style:style>
<style:style style:name="First_20_line_20_indent" style:family="paragraph" style:display-name="First line indent" style:parent-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:text-indent="0.593cm" />
</style:style>
<style:style style:name="Text_20_Meta" style:family="paragraph" style:display-name="Text Meta" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.247cm" fo:line-height="115%" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="12pt" fo:font-weight="normal" />
</style:style>
<style:style style:name="Title" style:family="paragraph" style:display-name="Title" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="chapter">
<style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" fo:text-align="center" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="30pt" fo:font-weight="bold" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="30pt" fo:font-weight="bold" />
</style:style>
<style:style style:name="Separator" style:family="paragraph" style:display-name="Separator" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.247cm" fo:line-height="115%" fo:text-align="center" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="12pt" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="12pt" fo:font-weight="normal" />
</style:style>
<style:style style:name="Heading_20_1" style:family="paragraph" style:display-name="Heading 1" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="1" style:class="text">
<style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="24pt" fo:font-weight="bold" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="24pt" fo:font-weight="bold" />
</style:style>
<style:style style:name="Heading_20_2" style:family="paragraph" style:display-name="Heading 2" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="2" style:class="text">
<style:paragraph-properties fo:margin-top="0.353cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="19pt" fo:font-weight="bold" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="19pt" fo:font-weight="bold" />
</style:style>
<style:style style:name="Heading_20_3" style:family="paragraph" style:display-name="Heading 3" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="3" style:class="text">
<style:paragraph-properties fo:margin-top="0.247cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="16pt" fo:font-weight="bold" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="16pt" fo:font-weight="bold" />
</style:style>
<style:style style:name="Heading_20_4" style:family="paragraph" style:display-name="Heading 4" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="4" style:class="text">
<style:paragraph-properties fo:margin-top="0.247cm" fo:margin-bottom="0.212cm" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="'Liberation Serif'" fo:font-size="14pt" fo:font-weight="bold" />
<style:text-properties style:font-name="Liberation Serif" fo:font-family="Liberation Serif" fo:font-size="14pt" fo:font-weight="bold" />
</style:style>
<style:style style:name="Header" style:family="paragraph" style:display-name="Header" style:parent-style-name="Header_20_and_20_Footer">
<style:paragraph-properties fo:text-align="right" />
@@ -5,7 +5,7 @@
<title>Lorem Ipsum</title>
</head>
<style>
body {font-family: 'Arial'; font-size: 12pt;}
body {font-family: 'Arial'; font-size: 12pt; font-weight: 400; font-style: normal;}
p {text-align: justify; line-height: 150%; margin-top: 0.00em; margin-bottom: 0.76em;}
h1 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.30em; margin-bottom: 0.65em;}
h2 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.09em; margin-bottom: 0.65em;}
@@ -2,12 +2,12 @@
"meta": {
"projectName": "Lorem Ipsum",
"novelAuthor": "lipsum.com",
"buildTime": 1714336438,
"buildTimeStr": "2024-04-28 22:33:58"
"buildTime": 1716412100,
"buildTimeStr": "2024-05-22 23:08:20"
},
"text": {
"css": [
"body {font-family: 'Arial'; font-size: 12pt;}",
"body {font-family: 'Arial'; font-size: 12pt; font-weight: 400; font-style: normal;}",
"p {text-align: justify; line-height: 150%; margin-top: 0.00em; margin-bottom: 0.76em;}",
"h1 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.30em; margin-bottom: 0.65em;}",
"h2 {color: rgb(66, 113, 174); page-break-after: avoid; margin-top: 1.09em; margin-bottom: 0.65em;}",
@@ -1,13 +1,13 @@
<?xml version='1.0' encoding='utf-8'?>
<office:document xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:meta>
<meta:creation-date>2024-05-10T15:23:56</meta:creation-date>
<meta:generator>novelWriter/2.5a3</meta:generator>
<meta:creation-date>2024-05-22T23:05:26</meta:creation-date>
<meta:generator>novelWriter/2.5a4</meta:generator>
<meta:initial-creator>lipsum.com</meta:initial-creator>
<meta:editing-cycles>45</meta:editing-cycles>
<meta:editing-duration>P0DT0H36M8S</meta:editing-duration>
<dc:title>Lorem Ipsum</dc:title>
<dc:date>2024-05-10T15:23:56</dc:date>
<dc:date>2024-05-22T23:05:26</dc:date>
<dc:creator>lipsum.com</dc:creator>
</office:meta>
<office:font-face-decls>
@@ -16,26 +16,26 @@
<office:styles>
<style:default-style style:family="paragraph">
<style:paragraph-properties style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" fo:language="en" fo:country="GB" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-weight="normal" fo:font-style="normal" fo:font-size="12pt" fo:language="en" fo:country="GB" />
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text">
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-weight="normal" fo:font-style="normal" fo:font-size="12pt" />
</style:style>
<style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.322cm" fo:margin-bottom="0.276cm" fo:keep-with-next="always" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="14pt" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-weight="normal" fo:font-style="normal" fo:font-size="14pt" />
</style:style>
<style:style style:name="Header_20_and_20_Footer" style:display-name="Header and Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra" />
<style:style style:name="Text_20_body" style:family="paragraph" style:display-name="Text body" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.322cm" fo:line-height="150%" fo:text-align="justify" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" fo:font-weight="normal" />
</style:style>
<style:style style:name="First_20_line_20_indent" style:family="paragraph" style:display-name="First line indent" style:parent-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:text-indent="0.593cm" />
</style:style>
<style:style style:name="Text_20_Meta" style:family="paragraph" style:display-name="Text Meta" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.322cm" fo:line-height="150%" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" fo:color="#813709" loext:opacity="100%" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" fo:font-weight="normal" fo:color="#813709" loext:opacity="100%" />
</style:style>
<style:style style:name="Title" style:family="paragraph" style:display-name="Title" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="chapter">
<style:paragraph-properties fo:margin-top="0.552cm" fo:margin-bottom="0.276cm" fo:text-align="center" />
@@ -43,7 +43,7 @@
</style:style>
<style:style style:name="Separator" style:family="paragraph" style:display-name="Separator" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.000cm" fo:margin-bottom="0.322cm" fo:line-height="150%" fo:text-align="center" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" />
<style:text-properties style:font-name="Arial" fo:font-family="Arial" fo:font-size="12pt" fo:font-weight="normal" />
</style:style>
<style:style style:name="Heading_20_1" style:family="paragraph" style:display-name="Heading 1" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="1" style:class="text">
<style:paragraph-properties fo:margin-top="0.552cm" fo:margin-bottom="0.276cm" />
+2 -1
View File
@@ -492,7 +492,8 @@ def testBaseCommon_describeFont():
"""Test the describeFont function."""
fontDB = QFontDatabase()
font = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont)
assert font.family() in describeFont(font)
font.setPointSize(12)
assert describeFont(font).startswith("12 pt")
assert describeFont(None) == "Error" # type: ignore
+1 -1
View File
@@ -148,7 +148,7 @@ def testCoreBuildSettings_BuildValues():
build = BuildSettings()
strSetting = "headings.fmtTitle"
intSetting = "format.textSize"
intSetting = "odt.pageCountOffset"
boolSetting = "filter.includeNovel"
floatSetting = "format.lineHeight"
+1 -2
View File
@@ -58,8 +58,7 @@ BUILD_CONF = {
"text.includeBodyText": True,
"text.addNoteHeadings": True,
"format.buildLang": "en_GB",
"format.textFont": "Arial",
"format.textSize": 12,
"format.textFont": "Arial,12",
"format.lineHeight": 1.5,
"format.justifyText": True,
"format.stripUnicode": False,
+2 -8
View File
@@ -316,7 +316,6 @@ def testCoreToHtml_ConvertDirect(mockGUI):
# Title
html._tokens = [
(html.T_TITLE, 1, "A Title", [], html.A_PBB | html.A_CENTRE),
(html.T_EMPTY, 1, "", [], html.A_NONE),
]
html.doConvert()
assert html.result == (
@@ -327,7 +326,6 @@ def testCoreToHtml_ConvertDirect(mockGUI):
# Unnumbered
html._tokens = [
(html.T_HEAD2, 1, "Prologue", [], html.A_PBB),
(html.T_EMPTY, 1, "", [], html.A_NONE),
]
html.doConvert()
assert html.result == (
@@ -341,7 +339,6 @@ def testCoreToHtml_ConvertDirect(mockGUI):
# Separator
html._tokens = [
(html.T_SEP, 1, "* * *", [], html.A_CENTRE),
(html.T_EMPTY, 1, "", [], html.A_NONE),
]
html.doConvert()
assert html.result == "<p class='sep' style='text-align: center;'>* * *</p>\n"
@@ -349,7 +346,6 @@ def testCoreToHtml_ConvertDirect(mockGUI):
# Skip
html._tokens = [
(html.T_SKIP, 1, "", [], html.A_NONE),
(html.T_EMPTY, 1, "", [], html.A_NONE),
]
html.doConvert()
assert html.result == "<p class='skip'>&nbsp;</p>\n"
@@ -425,8 +421,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
# Indent Left
html._tokens = [
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_L),
(html.T_EMPTY, 2, "", [], html.A_NONE),
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_L),
]
html.doConvert()
assert html.result == (
@@ -435,8 +430,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
# Indent Right
html._tokens = [
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_R),
(html.T_EMPTY, 2, "", [], html.A_NONE),
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_R),
]
html.doConvert()
assert html.result == (
+6 -8
View File
@@ -24,6 +24,8 @@ import json
import pytest
from PyQt5.QtGui import QFont
from novelwriter.constants import nwHeadFmt
from novelwriter.core.project import NWProject
from novelwriter.core.tokenizer import HeadingFormatter, Tokenizer, stripEscape
@@ -50,9 +52,7 @@ def testCoreToken_Setters(mockGUI):
assert tokens._fmtScene == nwHeadFmt.TITLE
assert tokens._fmtHScene == nwHeadFmt.TITLE
assert tokens._fmtSection == nwHeadFmt.TITLE
assert tokens._textFont == "Serif"
assert tokens._textSize == 11
assert tokens._textFixed is False
assert tokens._textFont == QFont("Serif", 11)
assert tokens._lineHeight == 1.15
assert tokens._blockIndent == 4.0
assert tokens._doJustify is False
@@ -82,7 +82,7 @@ def testCoreToken_Setters(mockGUI):
tokens.setSceneFormat(f"S: {nwHeadFmt.TITLE}", True)
tokens.setHardSceneFormat(f"H: {nwHeadFmt.TITLE}", True)
tokens.setSectionFormat(f"X: {nwHeadFmt.TITLE}", True)
tokens.setFont("Monospace", 10, True)
tokens.setFont(QFont("Monospace", 10))
tokens.setLineHeight(2.0)
tokens.setBlockIndent(6.0)
tokens.setJustify(True)
@@ -106,9 +106,7 @@ def testCoreToken_Setters(mockGUI):
assert tokens._fmtScene == f"S: {nwHeadFmt.TITLE}"
assert tokens._fmtHScene == f"H: {nwHeadFmt.TITLE}"
assert tokens._fmtSection == f"X: {nwHeadFmt.TITLE}"
assert tokens._textFont == "Monospace"
assert tokens._textSize == 10
assert tokens._textFixed is True
assert tokens._textFont == QFont("Monospace", 10)
assert tokens._lineHeight == 2.0
assert tokens._blockIndent == 6.0
assert tokens._doJustify is True
@@ -1835,7 +1833,7 @@ def testCoreToken_SceneSeparators(mockGUI):
# ===========================
# Requires a fresh builder class
md = ToMarkdown(project)
md.setExtendedMarkdown()
md.setExtendedMarkdown(True)
md._isNovel = True
md._text = (
+5 -7
View File
@@ -82,7 +82,7 @@ def testCoreToMarkdown_ConvertParagraphs(mockGUI):
toMD._isFirst = True
# Text for Extended Markdown
toMD.setExtendedMarkdown()
toMD.setExtendedMarkdown(True)
toMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
toMD.tokenizeText()
toMD.doConvert()
@@ -91,7 +91,7 @@ def testCoreToMarkdown_ConvertParagraphs(mockGUI):
)
# Text for Standard Markdown
toMD.setStandardMarkdown()
toMD.setExtendedMarkdown(False)
toMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
toMD.tokenizeText()
toMD.doConvert()
@@ -100,7 +100,7 @@ def testCoreToMarkdown_ConvertParagraphs(mockGUI):
)
# Shortcodes for Extended Markdown
toMD.setExtendedMarkdown()
toMD.setExtendedMarkdown(True)
toMD._text = (
"Some [b]bold[/b], [i]italic[/i], [s]strike[/s], [u]underline[/u], [m]mark[/m], "
"super[sup]script[/sup], sub[sub]script[/sub] here\n"
@@ -113,7 +113,7 @@ def testCoreToMarkdown_ConvertParagraphs(mockGUI):
)
# Shortcodes for Standard Markdown
toMD.setStandardMarkdown()
toMD.setExtendedMarkdown(False)
toMD._text = (
"Some [b]bold[/b], [i]italic[/i], [s]strike[/s], [u]underline[/u], [m]mark[/m], "
"super[sup]script[/sup], sub[sub]script[/sub] here\n"
@@ -215,6 +215,7 @@ def testCoreToMarkdown_ConvertDirect(mockGUI):
toMD = ToMarkdown(project)
toMD._isNovel = True
toMD.setExtendedMarkdown(False)
# Special Titles
# ==============
@@ -222,7 +223,6 @@ def testCoreToMarkdown_ConvertDirect(mockGUI):
# Title
toMD._tokens = [
(toMD.T_TITLE, 1, "A Title", [], toMD.A_PBB | toMD.A_CENTRE),
(toMD.T_EMPTY, 1, "", [], toMD.A_NONE),
]
toMD.doConvert()
assert toMD.result == "# A Title\n\n"
@@ -233,7 +233,6 @@ def testCoreToMarkdown_ConvertDirect(mockGUI):
# Separator
toMD._tokens = [
(toMD.T_SEP, 1, "* * *", [], toMD.A_CENTRE),
(toMD.T_EMPTY, 1, "", [], toMD.A_NONE),
]
toMD.doConvert()
assert toMD.result == "* * *\n\n"
@@ -241,7 +240,6 @@ def testCoreToMarkdown_ConvertDirect(mockGUI):
# Skip
toMD._tokens = [
(toMD.T_SKIP, 1, "", [], toMD.A_NONE),
(toMD.T_EMPTY, 1, "", [], toMD.A_NONE),
]
toMD.doConvert()
assert toMD.result == "\n\n"
+38 -8
View File
@@ -683,7 +683,6 @@ def testCoreToOdt_ConvertDirect(mockGUI):
doc = ToOdt(project, isFlat=True)
doc._tokens = [
(doc.T_TEXT, 1, "This is a paragraph", [], doc.A_JUSTIFY),
(doc.T_EMPTY, 1, "", [], doc.A_NONE),
]
doc.initDocument()
doc.doConvert()
@@ -704,7 +703,6 @@ def testCoreToOdt_ConvertDirect(mockGUI):
doc = ToOdt(project, isFlat=True)
doc._tokens = [
(doc.T_TEXT, 1, "This is a paragraph", [], doc.A_PBA),
(doc.T_EMPTY, 1, "", [], doc.A_NONE),
]
doc.initDocument()
doc.doConvert()
@@ -1045,10 +1043,26 @@ def testCoreToOdt_ODTParagraphStyle():
assert parStyle._tAttr["font-weight"] == ["fo", None]
parStyle.setFontWeight("normal")
assert parStyle._tAttr["font-weight"] == ["fo", "normal"]
parStyle.setFontWeight("inherit")
assert parStyle._tAttr["font-weight"] == ["fo", "inherit"]
parStyle.setFontWeight("bold")
assert parStyle._tAttr["font-weight"] == ["fo", "bold"]
parStyle.setFontWeight("100")
assert parStyle._tAttr["font-weight"] == ["fo", "100"]
parStyle.setFontWeight("200")
assert parStyle._tAttr["font-weight"] == ["fo", "200"]
parStyle.setFontWeight("300")
assert parStyle._tAttr["font-weight"] == ["fo", "300"]
parStyle.setFontWeight("400")
assert parStyle._tAttr["font-weight"] == ["fo", "400"]
parStyle.setFontWeight("500")
assert parStyle._tAttr["font-weight"] == ["fo", "500"]
parStyle.setFontWeight("600")
assert parStyle._tAttr["font-weight"] == ["fo", "600"]
parStyle.setFontWeight("700")
assert parStyle._tAttr["font-weight"] == ["fo", "700"]
parStyle.setFontWeight("800")
assert parStyle._tAttr["font-weight"] == ["fo", "800"]
parStyle.setFontWeight("900")
assert parStyle._tAttr["font-weight"] == ["fo", "900"]
parStyle.setFontWeight("stuff")
assert parStyle._tAttr["font-weight"] == ["fo", None]
@@ -1118,10 +1132,26 @@ def testCoreToOdt_ODTTextStyle():
assert txtStyle._tAttr["font-weight"] == ["fo", None]
txtStyle.setFontWeight("normal")
assert txtStyle._tAttr["font-weight"] == ["fo", "normal"]
txtStyle.setFontWeight("inherit")
assert txtStyle._tAttr["font-weight"] == ["fo", "inherit"]
txtStyle.setFontWeight("bold")
assert txtStyle._tAttr["font-weight"] == ["fo", "bold"]
txtStyle.setFontWeight("100")
assert txtStyle._tAttr["font-weight"] == ["fo", "100"]
txtStyle.setFontWeight("200")
assert txtStyle._tAttr["font-weight"] == ["fo", "200"]
txtStyle.setFontWeight("300")
assert txtStyle._tAttr["font-weight"] == ["fo", "300"]
txtStyle.setFontWeight("400")
assert txtStyle._tAttr["font-weight"] == ["fo", "400"]
txtStyle.setFontWeight("500")
assert txtStyle._tAttr["font-weight"] == ["fo", "500"]
txtStyle.setFontWeight("600")
assert txtStyle._tAttr["font-weight"] == ["fo", "600"]
txtStyle.setFontWeight("700")
assert txtStyle._tAttr["font-weight"] == ["fo", "700"]
txtStyle.setFontWeight("800")
assert txtStyle._tAttr["font-weight"] == ["fo", "800"]
txtStyle.setFontWeight("900")
assert txtStyle._tAttr["font-weight"] == ["fo", "900"]
txtStyle.setFontWeight("stuff")
assert txtStyle._tAttr["font-weight"] == ["fo", None]
@@ -1131,10 +1161,10 @@ def testCoreToOdt_ODTTextStyle():
assert txtStyle._tAttr["font-style"] == ["fo", None]
txtStyle.setFontStyle("normal")
assert txtStyle._tAttr["font-style"] == ["fo", "normal"]
txtStyle.setFontStyle("inherit")
assert txtStyle._tAttr["font-style"] == ["fo", "inherit"]
txtStyle.setFontStyle("italic")
assert txtStyle._tAttr["font-style"] == ["fo", "italic"]
txtStyle.setFontStyle("oblique")
assert txtStyle._tAttr["font-style"] == ["fo", "oblique"]
txtStyle.setFontStyle("stuff")
assert txtStyle._tAttr["font-style"] == ["fo", None]
+4 -11
View File
@@ -160,20 +160,12 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, tstPaths):
prefs = GuiPreferences(nwGUI)
prefs.show()
# Mock Font
class MockFont:
def family(self):
return "TestFont"
def pointSize(self):
return 42
# Appearance
prefs.guiLocale.setCurrentIndex(prefs.guiLocale.findData("en_US"))
prefs.guiTheme.setCurrentIndex(prefs.guiTheme.findData("default_dark"))
with monkeypatch.context() as mp:
mp.setattr(QFontDialog, "getFont", lambda *a: (QFont(), True))
mp.setattr(QFontDialog, "getFont", lambda *a, **k: (QFont(), True))
prefs.nativeFont.setChecked(True) # Use OS font dialog
prefs.guiFontButton.click()
prefs.hideVScroll.setChecked(True)
prefs.hideHScroll.setChecked(True)
@@ -187,7 +179,8 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, tstPaths):
# Document Style
prefs.guiSyntax.setCurrentIndex(prefs.guiSyntax.findData("default_dark"))
with monkeypatch.context() as mp:
mp.setattr(QFontDialog, "getFont", lambda *a: (QFont(), True))
mp.setattr(QFontDialog, "getFont", lambda *a, **k: (QFont(), True))
prefs.nativeFont.setChecked(False) # Use Qt font dialog
prefs.textFontButton.click()
prefs.emphLabels.setChecked(False)
prefs.showFullPath.setChecked(False)
+8 -16
View File
@@ -26,7 +26,8 @@ from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QFontDialog
from novelwriter import CONFIG, SHARED
from novelwriter import SHARED
from novelwriter.common import describeFont
from novelwriter.constants import nwHeadFmt
from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.tools.manussettings import (
@@ -547,11 +548,8 @@ def testBuildSettings_Format(monkeypatch, qtbot, nwGUI):
"""Test the Format Tab of the GuiBuildSettings dialog."""
build = BuildSettings()
textFont = str(CONFIG.textFont.family())
build.setValue("format.buildLang", "en_US")
build.setValue("format.textFont", "") # Will fall back to config value
build.setValue("format.textSize", 12)
build.setValue("format.lineHeight", 1.2)
build.setValue("format.justifyText", False)
@@ -577,8 +575,6 @@ def testBuildSettings_Format(monkeypatch, qtbot, nwGUI):
assert bSettings.toolStack.currentWidget() is fmtTab
# Check initial values
assert fmtTab.textFont.text() == textFont
assert fmtTab.textSize.value() == 12
assert fmtTab.lineHeight.value() == 1.2
assert fmtTab.justifyText.isChecked() is False
@@ -599,8 +595,9 @@ def testBuildSettings_Format(monkeypatch, qtbot, nwGUI):
assert fmtTab.rightMargin.value() == 15.0
# Change values
fmtTab.textFont.setText("Arial")
fmtTab.textSize.setValue(11)
testFont = QFont("Arial", 11)
fmtTab._textFont = testFont
fmtTab.textFont.setText(describeFont(testFont))
fmtTab.lineHeight.setValue(1.15)
fmtTab.justifyText.setChecked(True)
@@ -617,8 +614,7 @@ def testBuildSettings_Format(monkeypatch, qtbot, nwGUI):
# Save values
fmtTab.saveContent()
assert build.getStr("format.textFont") == "Arial"
assert build.getInt("format.textSize") == 11
assert build.getStr("format.textFont") == testFont.toString()
assert build.getFloat("format.lineHeight") == 1.15
assert build.getBool("format.justifyText") is True
@@ -643,11 +639,10 @@ def testBuildSettings_Format(monkeypatch, qtbot, nwGUI):
font = QFont()
font.setFamily("Times")
font.setPointSize(10)
mp.setattr(QFontDialog, "getFont", lambda *a: (font, True))
mp.setattr(QFontDialog, "getFont", lambda *a, **k: (font, True))
fmtTab.btnTextFont.click()
assert fmtTab.textFont.text() == "Times"
assert fmtTab.textSize.value() == 10
assert fmtTab._textFont == font
# Finish
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
@@ -677,13 +672,11 @@ def testBuildSettings_Output(qtbot, nwGUI):
assert outTab.odtPageCountOffset.value() == 0
assert outTab.htmlAddStyles.isChecked() is False
assert outTab.htmlPreserveTabs.isChecked() is False
assert outTab.mdPreserveBreaks.isChecked() is True
# Toggle all
outTab.odtAddColours.setChecked(True)
outTab.htmlAddStyles.setChecked(True)
outTab.htmlPreserveTabs.setChecked(True)
outTab.mdPreserveBreaks.setChecked(False)
# Change Values
outTab.odtPageCountOffset.setValue(1)
@@ -697,7 +690,6 @@ def testBuildSettings_Output(qtbot, nwGUI):
assert build.getInt("odt.pageCountOffset") == 1
assert build.getBool("html.addStyles") is True
assert build.getBool("html.preserveTabs") is True
assert build.getBool("md.preserveBreaks") is False
# Reset header format
outTab.btnPageHeader.click()