Skip to content

Commit

Permalink
Support building line blocks with markdown-it hardbreaks
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
jdknight committed Jul 20, 2024
1 parent d3d7fbb commit d1990c5
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 22 deletions.
53 changes: 43 additions & 10 deletions myst_parser/mdit_to_docutils/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,19 @@ def current_node_context(
def render_children(self, token: SyntaxTreeNode) -> None:
"""Render the children of a token."""
for child in token.children or []:
if f"render_{child.type}" in self.rules:
self.rules[f"render_{child.type}"](child)
else:
self.create_warning(
f"No render method for: {child.type}",
MystWarnings.RENDER_METHOD,
line=token_line(child, default=0),
append_to=self.current_node,
)
self.render_token(child)

def render_token(self, token: SyntaxTreeNode) -> None:
"""Render a token."""
if f"render_{token.type}" in self.rules:
self.rules[f"render_{token.type}"](token)
else:
self.create_warning(
f"No render method for: {token.type}",
MystWarnings.RENDER_METHOD,
line=token_line(token, default=0),
append_to=self.current_node,
)

def add_line_and_source_path(self, node, token: SyntaxTreeNode) -> None:
"""Copy the line number and document source path to the docutils node."""
Expand Down Expand Up @@ -526,7 +530,36 @@ def render_paragraph(self, token: SyntaxTreeNode) -> None:
self.render_children(token)

def render_inline(self, token: SyntaxTreeNode) -> None:
self.render_children(token)
needs_lineblock = False
for child in token.children or []:
if child.type == "hardbreak":
needs_lineblock = True
break

if not needs_lineblock:
self.render_children(token)
return

# if we have any hard breaks, we will build a line block and
# prepare line nodes for each group of children between these
# breaks
lineblock = nodes.line_block()
self.add_line_and_source_path(lineblock, token)
self.current_node.append(lineblock)

current_line = nodes.line()
self.add_line_and_source_path(current_line, token)
lineblock.append(current_line)

for child in token.children or []:
if child.type == "hardbreak":
current_line = nodes.line()
self.add_line_and_source_path(current_line, token)
lineblock.append(current_line)
continue

with self.current_node_context(current_line):
self.render_token(child)

def render_text(self, token: SyntaxTreeNode) -> None:
self.current_node.append(nodes.Text(token.content))
Expand Down
11 changes: 5 additions & 6 deletions tests/test_renderers/fixtures/docutil_syntax_elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ bar
.
<document source="notset">
<paragraph>
foo
<raw format="html" xml:space="preserve">
<br />
<raw format="latex" xml:space="preserve">
\\
bar
<line_block>
<line>
foo
<line>
bar
.

Strong:
Expand Down
11 changes: 5 additions & 6 deletions tests/test_renderers/fixtures/sphinx_syntax_elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ bar
.
<document source="<src>/index.md">
<paragraph>
foo
<raw format="html" xml:space="preserve">
<br />
<raw format="latex" xml:space="preserve">
\\
bar
<line_block>
<line>
foo
<line>
bar
.

Strong:
Expand Down

0 comments on commit d1990c5

Please sign in to comment.