Skip to content

Commit 1873066

Browse files
committed
Support building line blocks with markdown-it hardbreaks
Provides the ability to build docutils' line-block nodes if an inline element contains hardbreaks. When a hardbreak is detected as a child of an inline token, a line-block will be created and child tokens will be rendered into a prepared line node. Child nodes are placed into a line node until the next hardbreak is detected, where a new line node is created to hold the next child set. The process repeats until all children are processed. Signed-off-by: James Knight <git@jdknight.me>
1 parent fbb7f1d commit 1873066

File tree

3 files changed

+53
-22
lines changed

3 files changed

+53
-22
lines changed

myst_parser/mdit_to_docutils/base.py

+43-10
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,19 @@ def current_node_context(
345345
def render_children(self, token: SyntaxTreeNode) -> None:
346346
"""Render the children of a token."""
347347
for child in token.children or []:
348-
if f"render_{child.type}" in self.rules:
349-
self.rules[f"render_{child.type}"](child)
350-
else:
351-
self.create_warning(
352-
f"No render method for: {child.type}",
353-
MystWarnings.RENDER_METHOD,
354-
line=token_line(child, default=0),
355-
append_to=self.current_node,
356-
)
348+
self.render_token(child)
349+
350+
def render_token(self, token: SyntaxTreeNode) -> None:
351+
"""Render a token."""
352+
if f"render_{token.type}" in self.rules:
353+
self.rules[f"render_{token.type}"](token)
354+
else:
355+
self.create_warning(
356+
f"No render method for: {token.type}",
357+
MystWarnings.RENDER_METHOD,
358+
line=token_line(token, default=0),
359+
append_to=self.current_node,
360+
)
357361

358362
def add_line_and_source_path(self, node, token: SyntaxTreeNode) -> None:
359363
"""Copy the line number and document source path to the docutils node."""
@@ -479,7 +483,36 @@ def render_paragraph(self, token: SyntaxTreeNode) -> None:
479483
self.render_children(token)
480484

481485
def render_inline(self, token: SyntaxTreeNode) -> None:
482-
self.render_children(token)
486+
needs_lineblock = False
487+
for child in token.children or []:
488+
if child.type == "hardbreak":
489+
needs_lineblock = True
490+
break
491+
492+
if not needs_lineblock:
493+
self.render_children(token)
494+
return
495+
496+
# if we have any hard breaks, we will build a line block and
497+
# prepare line nodes for each group of children between these
498+
# breaks
499+
lineblock = nodes.line_block()
500+
self.add_line_and_source_path(lineblock, token)
501+
self.current_node.append(lineblock)
502+
503+
current_line = nodes.line()
504+
self.add_line_and_source_path(current_line, token)
505+
lineblock.append(current_line)
506+
507+
for child in token.children or []:
508+
if child.type == "hardbreak":
509+
current_line = nodes.line()
510+
self.add_line_and_source_path(current_line, token)
511+
lineblock.append(current_line)
512+
continue
513+
514+
with self.current_node_context(current_line):
515+
self.render_token(child)
483516

484517
def render_text(self, token: SyntaxTreeNode) -> None:
485518
self.current_node.append(nodes.Text(token.content))

tests/test_renderers/fixtures/docutil_syntax_elements.md

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ bar
1414
.
1515
<document source="notset">
1616
<paragraph>
17-
foo
18-
<raw format="html" xml:space="preserve">
19-
<br />
20-
<raw format="latex" xml:space="preserve">
21-
\\
22-
bar
17+
<line_block>
18+
<line>
19+
foo
20+
<line>
21+
bar
2322
.
2423

2524
Strong:

tests/test_renderers/fixtures/sphinx_syntax_elements.md

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ bar
1414
.
1515
<document source="<src>/index.md">
1616
<paragraph>
17-
foo
18-
<raw format="html" xml:space="preserve">
19-
<br />
20-
<raw format="latex" xml:space="preserve">
21-
\\
22-
bar
17+
<line_block>
18+
<line>
19+
foo
20+
<line>
21+
bar
2322
.
2423

2524
Strong:

0 commit comments

Comments
 (0)