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
18 changes: 18 additions & 0 deletions ConsoleMarkdownRenderer.Example/data/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,23 @@ Footnote references are placed inline[^example] and the rendered footnotes appea

[^longer-footnote]: A longer footnote with **bold**, *italic*, and `inline code` content.

## Custom Containers (Admonitions)

Custom containers represent admonitions / callouts commonly used in technical documentation.

:::note
This is a *note* admonition with **bold** content.
:::

:::warning
A multi-line warning that contains:

- a list item
- another item with `inline code`
:::

A paragraph with an inline ::tag inline container:: example.

## Definition Lists

Term
Expand Down Expand Up @@ -181,6 +198,7 @@ Some text after the block
- [x] Lists
- ~~Should lists use different numbering options as you nest lists~~ We could alternative, maybe we do that later
- [x] Footnotes
- [x] Custom containers (admonitions)
- [ ] One to always leave unchecked

And here is the end
22 changes: 22 additions & 0 deletions ConsoleMarkdownRenderer.Tests/RendererTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,25 @@ public void RendererTests_DefinitionListTest(bool useCrazy)
AssertMarkdownYieldsFormat("definitionList", "citrus", new Style(), useCrazy);
}

[TestMethod]
[DataRow(false)]
[DataRow(true)]
public void RendererTests_CustomContainerInfoTest(bool useCrazy)
{
// The container's Info label (e.g. "note", "warning") should carry the CustomContainerInfo style (bold by default)
AssertMarkdownYieldsFormat("customContainer", "note", new Style(decoration: Decoration.Bold), useCrazy);
AssertMarkdownYieldsFormat("customContainer", "warning", new Style(decoration: Decoration.Bold), useCrazy);
}

[TestMethod]
[DataRow(false)]
[DataRow(true)]
public void RendererTests_CustomContainerInlineTest(bool useCrazy)
{
// Inline custom container content (::tag inline::) carries the CustomContainerInline style (bold by default)
AssertMarkdownYieldsFormat("customContainer", "tag inline", new Style(decoration: Decoration.Bold), useCrazy);
}

[TestMethod]
public void RendererTests_PlainTextUsesDefaultColors()
{
Expand Down Expand Up @@ -655,6 +674,9 @@ private static Dictionary<string, int> Counts(string text)
Bold = c_crazyFormat,
CodeBlock = c_crazyFormat,
CodeInLine = c_crazyFormat,
CustomContainer = c_crazyFormat,
CustomContainerInfo = c_crazyFormat,
CustomContainerInline = c_crazyFormat,
DefinitionItem = c_crazyFormat,
DefinitionList = c_crazyFormat,
DefinitionTerm = c_crazyFormat,
Expand Down
6 changes: 6 additions & 0 deletions ConsoleMarkdownRenderer.Tests/resources/bracketEscaping.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,9 @@ Paragraph with [test21] reference[^bracketfn] embedded.
: Definition with [test25] bracket content.

[test26] paragraph with :smile: emoji and :-) smiley.

:::note
[test27] note with **[test28] bold** content.
:::

Inline ::tag [test29]:: container.
5 changes: 5 additions & 0 deletions ConsoleMarkdownRenderer.Tests/resources/bracketEscaping.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
│ │ └───────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────┘ │
│ [test26] paragraph with 😄 emoji and 😃 smiley. │
│ ┌───────────────────────────────────────────┐ │
│ │ note │ │
│ │ [test27] note with [test28] bold content. │ │
│ └───────────────────────────────────────────┘ │
│ Inline tag [test29] container. │
│ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── │ │
│ │ ┌───────────────────────────────────────────────────────┐ │ │
Expand Down
9 changes: 9 additions & 0 deletions ConsoleMarkdownRenderer.Tests/resources/customContainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
:::note
This is a sample admonition.
:::

:::warning
A callout with **bold** content.
:::

Text with ::tag inline:: container.
11 changes: 11 additions & 0 deletions ConsoleMarkdownRenderer.Tests/resources/customContainer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
┌──────────────────────────────────┐
│ ┌──────────────────────────────┐ │
│ │ note │ │
│ │ This is a sample admonition. │ │
│ └──────────────────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ warning │ │
│ │ A callout with bold content. │ │
│ └──────────────────────────────┘ │
│ Text with tag inline container. │
└──────────────────────────────────┘
21 changes: 21 additions & 0 deletions DisplayOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ public sealed class DisplayOptions
public TextStyle CodeBlock { get; set; } = new(foreground: TextColor.Yellow, background: TextColor.Blue);
public TextStyle CodeInLine { get; set; } = new(foreground: TextColor.Yellow, background: TextColor.Blue);

/// <summary>
/// Style applied to the body of a <see cref="Markdig.Extensions.CustomContainers.CustomContainer"/>
/// (e.g. an admonition / callout block such as <c>:::note</c>, <c>:::warning</c>, or <c>:::tip</c>).
/// </summary>
public TextStyle CustomContainer { get; set; } = new(decoration: TextDecoration.None);

/// <summary>
/// Style applied to the <see cref="Markdig.Extensions.CustomContainers.CustomContainer.Info"/> label
/// (e.g. <c>note</c> / <c>warning</c> / <c>tip</c>) emitted at the top of a custom container block.
/// </summary>
public TextStyle CustomContainerInfo { get; set; } = new(decoration: TextDecoration.Bold);

