Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions ConsoleMarkdownRenderer.Tests/RendererTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,49 @@ public void RendererTests_AutolinkTest(int index, string expectedContent, string
Assert.IsFalse(link.IsImage, $"IsImage should be false at index {index}");
}

[TestMethod]
public void RendererTests_TableColumnAlignment_HonorsMarkdownAlignment()
{
// Pipe-table column alignment specified in Markdown (`:---`, `:---:`, `---:`) should
// be reflected in the Spectre.Console TableColumn.Alignment of the rendered table.
const string markdown = "| left | center | right |\n| :--- | :----: | ----: |\n| a | b | c |\n";

var document = Markdown.Parse(markdown, MarkdownDisplayer.DefaultPipeline);
var renderer = new ConsoleRenderer(new DisplayOptions());
renderer.Render(document);

Assert.IsNotNull(renderer.Root);
// Root is an outer wrapper Table whose single cell holds the rendered table.
var outer = (Table)renderer.Root;
var inner = (Table)outer.Rows.First().First();

Assert.AreEqual(3, inner.Columns.Count, "Expected three table columns");
Assert.AreEqual(Justify.Left, inner.Columns[0].Alignment, "First column should be left-aligned");
Assert.AreEqual(Justify.Center, inner.Columns[1].Alignment, "Second column should be center-aligned");
Assert.AreEqual(Justify.Right, inner.Columns[2].Alignment, "Third column should be right-aligned");
}

[TestMethod]
public void RendererTests_TableColumnAlignment_DefaultsToLeftWhenUnspecified()
{
// When no alignment is specified (`---`), columns should default to left-aligned.
const string markdown = "| a | b | c |\n| - | - | - |\n| 1 | 2 | 3 |\n";

var document = Markdown.Parse(markdown, MarkdownDisplayer.DefaultPipeline);
var renderer = new ConsoleRenderer(new DisplayOptions());
renderer.Render(document);

Assert.IsNotNull(renderer.Root);
var outer = (Table)renderer.Root;
var inner = (Table)outer.Rows.First().First();

Assert.AreEqual(3, inner.Columns.Count);
foreach (var column in inner.Columns)
{
Assert.AreEqual(Justify.Left, column.Alignment, "Unspecified alignment should default to left");
}
}

