Skip to content

Commit 80668e3

Browse files
committed
Account for code spans at start of line.
Previously we didn't test for this because we did not allow raw blocks to have any indent. Now, that we allow up to 3 spaces of indent, we need to confirm those 3 chars are actually whitespace. Tests added. Note: the case where the code span is not on the first line is still failing. I havn't worked out why but ran out of time today.
1 parent 6dea522 commit 80668e3

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

markdown/htmlparser.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,30 @@ def close(self):
6565
self.cleandoc.append(self.md.htmlStash.store(''.join(self._cache)))
6666
self._cache = []
6767

68+
@property
69+
def line_offset(self):
70+
"""Returns char index in self.rawdata for the start of the current line. """
71+
if self.lineno > 1:
72+
return re.match(r'([^\n]*\n){{{}}}'.format(self.lineno-1), self.rawdata).end()
73+
return 0
74+
75+
def at_line_start(self):
76+
"""
77+
Returns True if current position is at start of line.
78+
79+
Allows for up to three blank spaces at start of line.
80+
"""
81+
if self.offset == 0:
82+
return True
83+
if self.offset > 3:
84+
return False
85+
# Confirm up to first 3 chars are whitespace
86+
return self.rawdata[self.line_offset:self.offset].strip() == ''
87+
6888
def handle_starttag(self, tag, attrs):
6989
self.stack.append(tag)
7090

71-
line, col = self.getpos()
72-
if col < 4 and self.md.is_block_level(tag) and not self.inraw:
91+
if self.at_line_start() and self.md.is_block_level(tag) and not self.inraw:
7392
# Started a new raw block
7493
self.inraw = True
7594
if len(self.cleandoc):
@@ -84,12 +103,7 @@ def handle_starttag(self, tag, attrs):
84103

85104
def handle_endtag(self, tag):
86105
# Attempt to extract actual tag from raw source text
87-
if self.lineno > 1:
88-
# Find start position: char index for end of line at self.lineno + self.offset
89-
start = re.match(r'([^\n]*\n){{{}}}'.format(self.lineno-1), self.rawdata).end() + self.offset
90-
else:
91-
# On first line. Just use self.offset for start position.
92-
start = self.offset
106+
start = self.line_offset + self.offset
93107
m = parser.endendtag.search(self.rawdata, start)
94108
if m:
95109
text = self.rawdata[start:m.end()]
@@ -122,11 +136,10 @@ def handle_data(self, data):
122136

123137
def handle_empty_tag(self, data, is_block):
124138
""" Handle empty tags (`<data>`). """
125-
line, col = self.getpos()
126139
if self.inraw:
127140
# Append this to the existing raw block
128141
self._cache.append(data)
129-
elif col < 4 and is_block:
142+
elif self.at_line_start() and is_block:
130143
# Handle this as a standalone raw block
131144
self.cleandoc.append(self.md.htmlStash.store(data))
132145
# Insert blank line between this and next line.

tests/test_syntax/blocks/test_html_blocks.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ def test_raw_span(self):
7474

7575
def test_code_span(self):
7676
self.assertMarkdownRenders(
77-
'`<em>code span</em>`',
78-
'<p><code>&lt;em&gt;code span&lt;/em&gt;</code></p>'
77+
'`<p>code span</p>`',
78+
'<p><code>&lt;p&gt;code span&lt;/p&gt;</code></p>'
7979
)
8080

8181
def test_raw_empty(self):
@@ -227,6 +227,25 @@ def test_raw_surrounded_by_text_without_blank_lines(self):
227227
)
228228
)
229229

230+
# TODO: Fix this. Not sure why its failing...
231+
def test_multiline_markdown_with_code_span(self):
232+
self.assertMarkdownRenders(
233+
self.dedent(
234+
"""
235+
A paragraph with a block-level
236+
`<p>code span</p>`, which is
237+
at the start of a line.
238+
"""
239+
),
240+
self.dedent(
241+
"""
242+
<p>A paragraph with a block-level
243+
<code>&lt;p&gt;code span&lt;/p&gt;</code>.
244+
More <em>Markdown</em> text.</p>
245+
"""
246+
)
247+
)
248+
230249
# Note: The blank line between the tags is a change in behavior.
231250
def test_raw_one_line_followed_by_text(self):
232251
self.assertMarkdownRenders(
@@ -645,6 +664,12 @@ def test_raw_comment_one_line_with_tag(self):
645664
'<!-- <tag> -->'
646665
)
647666

667+
def test_comment_in_code_span(self):
668+
self.assertMarkdownRenders(
669+
'`<!-- *foo* -->`',
670+
'<p><code>&lt;!-- *foo* --&gt;</code></p>'
671+
)
672+
648673
# Note: this is a change in behavior for Python-Markdown only in that a blank line is added.
649674
# While it does not match the reference implementation, there is no difference in rendering.
650675
def test_raw_comment_one_line_followed_by_text(self):

0 commit comments

Comments
 (0)