/// <summary>
/// Style applied to the contents of an inline
/// <see cref="Markdig.Extensions.CustomContainers.CustomContainerInline"/> (e.g. <c>::tag content::</c>).
/// </summary>
public TextStyle CustomContainerInline { get; set; } = new(decoration: TextDecoration.Bold);

/// <summary>
/// Style applied to the contents of a <see cref="Markdig.Extensions.DefinitionLists.DefinitionItem"/>
/// (all children of each item in a definition list, including its terms and definitions).
Expand Down Expand Up @@ -114,6 +132,9 @@ public sealed class DisplayOptions
Bold = this.Bold,
CodeBlock = this.CodeBlock,
CodeInLine = this.CodeInLine,
CustomContainer = this.CustomContainer,
CustomContainerInfo = this.CustomContainerInfo,
CustomContainerInline = this.CustomContainerInline,
DefinitionItem = this.DefinitionItem,
DefinitionList = this.DefinitionList,
DefinitionTerm = this.DefinitionTerm,
Expand Down
28 changes: 28 additions & 0 deletions ObjectRenderers/ConsoleCustomContainerRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using BoxOfYellow.ConsoleMarkdownRenderer.Styling;
using Markdig.Extensions.CustomContainers;
using Spectre.Console;

namespace BoxOfYellow.ConsoleMarkdownRenderer.ObjectRenderers
{
internal class ConsoleCustomContainerRenderer : ConsoleObjectRenderer<CustomContainer>
{
protected override void Write(ConsoleRenderer renderer, CustomContainer obj)
{
renderer.NewFrame(borderStyle: Style.Plain);
if (!string.IsNullOrEmpty(obj.Info))
{
renderer
.StartInline()
.AddInLine($"[{renderer.Options.CustomContainerInfo.ToSpectreStyle().ToMarkup()}]")
.WriteEscape(obj.Info)
.AddInLine("[/]")
.EndInline();
}
renderer
.PushStyle(renderer.Options.CustomContainer.ToSpectreStyle())
.WriteChildrenChain(obj)
.PopStyle()
.CompleteFrame();
}
}
}
10 changes: 10 additions & 0 deletions ObjectRenderers/ConsoleObjectRenderers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BoxOfYellow.ConsoleMarkdownRenderer.Styling;
using Markdig.Extensions.CustomContainers;
using Markdig.Extensions.DefinitionLists;
using Markdig.Extensions.Footnotes;
using Markdig.Extensions.TaskLists;
Expand Down Expand Up @@ -47,6 +48,15 @@ protected override void Write(ConsoleRenderer renderer, CodeInline obj)
.AddInLine("[/]");
}

internal class ConsoleCustomContainerInlineRenderer : ConsoleObjectRenderer<CustomContainerInline>
{
protected override void Write(ConsoleRenderer renderer, CustomContainerInline obj)
=> renderer
.AddInLine($"[{renderer.Options.CustomContainerInline.ToSpectreStyle().ToMarkup()}]")
.WriteChildrenChain(obj)
.AddInLine("[/]");
}

internal class ConsoleDocumentRenderer : ConsoleObjectRenderer<MarkdownDocument>
{
protected override void Write(ConsoleRenderer renderer, MarkdownDocument obj)
Expand Down
2 changes: 2 additions & 0 deletions ObjectRenderers/ConsoleRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ internal ConsoleRenderer(DisplayOptions options, bool omitAutolinkInlineRenderer
ObjectRenderers.AddRange([
new ConsoleCodeBlockRenderer(),
new ConsoleCodeInlineRenderer(),
new ConsoleCustomContainerInlineRenderer(),
new ConsoleCustomContainerRenderer(),
new ConsoleDefinitionItemRenderer(),
new ConsoleDefinitionListRenderer(),
new ConsoleDefinitionTermRenderer(),
Expand Down
18 changes: 17 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

## Upcoming Changes

### :art: Renderers :art:
- [#132](https://github.com/boxofyellow/ConsoleMarkdownRenderer/pull/132): Render Markdig CustomContainer admonition blocks
- ```markdown
:::note
This is a *note* admonition with **bold** content.
:::
```
- Rendered
:::note
This is a *note* admonition with **bold** content.
:::
- Before
<img width="314" height="22" alt="Image" src="https://github.com/user-attachments/assets/17f529a2-17c3-4a18-bd47-145befff5acb" />
- After
<img width="338" height="58" alt="Image" src="https://github.com/user-attachments/assets/6b66b0fd-9cfa-4b40-8733-236ed5ab4b39" />

### :wrench: Internal Improvements :wrench:
- [#129](https://github.com/boxofyellow/ConsoleMarkdownRenderer/pull/129): Use ConfigureAwait(false) on awaits in published library code
- [#131](https://github.com/boxofyellow/ConsoleMarkdownRenderer/pull/131): Use raw string literals for multi-line AssertCrossPlatStringMatch arguments
Expand Down Expand Up @@ -105,4 +121,4 @@ See the [this project's releases](https://github.com/boxofyellow/ConsoleMarkdown

- [v0.10.0](https://github.com/boxofyellow/ConsoleMarkdownRenderer/blob/main/docs/migration_v0.10.0.md)
- [v0.9.0](https://github.com/boxofyellow/ConsoleMarkdownRenderer/blob/main/docs/migration_v0.9.0.md)
- [v0.8.0](https://github.com/boxofyellow/ConsoleMarkdownRenderer/blob/main/docs/migration_v0.8.0.md)
- [v0.8.0](https://github.com/boxofyellow/ConsoleMarkdownRenderer/blob/main/docs/migration_v0.8.0.md)
Loading