Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
56efec6
Bump Markdig from 1.4.0 to 1.4.2
dependabot[bot] Oct 20, 2026
1d74c8e
Fix Markdown rendering and cover Markdig upgrades under Native AOT
harder Oct 20, 2026
ca38ad1
Preserve continuation indentation in list headings
harder Oct 20, 2026
41bcddc
Preserve Markdown table inline content and alert labels
harder Oct 20, 2026
5b95768
Restore original table alignment switch formatting (review 8)
harder Oct 20, 2026
708af2e
Use continuation prefixes after definition terms and alert headers (r…
harder Oct 20, 2026
d804799
Keep hard-break lines valid and omit trailing phantom lines (review 2)
harder Oct 20, 2026
917143d
Round-trip escaped table literals and multi-backtick code spans (revi…
harder Oct 20, 2026
a52321a
Preserve segment metadata through text and highlighter copies (review 4)
harder Oct 20, 2026
c93a431
Render depth-limited Markdown as literal text instead of throwing (re…
harder Oct 20, 2026
2f74856
Preserve alert kind markers when copying selected alerts (review 6)
harder Oct 20, 2026
1112ad9
Initialize tables with parsed content at the intended width (review 7)
harder Oct 20, 2026
5c846da
Use plain driver buffers for Markdown rendering assertions (review 9)
harder Oct 20, 2026
241e04f
Share parse recovery state without matching exception messages (round…
harder Oct 21, 2026
b00c39a
Use a single set of positional InlineRun properties (round 2 finding 2)
harder Oct 21, 2026
a240f1c
Scope continuation prefixes to definition lists and alerts (round 2 f…
harder Oct 21, 2026
32e5565
Preserve original alert kind casing in copied markers (round 2 findin…
harder Oct 21, 2026
cd1b370
Unify table inline parsing and preserve serialized literals (round 2 …
harder Oct 21, 2026
6b814cc
Test the production segment measurement path and remove dead overload…
harder Oct 21, 2026
80bc92f
Use collection spreads on PR-added materializations (round 2 finding 8)
harder Oct 21, 2026
576adb9
Preserve unsupported table inlines and linked cell round trips
harder Oct 21, 2026
10783e3
Include definition items when measuring block end lines
harder Oct 21, 2026
1c0634f
Restore repository XML summary conventions for table data
harder Oct 21, 2026
ae5fc7c
Log Markdown parse failures before preserving literal source
harder Oct 21, 2026
caeec1e
Reuse regex instances during table cell serialization
harder Oct 21, 2026
988bc09
Preserve multiline cells and complete table link serialization
harder Oct 21, 2026
065c11d
Leave anchor invalidation to content changes and layout rebuilds
harder Oct 21, 2026
7d8e49a
Keep dependency audit and rendering evidence in the PR description
harder Oct 21, 2026
25aa8b5
Separate inline parser setup from its explanatory comment
harder Oct 21, 2026
6d42973
Wrap table tabs and embedded newlines at measured word boundaries
harder Oct 21, 2026
1600813
Cache table column width bounds across viewport changes
harder Oct 21, 2026
5bca1e6
Use typed Markdown test helpers and plain drivers for mouse behavior
harder Oct 21, 2026
ae936a3
Keep safe custom-pipeline table literals readable on copy
harder Oct 21, 2026
40b9419
Wrap table words across styles and preserve explicit line breaks
harder Oct 21, 2026
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
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<PackageVersion Include="ColorHelper" Version="1.8.1" />
<PackageVersion Include="TextMateSharp" Version="2.0.4" />
<PackageVersion Include="TextMateSharp.Grammars" Version="2.0.4" />
<PackageVersion Include="Markdig" Version="1.4.0" />
<PackageVersion Include="Markdig" Version="1.4.2" />
<PackageVersion Include="Serilog" Version="4.4.0" />
<PackageVersion Include="Serilog.Extensions.Logging" Version="10.0.0" />
<PackageVersion Include="Serilog.Sinks.Debug" Version="3.0.0" />
Expand Down
9 changes: 8 additions & 1 deletion Terminal.Gui/Drawing/Markdown/MarkdownAttributeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ internal static class MarkdownAttributeHelper
/// </param>
/// <returns>A fully resolved <see cref="Attribute"/> ready for drawing.</returns>
public static Attribute GetAttributeForSegment (View view, StyledSegment segment, ISyntaxHighlighter? highlighter = null, Color? themeBackground = null)
{
Attribute attribute = ResolveSegmentAttribute (view, segment, highlighter, themeBackground);

return attribute with { Style = attribute.Style | segment.AdditionalStyle };
}

private static Attribute ResolveSegmentAttribute (View view, StyledSegment segment, ISyntaxHighlighter? highlighter, Color? themeBackground)
{
if (segment.Role is { } role)
{
Expand Down Expand Up @@ -116,7 +123,7 @@ public static List<StyledSegment> ToStyledSegments (IReadOnlyList<InlineRun> run

foreach (InlineRun run in runs)
{
segments.Add (new StyledSegment (run.Text, run.StyleRole, run.Url, run.ImageSource, run.Attribute, run.Role));
segments.Add (run.ToStyledSegment ());
}

return segments;
Expand Down
9 changes: 9 additions & 0 deletions Terminal.Gui/Drawing/Markdown/StyledSegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,13 @@ public StyledSegment (
/// if the role should be resolved from <see cref="StyleRole"/>.
/// </summary>
public VisualRole? Role { get; }

// Preserve nested Markdown styles without fixing colors before the view's scheme is resolved.
internal TextStyle AdditionalStyle { get; init; }

internal StyledSegment WithText (string text, VisualRole? role = null) =>
new (text, StyleRole, Url, ImageSource, Attribute, role ?? Role)
{
AdditionalStyle = AdditionalStyle
};
}
4 changes: 2 additions & 2 deletions Terminal.Gui/Views/CodeRoleLegendHighlighter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public IReadOnlyList<StyledSegment> Highlight (string code, string? language)

public Attribute? GetAttributeForScope (MarkdownStyleRole role) => _textMate.GetAttributeForScope (role);

private static void AddRoleSegments (List<StyledSegment> segments, StyledSegment segment)
internal static void AddRoleSegments (List<StyledSegment> segments, StyledSegment segment)
{
int index = 0;

Expand Down Expand Up @@ -77,6 +77,6 @@ private static (string Text, VisualRole Role) FindRoleMarker (string text, int i

private static void AddSegment (List<StyledSegment> segments, StyledSegment source, string text, VisualRole? role)
{
segments.Add (new StyledSegment (text, source.StyleRole, source.Url, source.ImageSource, source.Attribute, role));
segments.Add (source.WithText (text, role));
}
}
33 changes: 20 additions & 13 deletions Terminal.Gui/Views/Markdown/InlineRun.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
namespace Terminal.Gui.Views;

internal sealed class InlineRun (
string text,
MarkdownStyleRole styleRole,
string? url = null,
string? imageSource = null,
Attribute? attribute = null,
VisualRole? role = null)
internal sealed record InlineRun (
string Text,
MarkdownStyleRole StyleRole,
string? Url = null,
string? ImageSource = null,
Attribute? Attribute = null,
VisualRole? Role = null)
{
public string Text { get; } = text;
public MarkdownStyleRole StyleRole { get; } = styleRole;
public string? Url { get; } = url;
public string? ImageSource { get; } = imageSource;
public Attribute? Attribute { get; } = attribute;
public VisualRole? Role { get; } = role;
public TextStyle AdditionalStyle { get; init; }

public StyledSegment ToStyledSegment (string? text = null) =>
new (text ?? Text, StyleRole, Url, ImageSource, Attribute, Role)
{
AdditionalStyle = AdditionalStyle
};

public static InlineRun FromStyledSegment (StyledSegment segment) =>
new (segment.Text, segment.StyleRole, segment.Url, segment.ImageSource, segment.Attribute, segment.Role)
{
AdditionalStyle = segment.AdditionalStyle
};
}
7 changes: 6 additions & 1 deletion Terminal.Gui/Views/Markdown/IntermediateBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,23 @@ internal sealed class IntermediateBlock (IReadOnlyList<InlineRun> runs,
string? anchor = null,
bool isThematicBreak = false,
TableData? tableData = null,
string? language = null)
string? language = null,
MarkdownTableContent? tableContent = null,
string? sourceText = null)
{
public IReadOnlyList<InlineRun> Runs { get; } = runs;
public bool Wrap { get; } = wrap;
public string Prefix { get; } = prefix;
public string? SourceText { get; } = sourceText;
public string ContinuationPrefix { get; } = continuationPrefix;
public bool IsCodeBlock { get; } = isCodeBlock;
public bool IsThematicBreak { get; } = isThematicBreak;

/// <summary>Gets the parsed table data if this block represents a table; otherwise <see langword="null"/>.</summary>
public TableData? TableData { get; } = tableData;

public MarkdownTableContent? TableContent { get; } = tableContent;

/// <summary>Gets whether this block represents a Markdown table.</summary>
public bool IsTable => TableData is { };

Expand Down
18 changes: 18 additions & 0 deletions Terminal.Gui/Views/Markdown/Markdown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ bool IDesignable.EnableForDesign ()
* [Basic Formatting](#basic-formatting)
* [Links](#links)
* [Checklist](#checklist)
* [Definition Lists](#definition-lists)
* [Hard Line Breaks](#hard-line-breaks)
* [Code Blocks](#code-blocks)
* [Tables](#tables)
* [Separators](#separators)
Expand Down Expand Up @@ -588,6 +590,9 @@ Plain text. *Formatted text* with **bold** and `inline code`.
| [Links](https://tui-cs.github.io/Terminal.Gui/api/Terminal.Gui.Views.MarkdownTable.html) | ✅ Totally! |
| Inline `code` | ✅ *Awesome!* |
| Emojis 🎉 | ✅ **Whoa!** |
| Code with a backtick | ``a`b`` |
| Nested formatting | **bold *and italic*** with ~~strikethrough~~ |
| Nested link label | [Testing [Header]](https://example.com/path_(part)) |

**table** with different alignments:

Expand All @@ -608,13 +613,26 @@ And this text is after. Thematic breaks are rendered as full-width horizontal li

> **Tip:** This is a block quote with *inline formatting*.

> [!WARNING]
> Alert kinds remain visible alongside their content.

Here's a multi-line block quote with a link, code, and more:

> **Tip:** Block quotes can contain *inline formatting*, **bold text**,
> `inline code`, and [links](https://example.com).
>
> They can also span multiple lines with blank quote lines between paragraphs.

## Definition Lists

Terminal.Gui
: A toolkit for terminal user interfaces.

## Hard Line Breaks

This line ends with a backslash.\
This starts on a new line without a new paragraph.

That's all folks! 👋
""";
}
Loading
Loading