Display headings with a line break on a single line

This commit is contained in:
Veronica Berglyd Olsen
2025-06-18 19:26:41 +02:00
parent 2176dd2020
commit 92ef020342
6 changed files with 68 additions and 68 deletions
+2 -2
View File
@@ -44,7 +44,7 @@ from novelwriter.common import (
NWConfigParser, checkInt, checkPath, describeFont, fontMatcher,
formatTimeStamp, processDialogSymbols, simplified
)
from novelwriter.constants import nwFiles, nwHtmlUnicode, nwQuotes, nwUnicode
from novelwriter.constants import nwFiles, nwQuotes, nwUnicode
from novelwriter.error import formatException, logException
if TYPE_CHECKING:
@@ -892,7 +892,7 @@ class Config:
"""
self.splashMessage(f"Initialising {kind} font: {font.family()}")
metrics = QFontMetrics(font)
for char in nwHtmlUnicode.U_TO_H.keys():
for char in nwUnicode.UI_SYMBOLS:
if not metrics.inFont(char): # type: ignore
logger.warning("No glyph U+%04x in font", ord(char)) # pragma: no cover
return
+12 -19
View File
@@ -586,21 +586,14 @@ class nwUnicode:
U_TIMES = "\u00d7" # Multiplication sign
U_DIVIDE = "\u00f7" # Division sign
# Arrows
U_UTRI = "\u25b2" # Up-pointing triangle
U_UTRIS = "\u25b4" # Up-pointing triangle, small
U_RTRI = "\u25b6" # Right-pointing triangle
U_RTRIS = "\u25b8" # Right-pointing triangle, small
U_DTRI = "\u25bc" # Down-pointing triangle
U_DTRIS = "\u25be" # Down-pointing triangle, small
U_LTRI = "\u25c0" # Left-pointing triangle
U_LTRIS = "\u25c2" # Left-pointing triangle, small
# Special
U_UNKN = "\ufffd" # Unknown character
U_NAC1 = "\ufffe" # Not a character
U_NAC2 = "\uffff" # Not a character
# Placeholders
U_LBREAK = "\u21b2" # Downwards Arrow With Tip Leftwards
# HTML Equivalents
# ================
@@ -655,15 +648,15 @@ class nwUnicode:
H_TIMES = "×"
H_DIVIDE = "÷"
# Arrows
H_UTRI = "▲"
H_UTRIS = "▴"
H_RTRI = "▶"
H_RTRIS = "▸"
H_DTRI = "▼"
H_DTRIS = "▾"
H_LTRI = "◀"
H_LTRIS = "◂"
# Unicode symbols expected to be used on the UI
UI_SYMBOLS: Final[list[str]] = [
U_QUOT, U_APOS, U_LAQUO, U_RAQUO, U_LSQUO, U_RSQUO, U_SBQUO, U_SUQUO,
U_LDQUO, U_RDQUO, U_BDQUO, U_UDQUO, U_LSAQUO, U_RSAQUO, U_BDRQUO,
U_LCQUO, U_RCQUO, U_LWCQUO, U_RWCQUO, U_FGDASH, U_ENDASH, U_EMDASH,
U_HBAR, U_HELLIP, U_MAPOS, U_PRIME, U_DPRIME, U_NBSP, U_THSP, U_THNBSP,
U_ENSP, U_EMSP, U_MMSP, U_CHECK, U_CROSS, U_BULL, U_TRBULL, U_HYBULL,
U_FLOWER, U_PERMIL, U_DEGREE, U_MINUS, U_TIMES, U_DIVIDE, U_LBREAK,
]
class nwHtmlUnicode:
+23 -17
View File
@@ -1168,12 +1168,18 @@ class Tokenizer(ABC):
class HeadingFormatter:
def __init__(self, project: NWProject) -> None:
def __init__(
self,
project: NWProject,
chapter: int = 0,
scene: int = 0,
absolute: int = 0,
) -> None:
self._project = project
self._handle = None
self._chCount = 0
self._scChCount = 0
self._scAbsCount = 0
self._chapter = chapter
self._scene = scene
self._absolute = absolute
return
def setHandle(self, tHandle: str | None) -> None:
@@ -1183,42 +1189,42 @@ class HeadingFormatter:
def incChapter(self) -> None:
"""Increment the chapter counter."""
self._chCount += 1
self._chapter += 1
return
def incScene(self) -> None:
"""Increment the scene counters."""
self._scChCount += 1
self._scAbsCount += 1
self._scene += 1
self._absolute += 1
return
def resetAll(self) -> None:
"""Reset all counters."""
self._chCount = 0
self._scChCount = 0
self._scAbsCount = 0
self._chapter = 0
self._scene = 0
self._absolute = 0
return
def resetScene(self) -> None:
"""Reset the chapter scene counter."""
self._scChCount = 0
self._scene = 0
return
def apply(self, hFormat: str, text: str, nHead: int) -> str:
"""Apply formatting to a specific heading."""
hFormat = hFormat.replace(nwHeadFmt.TITLE, text)
hFormat = hFormat.replace(nwHeadFmt.BR, "\n")
hFormat = hFormat.replace(nwHeadFmt.CH_NUM, str(self._chCount))
hFormat = hFormat.replace(nwHeadFmt.SC_NUM, str(self._scChCount))
hFormat = hFormat.replace(nwHeadFmt.SC_ABS, str(self._scAbsCount))
hFormat = hFormat.replace(nwHeadFmt.CH_NUM, str(self._chapter))
hFormat = hFormat.replace(nwHeadFmt.SC_NUM, str(self._scene))
hFormat = hFormat.replace(nwHeadFmt.SC_ABS, str(self._absolute))
if nwHeadFmt.CH_WORD in hFormat:
chWord = self._project.localLookup(self._chCount)
chWord = self._project.localLookup(self._chapter)
hFormat = hFormat.replace(nwHeadFmt.CH_WORD, chWord)
if nwHeadFmt.CH_ROML in hFormat:
chRom = numberToRoman(self._chCount, toLower=True)
chRom = numberToRoman(self._chapter, toLower=True)
hFormat = hFormat.replace(nwHeadFmt.CH_ROML, chRom)
if nwHeadFmt.CH_ROMU in hFormat:
chRom = numberToRoman(self._chCount, toLower=False)
chRom = numberToRoman(self._chapter, toLower=False)
hFormat = hFormat.replace(nwHeadFmt.CH_ROMU, chRom)
if nwHeadFmt.CHAR_POV in hFormat or nwHeadFmt.CHAR_FOCUS in hFormat:
+4 -7
View File
@@ -43,7 +43,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED
from novelwriter.common import fuzzyTime, qtLambda
from novelwriter.constants import nwLabels, nwStats, trStats
from novelwriter.constants import nwHeadFmt, nwLabels, nwStats, nwUnicode, trStats
from novelwriter.core.buildsettings import BuildCollection, BuildSettings
from novelwriter.core.docbuild import NWBuildDocument
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
@@ -595,11 +595,7 @@ class _DetailsWidget(QWidget):
item.addChild(sub)
# Headings
hFmt = HeadingFormatter(SHARED.project)
hFmt.incChapter()
hFmt.incScene()
hFmt.resetScene()
hFmt.incScene()
hFmt = HeadingFormatter(SHARED.project, 7, 5, 23)
title = self.tr("Title")
hidden = self.tr("Hidden")
@@ -620,7 +616,8 @@ class _DetailsWidget(QWidget):
if build.getBool(hHide):
sub.setText(1, f"[{hidden}]")
else:
sub.setText(1, hFmt.apply(build.getStr(hFormat), title, 0))
preview = build.getStr(hFormat).replace(nwHeadFmt.BR, nwUnicode.U_LBREAK)
sub.setText(1, hFmt.apply(preview, title, 0))
item.addChild(sub)
# Text Content
+19 -15
View File
@@ -38,7 +38,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED
from novelwriter.common import describeFont, fontMatcher, qtAddAction, qtLambda
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwUnicode, trConst
from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.extensions.configlayout import (
NColorLabel, NFixedPage, NScrollableForm, NScrollablePage
@@ -795,12 +795,15 @@ class _HeadingsTab(NScrollablePage):
def loadContent(self) -> None:
"""Populate the widgets."""
self.fmtPart.setText(self._build.getStr("headings.fmtPart"))
self.fmtChapter.setText(self._build.getStr("headings.fmtChapter"))
self.fmtUnnumbered.setText(self._build.getStr("headings.fmtUnnumbered"))
self.fmtScene.setText(self._build.getStr("headings.fmtScene"))
self.fmtAScene.setText(self._build.getStr("headings.fmtAltScene"))
self.fmtSection.setText(self._build.getStr("headings.fmtSection"))
def fmtBreak(text: str) -> str:
return text.replace(nwHeadFmt.BR, nwUnicode.U_LBREAK)
self.fmtPart.setText(fmtBreak(self._build.getStr("headings.fmtPart")))
self.fmtChapter.setText(fmtBreak(self._build.getStr("headings.fmtChapter")))
self.fmtUnnumbered.setText(fmtBreak(self._build.getStr("headings.fmtUnnumbered")))
self.fmtScene.setText(fmtBreak(self._build.getStr("headings.fmtScene")))
self.fmtAScene.setText(fmtBreak(self._build.getStr("headings.fmtAltScene")))
self.fmtSection.setText(fmtBreak(self._build.getStr("headings.fmtSection")))
self.swtPart.setChecked(self._build.getBool("headings.hidePart"))
self.swtChapter.setChecked(self._build.getBool("headings.hideChapter"))
@@ -880,7 +883,7 @@ class _HeadingsTab(NScrollablePage):
text = ""
label = self.tr("None")
self.editTextBox.setPlainText(text.replace(nwHeadFmt.BR, "\n"))
self.editTextBox.setPlainText(text.replace(nwUnicode.U_LBREAK, "\n"))
self.lblEditForm.setText(self.tr("Editing: {0}").format(label))
return
@@ -893,25 +896,26 @@ class _HeadingsTab(NScrollablePage):
def _saveFormat(self) -> None:
"""Save the format from the edit text box."""
heading = self._editing
text = self.editTextBox.toPlainText().strip().replace("\n", nwHeadFmt.BR)
text = self.editTextBox.toPlainText().strip().replace("\n", nwUnicode.U_LBREAK)
value = text.replace(nwUnicode.U_LBREAK, nwHeadFmt.BR)
if heading == self.EDIT_TITLE:
self.fmtPart.setText(text)
self._build.setValue("headings.fmtPart", text)
self._build.setValue("headings.fmtPart", value)
elif heading == self.EDIT_CHAPTER:
self.fmtChapter.setText(text)
self._build.setValue("headings.fmtChapter", text)
self._build.setValue("headings.fmtChapter", value)
elif heading == self.EDIT_UNNUM:
self.fmtUnnumbered.setText(text)
self._build.setValue("headings.fmtUnnumbered", text)
self._build.setValue("headings.fmtUnnumbered", value)
elif heading == self.EDIT_SCENE:
self.fmtScene.setText(text)
self._build.setValue("headings.fmtScene", text)
self._build.setValue("headings.fmtScene", value)
elif heading == self.EDIT_HSCENE:
self.fmtAScene.setText(text)
self._build.setValue("headings.fmtAltScene", text)
self._build.setValue("headings.fmtAltScene", value)
elif heading == self.EDIT_SECTION:
self.fmtSection.setText(text)
self._build.setValue("headings.fmtSection", text)
self._build.setValue("headings.fmtSection", value)
else:
return