From d42074f8ea50721980f87c75a55a40ae90b8f591 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:43:11 +0100 Subject: [PATCH] Extend HTML anchor to include handle --- novelwriter/core/docbuild.py | 1 + novelwriter/core/tohtml.py | 21 +++++++++++++++++++-- novelwriter/core/tokenizer.py | 4 ++-- novelwriter/gui/docviewer.py | 5 +++-- novelwriter/guimain.py | 2 +- tests/test_core/test_core_tokenizer.py | 4 ++-- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/novelwriter/core/docbuild.py b/novelwriter/core/docbuild.py index 534cdd6c..ce5afdd7 100644 --- a/novelwriter/core/docbuild.py +++ b/novelwriter/core/docbuild.py @@ -171,6 +171,7 @@ class NWBuildDocument: filtered = self._setupBuild(makeObj) makeObj.setPreview(self._preview) + makeObj.setLinkHeadings(self._preview) for i, tHandle in enumerate(self._queue): self._error = None if filtered.get(tHandle, (False, 0))[0]: diff --git a/novelwriter/core/tohtml.py b/novelwriter/core/tohtml.py index da2507bd..ed791223 100644 --- a/novelwriter/core/tohtml.py +++ b/novelwriter/core/tohtml.py @@ -55,6 +55,7 @@ class ToHtml(Tokenizer): self._genMode = self.M_EXPORT self._cssStyles = True self._fullHTML: list[str] = [] + self._navMap: dict[str, str] = {} # Internals self._trMap = {} @@ -70,6 +71,10 @@ class ToHtml(Tokenizer): def fullHTML(self) -> list[str]: return self._fullHTML + @property + def navigationMap(self) -> dict[str, str]: + return self._navMap + ## # Setters ## @@ -227,9 +232,11 @@ class ToHtml(Tokenizer): else: hStyle = "" - if self._linkHeaders: - aNm = f"" + if self._linkHeadings and self._nwItem: + tHH = f"{self._nwItem.itemHandle}:T{nHead:04d}" + aNm = f"" else: + tHH = "" aNm = "" # Process Text Type @@ -249,22 +256,32 @@ class ToHtml(Tokenizer): elif tType == self.T_TITLE: tHead = tText.replace(nwHeadFmt.BR, "
") lines.append(f"

{aNm}{tHead}

\n") + if tHH: + self._navMap[tHH] = f"TT {tHead}" elif tType == self.T_HEAD1: tHead = tText.replace(nwHeadFmt.BR, "
") lines.append(f"<{h1}{h1Cl}{hStyle}>{aNm}{tHead}\n") + if tHH: + self._navMap[tHH] = f"H1 {tHead}" elif tType == self.T_HEAD2: tHead = tText.replace(nwHeadFmt.BR, "
") lines.append(f"<{h2}{hStyle}>{aNm}{tHead}\n") + if tHH: + self._navMap[tHH] = f"H2 {tHead}" elif tType == self.T_HEAD3: tHead = tText.replace(nwHeadFmt.BR, "
") lines.append(f"<{h3}{hStyle}>{aNm}{tHead}\n") + if tHH: + self._navMap[tHH] = f"H3 {tHead}" elif tType == self.T_HEAD4: tHead = tText.replace(nwHeadFmt.BR, "
") lines.append(f"<{h4}{hStyle}>{aNm}{tHead}\n") + if tHH: + self._navMap[tHH] = f"H4 {tHead}" elif tType == self.T_SEP: lines.append(f"

{tText}

\n") diff --git a/novelwriter/core/tokenizer.py b/novelwriter/core/tokenizer.py index ac44471c..15de37be 100644 --- a/novelwriter/core/tokenizer.py +++ b/novelwriter/core/tokenizer.py @@ -165,7 +165,7 @@ class Tokenizer(ABC): self._hideHScene = False # Do not include hard scene headings self._hideSection = False # Do not include section headings - self._linkHeaders = False # Add an anchor before headings + self._linkHeadings = False # Add an anchor before headings self._titleStyle = self.A_CENTRE | self.A_PBB self._chapterStyle = self.A_PBB @@ -353,7 +353,7 @@ class Tokenizer(ABC): def setLinkHeadings(self, state: bool) -> None: """Enable or disable adding an anchor before headings.""" - self._linkHeaders = state + self._linkHeadings = state return def setBodyText(self, state: bool) -> None: diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 701edafd..ac123ab9 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -732,7 +732,8 @@ class GuiDocViewHeader(QWidget): def setOutline(self, data: dict[int, tuple[str, int]]) -> None: """Set the document outline dataset.""" - if data != self._docOutline: + tHandle = self._docHandle + if data != self._docOutline and tHandle: self.outlineMenu.clear() entries = [] minLevel = 5 @@ -744,7 +745,7 @@ class GuiDocViewHeader(QWidget): indent = " "*(level - minLevel) action = self.outlineMenu.addAction(f"{indent}{text}") action.triggered.connect( - lambda _, title=title: self.docViewer.navigateTo(f"#{title}") + lambda _, title=title: self.docViewer.navigateTo(f"#{tHandle}:{title}") ) self._docOutline = data return diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index baf881c7..21db48b6 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -653,7 +653,7 @@ class GuiMain(QMainWindow): self.docEditor.ensureCursorVisibleNoCentre() if sTitle: - self.docViewer.navigateTo(f"#{sTitle}") + self.docViewer.navigateTo(f"#{tHandle}:{sTitle}") return True diff --git a/tests/test_core/test_core_tokenizer.py b/tests/test_core/test_core_tokenizer.py index b3b69774..30558c9c 100644 --- a/tests/test_core/test_core_tokenizer.py +++ b/tests/test_core/test_core_tokenizer.py @@ -68,7 +68,7 @@ def testCoreToken_Setters(mockGUI): assert tokens._hideScene is False assert tokens._hideHScene is False assert tokens._hideSection is False - assert tokens._linkHeaders is False + assert tokens._linkHeadings is False assert tokens._doBodyText is True assert tokens._doSynopsis is False assert tokens._doComments is False @@ -124,7 +124,7 @@ def testCoreToken_Setters(mockGUI): assert tokens._hideScene is True assert tokens._hideHScene is True assert tokens._hideSection is True - assert tokens._linkHeaders is True + assert tokens._linkHeadings is True assert tokens._doBodyText is False assert tokens._doSynopsis is True assert tokens._doComments is True