Switch Tokenizer to use QFont instead of font family and size

This commit is contained in:
Veronica Berglyd Olsen
2024-05-22 16:57:50 +02:00
parent c63a0c2f58
commit 7e1f1a725c
8 changed files with 81 additions and 73 deletions
+2 -4
View File
@@ -76,8 +76,7 @@ SETTINGS_TEMPLATE = {
"text.includeBodyText": (bool, True), "text.includeBodyText": (bool, True),
"text.ignoredKeywords": (str, ""), "text.ignoredKeywords": (str, ""),
"text.addNoteHeadings": (bool, True), "text.addNoteHeadings": (bool, True),
"format.textFont": (str, CONFIG.textFont.family()), "format.textFont": (str, CONFIG.textFont.toString()),
"format.textSize": (int, 12),
"format.lineHeight": (float, 1.15, 0.75, 3.0), "format.lineHeight": (float, 1.15, 0.75, 3.0),
"format.justifyText": (bool, False), "format.justifyText": (bool, False),
"format.stripUnicode": (bool, False), "format.stripUnicode": (bool, False),
@@ -125,8 +124,7 @@ SETTINGS_LABELS = {
"text.addNoteHeadings": QT_TRANSLATE_NOOP("Builds", "Add Titles for Notes"), "text.addNoteHeadings": QT_TRANSLATE_NOOP("Builds", "Add Titles for Notes"),
"format.grpFormat": QT_TRANSLATE_NOOP("Builds", "Text Format"), "format.grpFormat": QT_TRANSLATE_NOOP("Builds", "Text Format"),
"format.textFont": QT_TRANSLATE_NOOP("Builds", "Font Family"), "format.textFont": QT_TRANSLATE_NOOP("Builds", "Text Font"),
"format.textSize": QT_TRANSLATE_NOOP("Builds", "Font Size"),
"format.lineHeight": QT_TRANSLATE_NOOP("Builds", "Line Height"), "format.lineHeight": QT_TRANSLATE_NOOP("Builds", "Line Height"),
"format.grpOptions": QT_TRANSLATE_NOOP("Builds", "Text Options"), "format.grpOptions": QT_TRANSLATE_NOOP("Builds", "Text Options"),
"format.justifyText": QT_TRANSLATE_NOOP("Builds", "Justify Text Margins"), "format.justifyText": QT_TRANSLATE_NOOP("Builds", "Justify Text Margins"),
+4 -9
View File
@@ -28,7 +28,7 @@ import logging
from collections.abc import Iterable from collections.abc import Iterable
from pathlib import Path from pathlib import Path
from PyQt5.QtGui import QFont, QFontInfo from PyQt5.QtGui import QFont
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.constants import nwLabels from novelwriter.constants import nwLabels
@@ -279,13 +279,9 @@ class NWBuildDocument:
def _setupBuild(self, bldObj: Tokenizer) -> dict: def _setupBuild(self, bldObj: Tokenizer) -> dict:
"""Configure the build object.""" """Configure the build object."""
# Get Settings # Get Settings
textFont = self._build.getStr("format.textFont") textFont = QFont(CONFIG.textFont)
textSize = self._build.getInt("format.textSize") textFont.fromString(self._build.getStr("format.textFont"))
bldObj.setFont(textFont)
fontFamily = textFont or CONFIG.textFont.family()
bldFont = QFont(fontFamily, textSize)
fontInfo = QFontInfo(bldFont)
textFixed = fontInfo.fixedPitch()
bldObj.setTitleFormat( bldObj.setTitleFormat(
self._build.getStr("headings.fmtTitle"), self._build.getStr("headings.fmtTitle"),
@@ -324,7 +320,6 @@ class NWBuildDocument:
self._build.getBool("headings.breakScene") self._build.getBool("headings.breakScene")
) )
bldObj.setFont(fontFamily, textSize, textFixed)
bldObj.setJustify(self._build.getBool("format.justifyText")) bldObj.setJustify(self._build.getBool("format.justifyText"))
bldObj.setLineHeight(self._build.getFloat("format.lineHeight")) bldObj.setLineHeight(self._build.getFloat("format.lineHeight"))
bldObj.setKeepLineBreaks(self._build.getBool("format.keepBreaks")) bldObj.setKeepLineBreaks(self._build.getBool("format.keepBreaks"))
+5 -7
View File
@@ -34,7 +34,9 @@ from pathlib import Path
from time import time from time import time
from PyQt5.QtCore import QCoreApplication, QRegularExpression from PyQt5.QtCore import QCoreApplication, QRegularExpression
from PyQt5.QtGui import QFont
from novelwriter import CONFIG
from novelwriter.common import checkInt, formatTimeStamp, numberToRoman from novelwriter.common import checkInt, formatTimeStamp, numberToRoman
from novelwriter.constants import ( from novelwriter.constants import (
nwHeadFmt, nwKeyWords, nwLabels, nwRegEx, nwShortcode, nwUnicode, trConst nwHeadFmt, nwKeyWords, nwLabels, nwRegEx, nwShortcode, nwUnicode, trConst
@@ -139,9 +141,7 @@ class Tokenizer(ABC):
self._markdown: list[str] = [] self._markdown: list[str] = []
# User Settings # User Settings
self._textFont = "Serif" # Output text font self._textFont = CONFIG.textFont # Output text font
self._textSize = 11 # Output text size
self._textFixed = False # Fixed width text
self._lineHeight = 1.15 # Line height in units of em self._lineHeight = 1.15 # Line height in units of em
self._blockIndent = 4.00 # Block indent in units of em self._blockIndent = 4.00 # Block indent in units of em
self._firstIndent = False # Enable first line indent self._firstIndent = False # Enable first line indent
@@ -315,11 +315,9 @@ class Tokenizer(ABC):
) )
return return
def setFont(self, family: str, size: int, isFixed: bool = False) -> None: def setFont(self, font: QFont) -> None:
"""Set the build font.""" """Set the build font."""
self._textFont = family self._textFont = font
self._textSize = round(int(size))
self._textFixed = isFixed
return return
def setLineHeight(self, height: float) -> None: def setLineHeight(self, height: float) -> None:
+6 -6
View File
@@ -183,7 +183,7 @@ class GuiPreferences(QDialog):
self.guiFont.setMinimumWidth(fontWidth) self.guiFont.setMinimumWidth(fontWidth)
self.guiFont.setText(describeFont(self._guiFont)) self.guiFont.setText(describeFont(self._guiFont))
self.guiFont.setCursorPosition(0) self.guiFont.setCursorPosition(0)
self.guiFontButton = NIconToolButton(self, iSz, "more") self.guiFontButton = NIconToolButton(self, iSz, "font")
self.guiFontButton.clicked.connect(self._selectGuiFont) self.guiFontButton.clicked.connect(self._selectGuiFont)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Application font"), self.guiFont, self.tr("Application font"), self.guiFont,
@@ -233,7 +233,7 @@ class GuiPreferences(QDialog):
self.textFont.setMinimumWidth(fontWidth) self.textFont.setMinimumWidth(fontWidth)
self.textFont.setText(describeFont(CONFIG.textFont)) self.textFont.setText(describeFont(CONFIG.textFont))
self.textFont.setCursorPosition(0) self.textFont.setCursorPosition(0)
self.textFontButton = NIconToolButton(self, iSz, "more") self.textFontButton = NIconToolButton(self, iSz, "font")
self.textFontButton.clicked.connect(self._selectTextFont) self.textFontButton.clicked.connect(self._selectTextFont)
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Document font"), self.textFont, self.tr("Document font"), self.textFont,
@@ -695,7 +695,7 @@ class GuiPreferences(QDialog):
self.quoteSym["SO"].setFixedWidth(boxFixed) self.quoteSym["SO"].setFixedWidth(boxFixed)
self.quoteSym["SO"].setAlignment(QtAlignCenter) self.quoteSym["SO"].setAlignment(QtAlignCenter)
self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen) 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.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO"))
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Single quote open style"), self.quoteSym["SO"], self.tr("Single quote open style"), self.quoteSym["SO"],
@@ -709,7 +709,7 @@ class GuiPreferences(QDialog):
self.quoteSym["SC"].setFixedWidth(boxFixed) self.quoteSym["SC"].setFixedWidth(boxFixed)
self.quoteSym["SC"].setAlignment(QtAlignCenter) self.quoteSym["SC"].setAlignment(QtAlignCenter)
self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose) 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.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC"))
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Single quote close style"), self.quoteSym["SC"], self.tr("Single quote close style"), self.quoteSym["SC"],
@@ -724,7 +724,7 @@ class GuiPreferences(QDialog):
self.quoteSym["DO"].setFixedWidth(boxFixed) self.quoteSym["DO"].setFixedWidth(boxFixed)
self.quoteSym["DO"].setAlignment(QtAlignCenter) self.quoteSym["DO"].setAlignment(QtAlignCenter)
self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen) 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.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO"))
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Double quote open style"), self.quoteSym["DO"], self.tr("Double quote open style"), self.quoteSym["DO"],
@@ -738,7 +738,7 @@ class GuiPreferences(QDialog):
self.quoteSym["DC"].setFixedWidth(boxFixed) self.quoteSym["DC"].setFixedWidth(boxFixed)
self.quoteSym["DC"].setAlignment(QtAlignCenter) self.quoteSym["DC"].setAlignment(QtAlignCenter)
self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose) 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.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC"))
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Double quote close style"), self.quoteSym["DC"], self.tr("Double quote close style"), self.quoteSym["DC"],
+10 -14
View File
@@ -31,7 +31,7 @@ from time import time
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot 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.QtPrintSupport import QPrinter, QPrintPreviewDialog
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout, QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
@@ -404,10 +404,10 @@ class GuiManuscript(NToolDialog):
"""Update the preview widget and set relevant values.""" """Update the preview widget and set relevant values."""
self.docPreview.setContent(data) self.docPreview.setContent(data)
self.docPreview.setBuildName(build.name) self.docPreview.setBuildName(build.name)
self.docPreview.setTextFont(
build.getStr("format.textFont"), textFont = QFont()
build.getInt("format.textSize") textFont.fromString(build.getStr("format.textFont"))
) self.docPreview.setTextFont(textFont)
self.docPreview.setJustify( self.docPreview.setJustify(
build.getBool("format.justifyText") build.getBool("format.justifyText")
) )
@@ -787,7 +787,7 @@ class _PreviewWidget(QTextBrowser):
self._updateDocMargins() self._updateDocMargins()
self._updateBuildAge() self._updateBuildAge()
self.setTextFont(CONFIG.textFont.family(), CONFIG.textFont.pointSize()) self.setTextFont(CONFIG.textFont)
# Age Timer # Age Timer
self.ageTimer = QTimer(self) self.ageTimer = QTimer(self)
@@ -817,18 +817,14 @@ class _PreviewWidget(QTextBrowser):
self.document().setDefaultTextOption(pOptions) self.document().setDefaultTextOption(pOptions)
return 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. """Set the text font properties and then reset for sub-widgets.
This needs special attention since there appears to be a bug in This needs special attention since there appears to be a bug in
Qt 5.15.3. See issues #1862 and #1875. Qt 5.15.3. See issues #1862 and #1875.
""" """
if family and size > 4: self.setFont(font)
font = self.font() self.buildProgress.setFont(SHARED.theme.guiFont)
font.setFamily(family) self.ageLabel.setFont(SHARED.theme.guiFontSmall)
font.setPointSize(size)
self.setFont(font)
self.buildProgress.setFont(SHARED.theme.guiFont)
self.ageLabel.setFont(SHARED.theme.guiFontSmall)
return return
## ##
+15 -25
View File
@@ -37,6 +37,7 @@ from PyQt5.QtWidgets import (
) )
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import describeFont
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst
from novelwriter.core.buildsettings import BuildSettings, FilterMode from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.extensions.configlayout import ( from novelwriter.extensions.configlayout import (
@@ -1052,6 +1053,7 @@ class _FormatTab(NScrollableForm):
self._build = build self._build = build
self._unitScale = 1.0 self._unitScale = 1.0
self._textFont = QFont(CONFIG.textFont)
iPx = SHARED.theme.baseIconHeight iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize iSz = SHARED.theme.baseIconSize
@@ -1063,24 +1065,16 @@ class _FormatTab(NScrollableForm):
self.addGroupLabel(self._build.getLabel("format.grpFormat")) self.addGroupLabel(self._build.getLabel("format.grpFormat"))
# Font Family # Text Font
self.textFont = QLineEdit(self) self.textFont = QLineEdit(self)
self.textFont.setReadOnly(True) self.textFont.setReadOnly(True)
self.btnTextFont = NIconToolButton(self, iSz, "more") self.btnTextFont = NIconToolButton(self, iSz, "font")
self.btnTextFont.clicked.connect(self._selectFont) self.btnTextFont.clicked.connect(self._selectFont)
self.addRow( self.addRow(
self._build.getLabel("format.textFont"), self.textFont, 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 # Line Height
self.lineHeight = NDoubleSpinBox(self) self.lineHeight = NDoubleSpinBox(self)
self.lineHeight.setFixedWidth(spW) self.lineHeight.setFixedWidth(spW)
@@ -1175,14 +1169,13 @@ class _FormatTab(NScrollableForm):
def loadContent(self) -> None: def loadContent(self) -> None:
"""Populate the widgets.""" """Populate the widgets."""
textFont = self._build.getStr("format.textFont") self._textFont = QFont()
if not textFont: self._textFont.fromString(self._build.getStr("format.textFont"))
textFont = str(CONFIG.textFont.family())
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.lineHeight.setValue(self._build.getFloat("format.lineHeight"))
self.justifyText.setChecked(self._build.getBool("format.justifyText")) self.justifyText.setChecked(self._build.getBool("format.justifyText"))
self.stripUnicode.setChecked(self._build.getBool("format.stripUnicode")) self.stripUnicode.setChecked(self._build.getBool("format.stripUnicode"))
self.replaceTabs.setChecked(self._build.getBool("format.replaceTabs")) self.replaceTabs.setChecked(self._build.getBool("format.replaceTabs"))
@@ -1219,8 +1212,7 @@ class _FormatTab(NScrollableForm):
def saveContent(self) -> None: def saveContent(self) -> None:
"""Save choices back into build object.""" """Save choices back into build object."""
self._build.setValue("format.textFont", self.textFont.text()) self._build.setValue("format.textFont", self._textFont.toString())
self._build.setValue("format.textSize", self.textSize.value())
self._build.setValue("format.lineHeight", self.lineHeight.value()) self._build.setValue("format.lineHeight", self.lineHeight.value())
self._build.setValue("format.justifyText", self.justifyText.isChecked()) self._build.setValue("format.justifyText", self.justifyText.isChecked())
@@ -1249,13 +1241,11 @@ class _FormatTab(NScrollableForm):
@pyqtSlot() @pyqtSlot()
def _selectFont(self) -> None: def _selectFont(self) -> None:
"""Open the QFontDialog and set a font for the font style.""" """Open the QFontDialog and set a font for the font style."""
currFont = QFont() font, status = QFontDialog.getFont(self._textFont, self)
currFont.setFamily(self.textFont.text())
currFont.setPointSize(self.textSize.value())
newFont, status = QFontDialog.getFont(currFont, self)
if status: if status:
self.textFont.setText(newFont.family()) self.textFont.setText(describeFont(font))
self.textSize.setValue(newFont.pointSize()) self.textFont.setCursorPosition(0)
self._textFont = font
return return
@pyqtSlot(int) @pyqtSlot(int)
+34 -1
View File
@@ -24,7 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
from PyQt5.QtCore import QRegularExpression, Qt 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 from PyQt5.QtWidgets import QDialogButtonBox, QSizePolicy, QStyle
# Qt Alignment Flags # Qt Alignment Flags
@@ -105,3 +105,36 @@ QtSizeMinimumExpanding = QSizePolicy.Policy.MinimumExpanding
# Other # Other
QRegExUnicode = QRegularExpression.PatternOption.UseUnicodePropertiesOption 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_STRETCH: dict[int, str] = {
QFont.AnyStretch: "normal",
QFont.UltraCondensed: "ultra-condensed",
QFont.ExtraCondensed: "extra-condensed",
QFont.Condensed: "condensed",
QFont.SemiCondensed: "semi-condensed",
QFont.Unstretched: "normal",
QFont.SemiExpanded: "semi-expanded",
QFont.Expanded: "expanded",
QFont.ExtraExpanded: "extra-expanded",
QFont.UltraExpanded: "ultra-expanded",
}
FONT_STYLE: dict[int, str] = {
QFont.Style.StyleNormal: "normal",
QFont.Style.StyleItalic: "italic",
QFont.Style.StyleOblique: "oblique",
}
+5 -7
View File
@@ -24,6 +24,8 @@ import json
import pytest import pytest
from PyQt5.QtGui import QFont
from novelwriter.constants import nwHeadFmt from novelwriter.constants import nwHeadFmt
from novelwriter.core.project import NWProject from novelwriter.core.project import NWProject
from novelwriter.core.tokenizer import HeadingFormatter, Tokenizer, stripEscape from novelwriter.core.tokenizer import HeadingFormatter, Tokenizer, stripEscape
@@ -50,9 +52,7 @@ def testCoreToken_Setters(mockGUI):
assert tokens._fmtScene == nwHeadFmt.TITLE assert tokens._fmtScene == nwHeadFmt.TITLE
assert tokens._fmtHScene == nwHeadFmt.TITLE assert tokens._fmtHScene == nwHeadFmt.TITLE
assert tokens._fmtSection == nwHeadFmt.TITLE assert tokens._fmtSection == nwHeadFmt.TITLE
assert tokens._textFont == "Serif" assert tokens._textFont == QFont("Serif", 11)
assert tokens._textSize == 11
assert tokens._textFixed is False
assert tokens._lineHeight == 1.15 assert tokens._lineHeight == 1.15
assert tokens._blockIndent == 4.0 assert tokens._blockIndent == 4.0
assert tokens._doJustify is False assert tokens._doJustify is False
@@ -82,7 +82,7 @@ def testCoreToken_Setters(mockGUI):
tokens.setSceneFormat(f"S: {nwHeadFmt.TITLE}", True) tokens.setSceneFormat(f"S: {nwHeadFmt.TITLE}", True)
tokens.setHardSceneFormat(f"H: {nwHeadFmt.TITLE}", True) tokens.setHardSceneFormat(f"H: {nwHeadFmt.TITLE}", True)
tokens.setSectionFormat(f"X: {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.setLineHeight(2.0)
tokens.setBlockIndent(6.0) tokens.setBlockIndent(6.0)
tokens.setJustify(True) tokens.setJustify(True)
@@ -106,9 +106,7 @@ def testCoreToken_Setters(mockGUI):
assert tokens._fmtScene == f"S: {nwHeadFmt.TITLE}" assert tokens._fmtScene == f"S: {nwHeadFmt.TITLE}"
assert tokens._fmtHScene == f"H: {nwHeadFmt.TITLE}" assert tokens._fmtHScene == f"H: {nwHeadFmt.TITLE}"
assert tokens._fmtSection == f"X: {nwHeadFmt.TITLE}" assert tokens._fmtSection == f"X: {nwHeadFmt.TITLE}"
assert tokens._textFont == "Monospace" assert tokens._textFont == QFont("Monospace", 10)
assert tokens._textSize == 10
assert tokens._textFixed is True
assert tokens._lineHeight == 2.0 assert tokens._lineHeight == 2.0
assert tokens._blockIndent == 6.0 assert tokens._blockIndent == 6.0
assert tokens._doJustify is True assert tokens._doJustify is True