Skip to content

Commit 81a6cd6

Browse files
committed
🛠️ fix(parser): keep inline markers and ref link variants
1 parent 2c8cc22 commit 81a6cd6

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

sdiff/parser.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@
1111

1212
_BLOCK_TAGS = {tag.lower() for tag in block_parser.BLOCK_TAGS}
1313
_HEADING_LINE_RE = re.compile(r'^(\s*)(#{1,6})(?!#)(?=\S)')
14-
_REF_LINK_OR_IMAGE_RE = re.compile(r'!?\[[^\]]+\]\[[^\]]+\]')
14+
_REF_LINK_OR_IMAGE_RE = re.compile(r'!?\[[^\]]+\]\s*\[[^\]]*\]')
1515
_REF_DEF_LINE_RE = re.compile(r'^\s{0,3}\[[^\]]+\]:\s+\S+')
1616
_FENCE_RE = re.compile(r'^\s*(```|~~~)')
17+
_INLINE_MARKERS = {
18+
'strong': '**',
19+
'emphasis': '*',
20+
'strikethrough': '~~',
21+
}
1722

1823

1924
class MdParser:
@@ -134,6 +139,14 @@ def flush_buffer():
134139
url = attrs.get('url', '')
135140
title = attrs.get('title')
136141
nodes.append(Image(_format_image_markup(alt, url, title)))
142+
elif token_type in _INLINE_MARKERS:
143+
flush_buffer()
144+
marker = _INLINE_MARKERS[token_type]
145+
_append_text(nodes, marker)
146+
children = token.get('children', [])
147+
if children:
148+
nodes.extend(self._convert_inline_tokens(children))
149+
_append_text(nodes, marker)
137150
else:
138151
flush_buffer()
139152
children = token.get('children', [])
@@ -155,6 +168,10 @@ def _flatten_inline_text(self, tokens: Iterable[dict]):
155168
parts.append(token.get('raw') or token.get('text') or '')
156169
elif token_type == 'codespan':
157170
parts.append(f"`{token.get('raw') or token.get('text') or ''}`")
171+
elif token_type in _INLINE_MARKERS:
172+
marker = _INLINE_MARKERS[token_type]
173+
inner = self._flatten_inline_text(token.get('children', []))
174+
parts.append(f'{marker}{inner}{marker}')
158175
elif token_type in {'linebreak', 'softbreak'}:
159176
parts.append(' ')
160177
else:

tests/test_parser.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ def test_link_label_with_codespan(self):
7676
actual = self._parse('[use `foo`](url)')
7777
self.assertEqual('[use `foo`](url)', actual.nodes[0].nodes[0].text)
7878

79+
def test_link_label_with_strong_preserves_markers(self):
80+
actual = self._parse('[**bold**](url)')
81+
self.assertEqual('[**bold**](url)', actual.nodes[0].nodes[0].text)
82+
7983
def test_link_title_preserved(self):
8084
actual = self._parse('[label](https://example.com "Title Here")')
8185
self.assertEqual('[label](https://example.com "Title Here")', actual.nodes[0].nodes[0].text)
@@ -91,6 +95,13 @@ def test_reference_definition_preserved(self):
9195
self.assertEqual('[API][id]', link.text)
9296
self.assertEqual('[id]: https://example.com', tree.nodes[1].nodes[0].text)
9397

98+
def test_reference_links_with_whitespace_and_empty_id(self):
99+
data = 'See [API][] and [Ref] [id].\n\n[API]: https://example.com\n[id]: https://example.com'
100+
tree = self._parse(data)
101+
link_texts = [node.text for node in tree.nodes[0].nodes if node.name == 'link']
102+
self.assertIn('[API][]', link_texts)
103+
self.assertIn('[Ref] [id]', link_texts)
104+
94105
def test_reference_definition_inside_fence_is_text(self):
95106
data = """```
96107
[id]: https://example.com

0 commit comments

Comments
 (0)