Skip to content

Conversation

@anish-devgit
Copy link

Problem

Previously, Rich rendered all Markdown lists as "tight" lists, even when items were separated by blank lines (loose lists). This squashed list items together, ignoring the intended vertical spacing defined in the CommonMark spec.

Solution

I updated the ListItem class in rich/markdown.py to respect the hidden attribute provided by the markdown-it-py parser.

  • Logic Update: When ListItem.on_child_close processes a child element, it now checks if that child is explicitly marked as "visible" (not token.hidden).
  • Rendering: If it is visible (indicating a loose list), a single blank line (Text(" ")) is appended to the renderable elements.
  • Regression Tests: I updated tests/test_markdown.py and tests/test_markdown_no_hyperlinks.py to reflect the corrected, spaced-out rendering. This ensures no regressions for standard (tight) lists while fixing the output for loose lists.

Example

Input:

1. Item 1

2. Item 2

Before:
1 Item 1
2 Item 2

After:
1 Item 1

2 Item 2

Linked Issue
Fixes #3907

Updates ListItem to respect the 'hidden' token attribute from markdown-it-py. This ensures that loose lists (items separated by newlines) render with proper spacing, complying with the CommonMark spec, while keeping tight lists compact. Updated regression tests to match the corrected output.

def on_child_close(self, context: MarkdownContext, child: MarkdownElement) -> bool:
self.elements.append(child)
# FIX: If the child is a visible paragraph (loose list), add a blank line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIX would be superfluous once merged...

def on_child_close(self, context: MarkdownContext, child: MarkdownElement) -> bool:
self.elements.append(child)
# FIX: If the child is a visible paragraph (loose list), add a blank line
if getattr(child, "visible", False):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getattr is often a hack. Why can't we be sure of this attribute?

self.elements.append(child)
# FIX: If the child is a visible paragraph (loose list), add a blank line
if getattr(child, "visible", False):
# Text(" ") creates exactly one new line of height
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little redundant perhaps?

# FIX: If the child is a visible paragraph (loose list), add a blank line
if getattr(child, "visible", False):
# Text(" ") creates exactly one new line of height
self.elements.append(Text(" "))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the intent here? I doubt a single space in the output is desirable...

return cls(justify=markdown.justify or "left")
return cls(
justify=markdown.justify or "left",
visible=not getattr(token, "hidden", False),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we be sure that the "hidden" attribute exists? Is it not on all Tokens? If not, would an isinstance check allow us to avoid the getattr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants