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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ and `MarkupString.Pueblo`. The packages share one version and are released toget
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 2.24.2 — Unreleased

### Fixed

- **A table's heading rule matches its border**: unless a theme names its own, the line under a table's
headings is `─` (the default `LayoutTheme.Defaults.HeaderRule`), and `-` under an ASCII border or for an
ASCII reader. It was always `-`, so a table in a Unicode box had an ASCII rule under its headings.

## 2.24.1 — Unreleased

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion MarkupString.Tests/Layout/CompositionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public async Task Shaded_Text_ColoursTheTextAndLeavesTheBoxDrawingInItsTheme()
var ansi = text.Render(MarkupFormat.Ansi, Registry);

await Assert.That(ansi).Contains("\u001b[38;2;0;128;0m|");
await Assert.That(ansi).Contains("\u001b[38;2;0;128;0m-");
await Assert.That(ansi).Contains("\u001b[38;2;0;128;0m─");
await Assert.That(ansi).Contains("\u001b[38;2;255;0;0mA");
await Assert.That(ansi).Contains("\u001b[38;2;0;0;255md");
await Assert.That(text.Runs.SelectMany(run => run.Markups).OfType<IDataMarkup>()).IsEmpty();
Expand Down
22 changes: 16 additions & 6 deletions MarkupString.Tests/Layout/WidgetLayoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ public async Task Grid_InHtml_IsAColumnedList()
=> await Assert.That(BlockLayout.Build(new Grid(Names), 32).Render(MarkupFormat.Html, Registry))
.Contains("<ul class=\"ms-grid ms-down\" style=\"columns:8ch;column-gap:2ch\"><li>Mannaz</li>");

/// <summary>The rule under the headings is drawn like the border around it: <c>-</c> under an ASCII one or for an ASCII reader.</summary>
[Test]
public async Task Table_HeaderRule_FollowsTheBorder()
{
await Assert.That(Lines(Who(), 60)[1]).IsEqualTo(new string('─', 43));
await Assert.That(Lines(Who(), 60, Ascii)[1]).IsEqualTo(new string('-', 43));
await Assert.That(Lines(Who().Themed(new LayoutTheme { Border = BorderStyle.Ascii }), 60)[1]).IsEqualTo(new string('-', 43));
await Assert.That(Lines(Who().Themed(new LayoutTheme { Border = BorderStyle.Ascii, HeaderRule = P("=") }), 60)[1]).IsEqualTo(new string('=', 43));
}

