Skip to content

Commit c36cd2e

Browse files
committed
⚡ Improve the detection of headings
Closes #27.
1 parent 767990b commit c36cd2e

3 files changed

Lines changed: 30 additions & 9 deletions

File tree

ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
([#24](https://github.com/davep/rogallo/pull/24))
1111
- Improved the detection of links.
1212
([#26](https://github.com/davep/rogallo/pull/26))
13+
- Improved the detection of headings.
14+
([#29](https://github.com/davep/rogallo/pull/29))
1315

1416
## v0.1.0
1517

src/rogallo/gemtext/parser.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# Python imports.
55
from collections.abc import Iterator
66
from functools import cached_property
7+
from typing import Final
78

89

910
##############################################################################
@@ -90,6 +91,17 @@ def uri(self) -> str:
9091
return self._uri
9192

9293

94+
##############################################################################
95+
_LINK: Final[str] = "=>"
96+
"""Marker for a link in Gemtext."""
97+
_H1: Final[str] = "#"
98+
"""Marker for a level 1 heading in Gemtext."""
99+
_H2: Final[str] = "##"
100+
"""Marker for a level 2 heading in Gemtext."""
101+
_H3: Final[str] = "###"
102+
"""Marker for a level 3 heading in Gemtext."""
103+
104+
93105
##############################################################################
94106
class Gemtext:
95107
"""A Gemtext parser."""
@@ -118,14 +130,17 @@ def _parse(self) -> Iterator[Line]:
118130
preformat_content = []
119131
elif in_preformat:
120132
preformat_content.append(line)
121-
elif line.startswith("=>"):
122-
parts = line.removeprefix("=>").strip().split(maxsplit=1)
133+
elif line.startswith(_LINK):
134+
parts = line.removeprefix(_LINK).strip().split(maxsplit=1)
123135
yield Link(parts[0], parts[1] if len(parts) > 1 else "")
124136
elif line.startswith("> "):
125137
yield Quote(line.removeprefix("> ").strip())
126-
elif line.startswith(("# ", "## ", "### ")):
127-
marker, _, heading_text = line.partition(" ")
128-
yield Heading(heading_text.strip(), len(marker.strip()))
138+
elif line.startswith(_H3):
139+
yield Heading(line.removeprefix(_H3).strip(), 3)
140+
elif line.startswith(_H2):
141+
yield Heading(line.removeprefix(_H2).strip(), 2)
142+
elif line.startswith(_H1):
143+
yield Heading(line.removeprefix(_H1).strip(), 1)
129144
elif line.startswith("* "):
130145
yield ListItem(line.removeprefix("* ").strip())
131146
else:

tests/unit/test_gemtext.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ def test_str_gemtext() -> None:
4242
(">Not a quote", ">Not a quote"),
4343
(">> Not a quote", ">> Not a quote"),
4444
(" # Not a header", " # Not a header"),
45-
("#Not a header", "#Not a header"),
46-
("##Not a header", "##Not a header"),
47-
("###Not a header", "###Not a header"),
48-
("#### Header 4", "#### Header 4"),
4945
("*Not a list item", "*Not a list item"),
5046
("** Not a list item", "** Not a list item"),
5147
(" * Not a list item", " * Not a list item"),
@@ -70,9 +66,17 @@ def test_parse_paragraph(gemtext: str, expected_text: str) -> None:
7066
("# Header 1", 1, "Header 1"),
7167
("## Header 2", 2, "Header 2"),
7268
("### Header 3", 3, "Header 3"),
69+
("#\tHeader 1", 1, "Header 1"),
70+
("##\tHeader 2", 2, "Header 2"),
71+
("###\tHeader 3", 3, "Header 3"),
72+
("# \tHeader 1", 1, "Header 1"),
73+
("## \tHeader 2", 2, "Header 2"),
74+
("### \tHeader 3", 3, "Header 3"),
7375
("# # Header 1", 1, "# Header 1"),
7476
("## ## Header 2", 2, "## Header 2"),
7577
("### ### Header 3", 3, "### Header 3"),
78+
("#### Header 3", 3, "# Header 3"),
79+
("####Header 3", 3, "#Header 3"),
7680
],
7781
)
7882
def test_parse_header(gemtext: str, expected_level: int, expected_content: str) -> None:

0 commit comments

Comments
 (0)