Distinguish between anchor ref and href in tokenizer

This commit is contained in:
Veronica Berglyd Olsen
2024-10-25 19:08:06 +02:00
parent 058758122c
commit d71435df53
7 changed files with 37 additions and 31 deletions
+6 -4
View File
@@ -87,10 +87,12 @@ class TextFmt(IntEnum):
COL_E = 16 # End colour COL_E = 16 # End colour
ANM_B = 17 # Begin anchor name ANM_B = 17 # Begin anchor name
ANM_E = 18 # End anchor name ANM_E = 18 # End anchor name
HRF_B = 19 # Begin href link ARF_B = 19 # Begin anchor link
HRF_E = 20 # End href link ARF_E = 20 # End anchor link
FNOTE = 21 # Footnote marker HRF_B = 21 # Begin href link
STRIP = 22 # Strip the format code HRF_E = 22 # End href link
FNOTE = 23 # Footnote marker
STRIP = 24 # Strip the format code
class BlockTyp(IntEnum): class BlockTyp(IntEnum):
+3 -1
View File
@@ -49,6 +49,7 @@ HTML_OPENER: dict[int, tuple[int, str]] = {
TextFmt.SUB_B: (TextFmt.SUB_E, "<sub>"), TextFmt.SUB_B: (TextFmt.SUB_E, "<sub>"),
TextFmt.COL_B: (TextFmt.COL_E, "<span style='color: {0}'>"), TextFmt.COL_B: (TextFmt.COL_E, "<span style='color: {0}'>"),
TextFmt.ANM_B: (TextFmt.ANM_E, "<a name='{0}'>"), TextFmt.ANM_B: (TextFmt.ANM_E, "<a name='{0}'>"),
TextFmt.ARF_B: (TextFmt.ARF_E, "<a href='{0}'>"),
TextFmt.HRF_B: (TextFmt.HRF_E, "<a href='{0}'>"), TextFmt.HRF_B: (TextFmt.HRF_E, "<a href='{0}'>"),
} }
@@ -63,6 +64,7 @@ HTML_CLOSER: dict[int, tuple[int, str]] = {
TextFmt.SUB_E: (TextFmt.SUB_B, "</sub>"), TextFmt.SUB_E: (TextFmt.SUB_B, "</sub>"),
TextFmt.COL_E: (TextFmt.COL_B, "</span>"), TextFmt.COL_E: (TextFmt.COL_B, "</span>"),
TextFmt.ANM_E: (TextFmt.ANM_B, "</a>"), TextFmt.ANM_E: (TextFmt.ANM_B, "</a>"),
TextFmt.ARF_E: (TextFmt.ARF_B, "</a>"),
TextFmt.HRF_E: (TextFmt.HRF_B, "</a>"), TextFmt.HRF_E: (TextFmt.HRF_B, "</a>"),
} }
@@ -398,7 +400,7 @@ class ToHtml(Tokenizer):
if not state.get(fmt, True): if not state.get(fmt, True):
if fmt == TextFmt.COL_B and (color := self._classes.get(data)): if fmt == TextFmt.COL_B and (color := self._classes.get(data)):
tags.append((pos, m[1].format(color.name(QtHexRgb)))) tags.append((pos, m[1].format(color.name(QtHexRgb))))
elif fmt in (TextFmt.ANM_B, TextFmt.HRF_B): elif fmt in (TextFmt.ANM_B, TextFmt.ARF_B, TextFmt.HRF_B):
tags.append((pos, m[1].format(data or "#"))) tags.append((pos, m[1].format(data or "#")))
else: else:
tags.append((pos, m[1])) tags.append((pos, m[1]))
+2 -2
View File
@@ -1089,8 +1089,8 @@ class Tokenizer(ABC):
for n, bit in enumerate(bits[1:], 2): for n, bit in enumerate(bits[1:], 2):
end = pos + len(bit) end = pos + len(bit)
fmt.append((pos, TextFmt.COL_B, "tag")) fmt.append((pos, TextFmt.COL_B, "tag"))
fmt.append((pos, TextFmt.HRF_B, f"#tag_{bit}".lower())) fmt.append((pos, TextFmt.ARF_B, f"#tag_{bit}".lower()))
fmt.append((end, TextFmt.HRF_E, "")) fmt.append((end, TextFmt.ARF_E, ""))
fmt.append((end, TextFmt.COL_E, "")) fmt.append((end, TextFmt.COL_E, ""))
txt.append(bit) txt.append(bit)
pos = end pos = end
+2 -2
View File
@@ -330,12 +330,12 @@ class ToQTextDocument(Tokenizer):
cFmt.setAnchorNames([data]) cFmt.setAnchorNames([data])
elif fmt == TextFmt.ANM_E: elif fmt == TextFmt.ANM_E:
cFmt.setAnchor(False) cFmt.setAnchor(False)
elif fmt == TextFmt.HRF_B: elif fmt in (TextFmt.HRF_B, TextFmt.ARF_B):
cFmt.setForeground(primary or self._theme.link) cFmt.setForeground(primary or self._theme.link)
cFmt.setFontUnderline(True) cFmt.setFontUnderline(True)
cFmt.setAnchor(True) cFmt.setAnchor(True)
cFmt.setAnchorHref(data) cFmt.setAnchorHref(data)
elif fmt == TextFmt.HRF_E: elif fmt in (TextFmt.HRF_E, TextFmt.ARF_E):
cFmt.setForeground(primary or self._theme.text) cFmt.setForeground(primary or self._theme.text)
cFmt.setFontUnderline(False) cFmt.setFontUnderline(False)
cFmt.setAnchor(False) cFmt.setAnchor(False)
+4 -2
View File
@@ -1,8 +1,8 @@
%%~name: Making a Scene %%~name: Making a Scene
%%~path: 6a2d6d5f4f401/636b6aa9b697b %%~path: 6a2d6d5f4f401/636b6aa9b697b
%%~kind: NOVEL/DOCUMENT %%~kind: NOVEL/DOCUMENT
%%~hash: 349d9ce3d59ad241d63b01380c53a7fb26ce9f19 %%~hash: 89d562ae05727028d74bd10cfd6953882d1cd140
%%~date: Unknown/2024-10-24 23:44:27 %%~date: Unknown/2024-10-25 12:41:02
### Making a Scene ### Making a Scene
@pov: Jane @pov: Jane
@@ -20,6 +20,8 @@ In addition, the editor supports automatic formatting of “quotes”, both doub
If you have the need for it, you can also add text that can be automatically replaced by other text when you generate a preview or export the project. Now, lets auto-replace this A with <A>, and this C with <C>. While <E> is just <E>. Press Ctrl+R to see what this looks like in the view pane. The list of auto-replaced text is set in Project Settings. If you have the need for it, you can also add text that can be automatically replaced by other text when you generate a preview or export the project. Now, lets auto-replace this A with <A>, and this C with <C>. While <E> is just <E>. Press Ctrl+R to see what this looks like in the view pane. The list of auto-replaced text is set in Project Settings.
You can also add URLs like http://www.example.com to the text.
The editor also supports non breaking spaces, and the spell checker accepts long dashes—like this—as valid word separators. Regular dashes are also supported and can be automatically inserted when typing two hyphens. The editor also supports non breaking spaces, and the spell checker accepts long dashes—like this—as valid word separators. Regular dashes are also supported and can be automatically inserted when typing two hyphens.
Thin spaces and thin non-breaking spaces are also supported from the Insert menu, and can be used to separate numbers from their units, like: 25kg.[footnote:f4xr5] Thin spaces and thin non-breaking spaces are also supported from the Insert menu, and can be used to separate numbers from their units, like: 25kg.[footnote:f4xr5]
+6 -6
View File
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="2.6a2" hexVersion="0x020600a2" fileVersion="1.5" fileRevision="4" timeStamp="2024-10-24 23:58:23"> <novelWriterXML appVersion="2.6a2" hexVersion="0x020600a2" fileVersion="1.5" fileRevision="4" timeStamp="2024-10-25 23:19:07">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="2088" autoCount="280" editTime="93793"> <project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="2122" autoCount="279" editTime="94855">
<name>Sample Project</name> <name>Sample Project</name>
<author>Jane Smith</author> <author>Jane Smith</author>
</project> </project>
@@ -36,7 +36,7 @@
<entry key="i56be10" count="1" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry> <entry key="i56be10" count="1" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance> </importance>
</settings> </settings>
<content items="31" novelWords="1004" notesWords="416"> <content items="31" novelWords="1014" notesWords="416">
<item handle="7031beac91f75" parent="None" root="7031beac91f75" order="0" type="ROOT" class="NOVEL"> <item handle="7031beac91f75" parent="None" root="7031beac91f75" order="0" type="ROOT" class="NOVEL">
<meta expanded="yes" /> <meta expanded="yes" />
<name status="sc24b8f" import="ia857f0">Novel</name> <name status="sc24b8f" import="ia857f0">Novel</name>
@@ -58,11 +58,11 @@
<name status="sf24ce6" import="ia857f0" active="yes">Chapter One</name> <name status="sf24ce6" import="ia857f0" active="yes">Chapter One</name>
</item> </item>
<item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT"> <item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="no" heading="H3" charCount="2937" wordCount="520" paraCount="15" cursorPos="19" /> <meta expanded="no" heading="H3" charCount="2999" wordCount="530" paraCount="16" cursorPos="1663" />
<name status="s90e6c9" import="ia857f0" active="yes">Making a Scene</name> <name status="s90e6c9" import="ia857f0" active="yes">Making a Scene</name>
</item> </item>
<item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT"> <item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="no" heading="H3" charCount="548" wordCount="108" paraCount="3" cursorPos="650" /> <meta expanded="no" heading="H3" charCount="548" wordCount="108" paraCount="3" cursorPos="691" />
<name status="s90e6c9" import="ia857f0" active="yes">Another Scene</name> <name status="s90e6c9" import="ia857f0" active="yes">Another Scene</name>
</item> </item>
<item handle="ba8a28a246524" parent="7031beac91f75" root="7031beac91f75" order="4" type="FILE" class="NOVEL" layout="DOCUMENT"> <item handle="ba8a28a246524" parent="7031beac91f75" root="7031beac91f75" order="4" type="FILE" class="NOVEL" layout="DOCUMENT">
@@ -102,7 +102,7 @@
<name status="sf12341" import="ia857f0">Main Characters</name> <name status="sf12341" import="ia857f0">Main Characters</name>
</item> </item>
<item handle="14298de4d9524" parent="f7e2d9f330615" root="f6622b4617424" order="0" type="FILE" class="CHARACTER" layout="NOTE"> <item handle="14298de4d9524" parent="f7e2d9f330615" root="f6622b4617424" order="0" type="FILE" class="CHARACTER" layout="NOTE">
<meta expanded="no" heading="H1" charCount="49" wordCount="9" paraCount="1" cursorPos="15" /> <meta expanded="no" heading="H1" charCount="49" wordCount="9" paraCount="1" cursorPos="23" />
<name status="sf12341" import="i2d7a54" active="yes">John Smith</name> <name status="sf12341" import="i2d7a54" active="yes">John Smith</name>
</item> </item>
<item handle="bb2c23b3c42cc" parent="f7e2d9f330615" root="f6622b4617424" order="1" type="FILE" class="CHARACTER" layout="NOTE"> <item handle="bb2c23b3c42cc" parent="f7e2d9f330615" root="f6622b4617424" order="1" type="FILE" class="CHARACTER" layout="NOTE">
+14 -14
View File
@@ -834,8 +834,8 @@ def testFmtToken_MetaFormat(mockGUI):
BlockTyp.KEYWORD, "char", "Characters: Bod", [ BlockTyp.KEYWORD, "char", "Characters: Bod", [
(0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"), (0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"),
(11, TextFmt.COL_E, ""), (11, TextFmt.B_E, ""), (11, TextFmt.COL_E, ""), (11, TextFmt.B_E, ""),
(12, TextFmt.COL_B, "tag"), (12, TextFmt.HRF_B, "#tag_bod"), (12, TextFmt.COL_B, "tag"), (12, TextFmt.ARF_B, "#tag_bod"),
(15, TextFmt.HRF_E, ""), (15, TextFmt.COL_E, ""), (15, TextFmt.ARF_E, ""), (15, TextFmt.COL_E, ""),
], BlockFmt.NONE ], BlockFmt.NONE
)] )]
assert tokens._raw[-1] == "@char: Bod\n\n" assert tokens._raw[-1] == "@char: Bod\n\n"
@@ -846,22 +846,22 @@ def testFmtToken_MetaFormat(mockGUI):
BlockTyp.KEYWORD, "pov", "Point of View: Bod", [ BlockTyp.KEYWORD, "pov", "Point of View: Bod", [
(0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"), (0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"),
(14, TextFmt.COL_E, ""), (14, TextFmt.B_E, ""), (14, TextFmt.COL_E, ""), (14, TextFmt.B_E, ""),
(15, TextFmt.COL_B, "tag"), (15, TextFmt.HRF_B, "#tag_bod"), (15, TextFmt.COL_B, "tag"), (15, TextFmt.ARF_B, "#tag_bod"),
(18, TextFmt.HRF_E, ""), (18, TextFmt.COL_E, ""), (18, TextFmt.ARF_E, ""), (18, TextFmt.COL_E, ""),
], BlockFmt.Z_BTM ], BlockFmt.Z_BTM
), ( ), (
BlockTyp.KEYWORD, "plot", "Plot: Main", [ BlockTyp.KEYWORD, "plot", "Plot: Main", [
(0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"), (0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"),
(5, TextFmt.COL_E, ""), (5, TextFmt.B_E, ""), (5, TextFmt.COL_E, ""), (5, TextFmt.B_E, ""),
(6, TextFmt.COL_B, "tag"), (6, TextFmt.HRF_B, "#tag_main"), (6, TextFmt.COL_B, "tag"), (6, TextFmt.ARF_B, "#tag_main"),
(10, TextFmt.HRF_E, ""), (10, TextFmt.COL_E, ""), (10, TextFmt.ARF_E, ""), (10, TextFmt.COL_E, ""),
], BlockFmt.Z_TOP | BlockFmt.Z_BTM ], BlockFmt.Z_TOP | BlockFmt.Z_BTM
), ( ), (
BlockTyp.KEYWORD, "location", "Locations: Europe", [ BlockTyp.KEYWORD, "location", "Locations: Europe", [
(0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"), (0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"),
(10, TextFmt.COL_E, ""), (10, TextFmt.B_E, ""), (10, TextFmt.COL_E, ""), (10, TextFmt.B_E, ""),
(11, TextFmt.COL_B, "tag"), (11, TextFmt.HRF_B, "#tag_europe"), (11, TextFmt.COL_B, "tag"), (11, TextFmt.ARF_B, "#tag_europe"),
(17, TextFmt.HRF_E, ""), (17, TextFmt.COL_E, ""), (17, TextFmt.ARF_E, ""), (17, TextFmt.COL_E, ""),
], BlockFmt.Z_TOP ], BlockFmt.Z_TOP
)] )]
assert tokens._raw[-1] == "@pov: Bod\n@plot: Main\n@location: Europe\n\n" assert tokens._raw[-1] == "@pov: Bod\n@plot: Main\n@location: Europe\n\n"
@@ -874,8 +874,8 @@ def testFmtToken_MetaFormat(mockGUI):
BlockTyp.KEYWORD, "pov", "Point of View: Bod", [ BlockTyp.KEYWORD, "pov", "Point of View: Bod", [
(0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"), (0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"),
(14, TextFmt.COL_E, ""), (14, TextFmt.B_E, ""), (14, TextFmt.COL_E, ""), (14, TextFmt.B_E, ""),
(15, TextFmt.COL_B, "tag"), (15, TextFmt.HRF_B, "#tag_bod"), (15, TextFmt.COL_B, "tag"), (15, TextFmt.ARF_B, "#tag_bod"),
(18, TextFmt.HRF_E, ""), (18, TextFmt.COL_E, ""), (18, TextFmt.ARF_E, ""), (18, TextFmt.COL_E, ""),
], BlockFmt.NONE ], BlockFmt.NONE
)] )]
@@ -1831,10 +1831,10 @@ def testFmtToken_FormatMeta(mockGUI):
"@char", "Characters: Jane, John", [ "@char", "Characters: Jane, John", [
(0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"), (0, TextFmt.B_B, ""), (0, TextFmt.COL_B, "keyword"),
(11, TextFmt.COL_E, ""), (11, TextFmt.B_E, ""), (11, TextFmt.COL_E, ""), (11, TextFmt.B_E, ""),
(12, TextFmt.COL_B, "tag"), (12, TextFmt.HRF_B, "#tag_jane"), (12, TextFmt.COL_B, "tag"), (12, TextFmt.ARF_B, "#tag_jane"),
(16, TextFmt.HRF_E, ""), (16, TextFmt.COL_E, ""), (16, TextFmt.ARF_E, ""), (16, TextFmt.COL_E, ""),
(18, TextFmt.COL_B, "tag"), (18, TextFmt.HRF_B, "#tag_john"), (18, TextFmt.COL_B, "tag"), (18, TextFmt.ARF_B, "#tag_john"),
(22, TextFmt.HRF_E, ""), (22, TextFmt.COL_E, ""), (22, TextFmt.ARF_E, ""), (22, TextFmt.COL_E, ""),
] ]
) )