[TestMethod]
public void RendererTests_TerminalHyperlinks_DefaultEnabled()
{
Expand Down
18 changes: 9 additions & 9 deletions ConsoleMarkdownRenderer.Tests/resources/table.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
│ │ │ header 1 │ │ │ header 2 │ │ │ header 3 │ │ │
│ │ └──────────┘ │ └──────────┘ │ └──────────┘ │ │
│ ├──────────────┼──────────────┼──────────────┤ │
│ │ ┌───│ ┌───│ ┌─── │ │
│ │ │ 1 │ │ 2 │ │ 3 │ │
│ │ └───│ └───│ └─── │ │
│ │ ┌───│ ┌───│ ┌─── │ │
│ │ │ 4 │ │ 5 │ │ 6 │ │
│ │ └───│ └───│ └─── │ │
│ │ ┌───│ ┌───│ ┌─── │ │
│ │ │ 7 │ │ 8 │ │ 9 │ │
│ │ └───│ └───│ └─── │ │
│ │ ┌──────────┐ │ ┌──────────┐ │ ┌──────────┐ │ │
│ │ │ 1 │ │ 2 │ │ 3 │ │
│ │ └──────────┘ │ └──────────┘ │ └──────────┘ │ │
│ │ ┌──────────┐ │ ┌──────────┐ │ ┌──────────┐ │ │
│ │ │ 4 │ │ 5 │ │ 6 │ │
│ │ └──────────┘ │ └──────────┘ │ └──────────┘ │ │
│ │ ┌──────────┐ │ ┌──────────┐ │ ┌──────────┐ │ │
│ │ │ 7 │ │ 8 │ │ 9 │ │
│ │ └──────────┘ │ └──────────┘ │ └──────────┘ │ │
│ └──────────────┴──────────────┴──────────────┘ │
└────────────────────────────────────────────────┘
4 changes: 4 additions & 0 deletions ConsoleMarkdownRenderer.Tests/resources/tableAlignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| left | center | right |
| :--- | :----: | ----: |
| a | b | c |
| dd | ee | ff |
14 changes: 14 additions & 0 deletions ConsoleMarkdownRenderer.Tests/resources/tableAlignment.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
┌───────────────────────────────────────┐
│ ┌──────────┬────────────┬───────────┐ │
│ │ ┌──────┐ │ ┌────────┐ │ ┌───────┐ │ │
│ │ │ left │ │ │ center │ │ │ right │ │ │
│ │ └──────┘ │ └────────┘ │ └───────┘ │ │
│ ├──────────┼────────────┼───────────┤ │
│ │ ┌──────┐ │ ┌────────┐ │ ┌───────┐ │ │
│ │ │ a │ │ │ b │ │ │ c │ │ │
│ │ └──────┘ │ └────────┘ │ └───────┘ │ │
│ │ ┌──────┐ │ ┌────────┐ │ ┌───────┐ │ │
│ │ │ dd │ │ │ ee │ │ │ ff │ │ │
│ │ └──────┘ │ └────────┘ │ └───────┘ │ │
│ └──────────┴────────────┴───────────┘ │
└───────────────────────────────────────┘
30 changes: 29 additions & 1 deletion ObjectRenderers/Frames/ConsoleRendererBase.TableFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using Spectre.Console;
using Spectre.Console.Rendering;

using Markdig.Extensions.Tables;

using MDTable = Markdig.Extensions.Tables.Table;
using MDTableRow = Markdig.Extensions.Tables.TableRow;

Expand Down Expand Up @@ -29,6 +31,20 @@ public TableFrame(MDTable mdTable)

public void AddCell(IRenderable data)
{
// The data is the cell's frame Table (created by NewFrameImplementation in
// StartTableCellImplementation). To make the parent column's alignment
// visible we expand the inner frame Table to fill the parent column and
// apply the matching Justify to its single column — Spectre.Console only
// honors TableColumn.Alignment on Markup-like cell content and ignores it
// for nested Table renderables.
if (data is Spectre.Console.Table cellTable
&& m_pos < MDTable.ColumnDefinitions.Count
&& cellTable.Columns.Count > 0)
{
cellTable.Expand = true;
cellTable.Columns[0].Alignment = ToJustify(MDTable.ColumnDefinitions[m_pos].Alignment);
}

m_columnData[m_pos] = data;
m_pos++;
}
Expand All @@ -39,7 +55,12 @@ public override void AddRow(IRenderable data)
{
for (int i = 0; i < m_columnData.Length; i++)
{
Table.AddColumn(new TableColumn(m_columnData[i]));
var column = new TableColumn(m_columnData[i]);
if (i < MDTable.ColumnDefinitions.Count)
{
column.Alignment = ToJustify(MDTable.ColumnDefinitions[i].Alignment);
}
Table.AddColumn(column);
}
m_addedColumns = true;
}
Expand All @@ -54,6 +75,13 @@ public override void AddRow(IRenderable data)
m_pos = 0;
}

private static Justify ToJustify(TableColumnAlign? alignment) => alignment switch
{
TableColumnAlign.Center => Justify.Center,
TableColumnAlign.Right => Justify.Right,
_ => Justify.Left,
};

private bool m_addedColumns;

private readonly IRenderable[] m_columnData;
Expand Down
16 changes: 16 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
## Upcoming Changes

### :art: Renderers :art:
- [#143](https://github.com/boxofyellow/ConsoleMarkdownRenderer/pull/143): Honor Markdown pipe-table column alignment in ConsoleTableRenderer
- ``` markdown
| left | center | right |
| :--- | :----: | ----: |
| a | b | c |
| dd | ee | ff |
```
- Render
| left | center | right |
| :--- | :----: | ----: |
| a | b | c |
| dd | ee | ff |
- Before
<img width="222" height="97" alt="Image" src="https://github.com/user-attachments/assets/fce577de-34d3-478f-9cd5-611617e640f1" />
- After
<img width="222" height="97" alt="Image" src="https://github.com/user-attachments/assets/3ba697ad-8197-453d-894a-c1893edaf12c" />
- [#132](https://github.com/boxofyellow/ConsoleMarkdownRenderer/pull/132): Render Markdig CustomContainer admonition blocks
- ```markdown
:::note
Expand Down
Loading