Class
Sealed
public sealed class LinkCardsRenderer : HtmlObjectRenderer<Moka.Docs.Parsing.Markdown.LinkCardsBlock>
Namespace: Moka.Docs.Parsing.Markdown
Renders a link-cards block as a responsive grid.
Inheritance
Inherits from: HtmlObjectRenderer<Moka.Docs.Parsing.Markdown.LinkCardsBlock>
Methods
| Name | Description |
|---|---|
Write(HtmlRenderer renderer, LinkCardsBlock block) override |
Type Relationships
classDiagram
style LinkCardsRenderer fill:#f9f,stroke:#333,stroke-width:2px
LinkCardsRenderer --|> LinkCardsBlock~ : inherits
View Source
/// <summary>
/// Renders a link-cards block as a responsive grid.
/// </summary>
public sealed class LinkCardsRenderer : HtmlObjectRenderer<LinkCardsBlock>
{
/// <inheritdoc/>
protected override void Write(HtmlRenderer renderer, LinkCardsBlock block)
{
renderer.EnsureLine();
renderer.Write("<div class=\"component-link-cards\">");
renderer.WriteLine();
// Walk through the AST to find list items with links
foreach (Block child in block)
{
if (child is ListBlock list)
{
foreach (Block listItem in list)
{
if (listItem is ListItemBlock item)
{
RenderLinkCard(renderer, item);
}
}
}
}
renderer.Write("</div>");
renderer.WriteLine();
}
private static void RenderLinkCard(HtmlRenderer renderer, ListItemBlock item)
{
// Extract the link and description from the list item
string? href = null;
string? title = null;
string? description = null;
foreach (Block block in item)
{
if (block is ParagraphBlock para && para.Inline != null)
{
foreach (Inline inline in para.Inline)
{
if (inline is LinkInline link)
{
href = link.Url;
// Get link text
var sb = new StringBuilder();
foreach (Inline linkChild in link)
{
if (linkChild is LiteralInline lit)
{
sb.Append(lit.Content);
}
}
title = sb.ToString();
}
else if (inline is LiteralInline literal)
{
string text = literal.Content.ToString().Trim();
// The description follows " — " or " - " after the link
if (text.StartsWith("—") || text.StartsWith("-"))
{
description = text.TrimStart('—', '-', ' ');
}
else if (!string.IsNullOrWhiteSpace(text))
{
description = text;
}
}
}
}
}
if (string.IsNullOrEmpty(href) || string.IsNullOrEmpty(title))
{
return;
}
renderer.Write($"<a class=\"component-link-card\" href=\"{href}\">");
renderer.WriteLine();
renderer.Write("<div class=\"component-link-card-content\">");
renderer.WriteLine();
renderer.Write($"<span class=\"component-link-card-title\">{title}</span>");
renderer.WriteLine();
if (!string.IsNullOrEmpty(description))
{
renderer.Write($"<span class=\"component-link-card-desc\">{description}</span>");
renderer.WriteLine();
}
renderer.Write("</div>");
renderer.WriteLine();
renderer.Write("<span class=\"component-link-card-arrow\">");
renderer.Write("<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"/></svg>");
renderer.Write("</span>");
renderer.WriteLine();
renderer.Write("</a>");
renderer.WriteLine();
}
}