using AIStudio.Tools.CodeHighlighting;
using Microsoft.AspNetCore.Components.Rendering;
namespace AIStudio.Components;
///
/// Renders Markdown the way MudMarkdown does, and highlights the code blocks of more languages than
/// the library does, such as Python or SQL.
///
///
/// MudBlazor.Markdown highlights only a few languages itself, and its highlighter is internal.
/// MudMarkdown renders every code block through RenderCodeBlock, though, and lets us override that.
/// A block in one of the languages of CodeHighlighters becomes a HighlightedCodeBlock; any other block
/// stays as the library renders it. A block which names no language gets the one its code is written in,
/// see CodeLanguageDetector, the same as when it is saved as a file.
///
public class HighlightedMarkdown : MudMarkdown
{
///
/// The text of a code block: its lines, each with the line break it came with.
///
/// The code block, as Markdig read it.
/// The text of the block.
internal static string TextOf(Markdig.Syntax.CodeBlock code) => code.Lines.ToString();
#region Overrides of MudMarkdown
///
protected override void RenderCodeBlock(in RenderTreeBuilder builder, ref int elementIndex, in Markdig.Syntax.CodeBlock code, in string? info)
{
var text = TextOf(code);
var language = CodeLanguageDetector.FenceLanguageOf(info, text);
if (!CodeHighlighters.TryGetRules(language, out _))
{
//
// The copy button of the library confirms in the language of the app, as ours does:
//
this.Styling.CodeBlock.CopyButtonText = CodeBlockCopyButton.ConfirmationText;
base.RenderCodeBlock(builder, ref elementIndex, code, language);
return;
}
//
// Our frames are numbered by their place in this method, as Blazor asks for. The frames of
// the library keep the running count it hands through every render method instead:
//
builder.OpenComponent(0);
builder.AddComponentParameter(1, nameof(HighlightedCodeBlock.Code), text);
builder.AddComponentParameter(2, nameof(HighlightedCodeBlock.Language), language);
builder.CloseComponent();
}
#endregion
}