private static Table Who(int nameMin = 6) => new(
[
new TableColumn(P("Name")) { Min = nameMin },
Expand All @@ -128,7 +138,7 @@ public async Task Table_ColumnsFitTheirWidestCell()
=> await Assert.That(Lines(Who(), 60)).IsEquivalentTo(new[]
{
"Name Idle Doing",
"-------------------------------------------",
"───────────────────────────────────────────",
"Mannaz 0s Hooooo?",
"Raya 5m Writing a scene in the garden",
});
Expand All @@ -138,7 +148,7 @@ public async Task Table_TooWide_WrapsFirst()
=> await Assert.That(Lines(Who(), 30)).IsEquivalentTo(new[]
{
"Name Idle Doing",
"------------------------------",
"──────────────────────────────",
"Mannaz 0s Hooooo?",
"Raya 5m Writing a scene",
" in the garden",
Expand All @@ -149,7 +159,7 @@ public async Task Table_TooWideToWrap_LeavesOutTheLeastImportant()
=> await Assert.That(Lines(Who(), 18)).IsEquivalentTo(new[]
{
"Name Idle",
"------------",
"────────────",
"Mannaz 0s",
"Raya 5m",
});
Expand All @@ -165,7 +175,7 @@ public async Task Table_NoColumnFits_RowsBecomeCards()

[Test]
public async Task Table_AColumnThatDoesNotWrap_IsWholeOrLeftOut()
=> await Assert.That(Lines(Who(), 10)).IsEquivalentTo(new[] { "Name", "------", "Mannaz", "Raya" });
=> await Assert.That(Lines(Who(), 10)).IsEquivalentTo(new[] { "Name", "──────", "Mannaz", "Raya" });

[Test]
public async Task Table_InHtml_IsATableThatDropsColumnsWhenNarrow()
Expand Down Expand Up @@ -218,7 +228,7 @@ public async Task Table_AColumnThatGrows_FillsTheWidth()
{
var lines = BlockLayout.Build(Growing(0, 1), 60).ToPlainText().Split('\n');

await Assert.That(lines[1]).IsEqualTo(new string('-', 60)).Because("the heading rule spans the table, which now spans its width");
await Assert.That(lines[1]).IsEqualTo(new string('─', 60)).Because("the heading rule spans the table, which now spans its width");
await Assert.That(lines[0].TrimEnd()).IsEqualTo("Name Idle Doing");
await Assert.That(lines[3].TrimEnd()).IsEqualTo("Raya 5m Writing a scene in the garden");
}
Expand All @@ -233,7 +243,7 @@ public async Task Table_AGrowingColumn_StopsAtItsMax()
{
var table = Growing(0, 1) with { Columns = [.. Growing(0, 1).Columns.SetItem(2, Growing(0, 1).Columns[2] with { Max = 35 })] };

await Assert.That(Lines(table, 60)[1]).IsEqualTo(new string('-', 49)).Because("Doing grows from 29 to its 35 and no further");
await Assert.That(Lines(table, 60)[1]).IsEqualTo(new string('─', 49)).Because("Doing grows from 29 to its 35 and no further");
}

[Test]
Expand Down
5 changes: 3 additions & 2 deletions MarkupString/Layout/Blocks/Block.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ public sealed record LayoutTheme

/// <summary>
/// What every unset piece ends up as: light box lines, light tree guides, <c>[█████░░░░░]</c>
/// gauges, <c>•</c> bullets, <c>": "</c> after a label and <c>-</c> under table headings.
/// gauges, <c>•</c> bullets, <c>": "</c> after a label and <c>─</c> under table headings (<c>-</c> under an
/// ASCII border).
/// </summary>
public static LayoutTheme Defaults { get; } = new()
{
Expand All @@ -273,7 +274,7 @@ public sealed record LayoutTheme
GaugeClose = MarkupText.Plain("]"),
Bullet = MarkupText.Plain("•"),
FieldSeparator = MarkupText.Plain(": "),
HeaderRule = MarkupText.Plain("-"),
HeaderRule = MarkupText.Plain("─"),
};

/// <summary>Boxes and rules.</summary>
Expand Down
11 changes: 9 additions & 2 deletions MarkupString/Layout/Blocks/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ this with
/// <summary>Drawn between two columns on every line instead of the gap.</summary>
public MarkupText? Separator { get; init; }

/// <summary>The line under the headings, repeated; empty for none; unset, the theme's (<c>-</c>).</summary>
/// <summary>
/// The line under the headings, repeated; empty for none; unset, the theme's, or <c>─</c> (<c>-</c> under an
/// ASCII border) when the theme names none.
/// </summary>
public MarkupText? HeaderRule { get; init; }

/// <summary>
Expand Down Expand Up @@ -60,7 +63,7 @@ public override void Draw(LayoutContext context, int width, IList<MarkupText> li
MarkupText Join(IEnumerable<MarkupText> cells) => BlockText.Fit(MarkupText.Join(divider, cells), width);

lines.Add(Join(shown.Select(c => BlockText.Fit(context.Paint(theme => theme.HeadingColor, Columns[c].Header).FormatColumn(BlockText.Column(widths[c], Columns[c].Alignment))[0], widths[c]))));
var rule = HeaderRule ?? context.Theme.Piece(theme => theme.HeaderRule);
var rule = HeaderRule ?? context.Theme.HeaderRule ?? DefaultRule(context);
if (rule.Length > 0) lines.Add(BlockText.Fit(context.PaintLine(theme => theme.HeaderRuleColor, BlockText.Run(context.Glyph(rule, "-"), tableWidth)), width));

var cellLines = new List<MarkupText>[Columns.Length];
Expand Down Expand Up @@ -103,6 +106,10 @@ public override void DrawLinear(LayoutContext context, int width, IList<MarkupTe
}
}

/// <summary>The default rule under the headings, ASCII when the border it sits among is.</summary>
private static MarkupText DefaultRule(LayoutContext context) =>
context.Border(null).IsAscii ? MarkupText.Plain("-") : LayoutTheme.Defaults.HeaderRule!;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

/// <summary>Each row as a card of labelled values, the way a phone shows a table too wide for it.</summary>
private void DrawCards(LayoutContext context, int width, IList<MarkupText> lines)
{
Expand Down
5 changes: 3 additions & 2 deletions docs/layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,13 @@ widest cell. When the table is too wide, the columns that wrap give way, widest
least width; then the column with the highest `Priority` number is left out, and so on. A column that
does not wrap is shown whole or not at all. When not even the most important column fits, each row
becomes a card of labelled values. In HTML, a column of priority 2 carries `ms-p2` and one of 3 or
more `ms-p3`, which `LayoutCss.Fixed` hides on narrow pages.
more `ms-p3`, which `LayoutCss.Fixed` hides on narrow pages. The rule under the headings is the
theme's `HeaderRule`, or `─` when it names none (`-` under an ASCII border or for an ASCII reader).

```
At 30: At 18:
Name Idle Doing Name Idle
------------------------------ ------------
────────────────────────────── ────────────
Mannaz 0s Hooooo? Mannaz 0s
Raya 5m Writing a scene Raya 5m
in the garden
Expand Down
Loading