Skip to content

Commit 0ba607d

Browse files
authored
Merge pull request #3469 from Textualize/fix-table-nl
fix superfluous space
2 parents c478588 + 6f529d3 commit 0ba607d

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- Fixed overriding the `background_color` of `Syntax` not including padding https://github.com/Textualize/rich/issues/3295
2020
- Fixed selective enabling of highlighting when disabled in the `Console` https://github.com/Textualize/rich/issues/3419
2121
- Fixed BrokenPipeError writing an error message https://github.com/Textualize/rich/pull/3468
22+
- Fixed superfluous space above Markdown tables https://github.com/Textualize/rich/pull/3469
2223

2324
### Changed
2425

rich/markdown.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ def __rich_console__(
677677
and context.stack.top.on_child_close(context, element)
678678
)
679679
if should_render:
680-
if new_line:
680+
if new_line and node_type != "inline":
681681
yield _new_line_segment
682682
yield from console.render(element, context.options)
683683

tests/test_markdown.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
Paragraphs are separated
1919
by a blank line.
2020
21-
Two spaces at the end of a line
21+
Two spaces at the end of a line
2222
produces a line break.
2323
24-
Text attributes _italic_,
24+
Text attributes _italic_,
2525
**bold**, `monospace`.
2626
2727
Horizontal rule:
@@ -99,7 +99,7 @@ def render(renderable: RenderableType) -> str:
9999
def test_markdown_render():
100100
markdown = Markdown(MARKDOWN)
101101
rendered_markdown = render(markdown)
102-
expected = "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n\x1b[1mHeading\x1b[0m ┃\n┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n\n\n \x1b[1;4mSub-heading\x1b[0m \n\n \x1b[1mHeading\x1b[0m \n\n \x1b[1;2mH4 Heading\x1b[0m \n\n \x1b[4mH5 Heading\x1b[0m \n\n \x1b[3mH6 Heading\x1b[0m \n\nParagraphs are separated by a blank line. \n\nTwo spaces at the end of a line \nproduces a line break. \n\nText attributes \x1b[3mitalic\x1b[0m, \x1b[1mbold\x1b[0m, \x1b[1;36;40mmonospace\x1b[0m. \n\nHorizontal rule: \n\n\x1b[33m────────────────────────────────────────────────────────────────────────────────────────────────────\x1b[0m\nBullet list: \n\n\x1b[1;33m • \x1b[0mapples \n\x1b[1;33m • \x1b[0moranges \n\x1b[1;33m • \x1b[0mpears \n\nNumbered list: \n\n\x1b[1;33m 1 \x1b[0mlather \n\x1b[1;33m 2 \x1b[0mrinse \n\x1b[1;33m 3 \x1b[0mrepeat \n\nAn \x1b]8;id=0;foo\x1b\\\x1b[4;34mexample\x1b[0m\x1b]8;;\x1b\\. \n\n\x1b[35m▌ \x1b[0m\x1b[35mMarkdown uses email-style > characters for blockquoting.\x1b[0m\x1b[35m \x1b[0m\n\x1b[35m▌ \x1b[0m\x1b[35mLorem ipsum\x1b[0m\x1b[35m \x1b[0m\n\n🌆 \x1b]8;id=0;foo\x1b\\progress\x1b]8;;\x1b\\ \n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34ma=1\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;255;70;137;48;2;39;40;34mimport\x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mthis\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mfoobar\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mimport this\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[1;33m 1 \x1b[0mList item \n\x1b[1;33m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[1;33m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mCode block\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[1;33m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n"
102+
expected = "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n\x1b[1mHeading\x1b[0m ┃\n┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n\n\n \x1b[1;4mSub-heading\x1b[0m \n\n \x1b[1mHeading\x1b[0m \n\n \x1b[1;2mH4 Heading\x1b[0m \n\n \x1b[4mH5 Heading\x1b[0m \n\n \x1b[3mH6 Heading\x1b[0m \n\nParagraphs are separated by a blank line. \n\nTwo spaces at the end of a line produces a line break. \n\nText attributes \x1b[3mitalic\x1b[0m, \x1b[1mbold\x1b[0m, \x1b[1;36;40mmonospace\x1b[0m. \n\nHorizontal rule: \n\n\x1b[33m────────────────────────────────────────────────────────────────────────────────────────────────────\x1b[0m\nBullet list: \n\n\x1b[1;33m • \x1b[0mapples \n\x1b[1;33m • \x1b[0moranges \n\x1b[1;33m • \x1b[0mpears \n\nNumbered list: \n\n\x1b[1;33m 1 \x1b[0mlather \n\x1b[1;33m 2 \x1b[0mrinse \n\x1b[1;33m 3 \x1b[0mrepeat \n\nAn \x1b]8;id=0;foo\x1b\\\x1b[4;34mexample\x1b[0m\x1b]8;;\x1b\\. \n\n\x1b[35m▌ \x1b[0m\x1b[35mMarkdown uses email-style > characters for blockquoting.\x1b[0m\x1b[35m \x1b[0m\n\x1b[35m▌ \x1b[0m\x1b[35mLorem ipsum\x1b[0m\x1b[35m \x1b[0m\n\n🌆 \x1b]8;id=0;foo\x1b\\progress\x1b]8;;\x1b\\ \n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34ma=1\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;255;70;137;48;2;39;40;34mimport\x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mthis\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mfoobar\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mimport this\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[48;2;39;40;34m \x1b[0m\n\n\x1b[1;33m 1 \x1b[0mList item \n\x1b[1;33m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[1;33m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[38;2;248;248;242;48;2;39;40;34mCode block\x1b[0m\x1b[48;2;39;40;34m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n\x1b[1;33m \x1b[0m\x1b[48;2;39;40;34m \x1b[0m\n"
103103
assert rendered_markdown == expected
104104

105105

@@ -174,6 +174,31 @@ def test_partial_table():
174174
assert result == expected
175175

176176

177+
def test_table_with_empty_cells() -> None:
178+
"""Test a table with empty cells is rendered without extra newlines above.
179+
Regression test for #3027 https://github.com/Textualize/rich/issues/3027
180+
"""
181+
complete_table = Markdown(
182+
"""\
183+
| First Header | Second Header |
184+
| ------------- | ------------- |
185+
| Content Cell | Content Cell |
186+
| Content Cell | Content Cell |
187+
"""
188+
)
189+
table_with_empty_cells = Markdown(
190+
"""\
191+
| First Header | |
192+
| ------------- | ------------- |
193+
| Content Cell | Content Cell |
194+
| | Content Cell |
195+
"""
196+
)
197+
result = len(render(table_with_empty_cells).splitlines())
198+
expected = len(render(complete_table).splitlines())
199+
assert result == expected
200+
201+
177202
if __name__ == "__main__":
178203
markdown = Markdown(MARKDOWN)
179204
rendered = render(markdown)

0 commit comments

Comments
 (0)