添加项目文件。
This commit is contained in:
100
Szmedi.AIScriptRunner/RvScript/ColorCodeBlockRenderer.cs
Normal file
100
Szmedi.AIScriptRunner/RvScript/ColorCodeBlockRenderer.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
|
||||
using ColorCode;
|
||||
using ColorCode.Styling;
|
||||
|
||||
using Markdig.Parsers;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Renderers.Wpf;
|
||||
using Markdig.Syntax;
|
||||
using Markdig.Wpf;
|
||||
|
||||
namespace Szmedi.AIScriptRunner.RvScript;
|
||||
|
||||
public class ColorCodeBlockRenderer : WpfObjectRenderer<CodeBlock>
|
||||
{
|
||||
private readonly CodeBlockRenderer _underlyingCodeBlockRenderer;
|
||||
private readonly StyleDictionary _styleDictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ColorCodeBlockRenderer"/> with the specified <paramref name="underlyingCodeBlockRenderer"/> and <paramref name="styleDictionary"/>.
|
||||
/// </summary>
|
||||
/// <param name="underlyingCodeBlockRenderer">The underlying CodeBlockRenderer to handle unsupported languages.</param>
|
||||
/// <param name="styleDictionary">A StyleDictionary for custom styling.</param>
|
||||
public ColorCodeBlockRenderer(CodeBlockRenderer underlyingCodeBlockRenderer, StyleDictionary styleDictionary)
|
||||
{
|
||||
_underlyingCodeBlockRenderer = underlyingCodeBlockRenderer;
|
||||
_styleDictionary = styleDictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified <paramref name="codeBlock"/> to the <paramref name="renderer"/>.
|
||||
/// </summary>
|
||||
/// <param name="renderer">The renderer.</param>
|
||||
/// <param name="codeBlock">The code block to render.</param>
|
||||
protected override void Write(WpfRenderer renderer, CodeBlock codeBlock)
|
||||
{
|
||||
if (codeBlock is not FencedCodeBlock fencedCodeBlock ||
|
||||
codeBlock.Parser is not FencedCodeBlockParser fencedCodeBlockParser)
|
||||
{
|
||||
_underlyingCodeBlockRenderer.Write(renderer, codeBlock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var language = ExtractLanguage(fencedCodeBlock, fencedCodeBlockParser);
|
||||
|
||||
if (language is null)
|
||||
{
|
||||
_underlyingCodeBlockRenderer.Write(renderer, codeBlock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var code = ExtractCode(codeBlock);
|
||||
var formatter = new RichTextBoxFormatter(_styleDictionary);
|
||||
var paragraph = new Paragraph();
|
||||
paragraph.SetResourceReference(FrameworkContentElement.StyleProperty, Styles.CodeBlockStyleKey);
|
||||
formatter.FormatInlines(code, language, paragraph.Inlines);
|
||||
|
||||
renderer.WriteBlock(paragraph);
|
||||
}
|
||||
|
||||
private static ILanguage? ExtractLanguage(IFencedBlock fencedCodeBlock, FencedCodeBlockParser parser)
|
||||
{
|
||||
var languageId = fencedCodeBlock.Info!.Replace(parser.InfoPrefix!, string.Empty);
|
||||
|
||||
return string.IsNullOrWhiteSpace(languageId) ? null : Languages.FindById(languageId);
|
||||
}
|
||||
|
||||
private static string ExtractCode(LeafBlock leafBlock)
|
||||
{
|
||||
var code = new StringBuilder();
|
||||
var lines = leafBlock.Lines.Lines;
|
||||
//var totalLines = lines.Length;
|
||||
var totalLines = lines == null ? 0 : lines.Length;
|
||||
for (var index = 0; index < totalLines; index++)
|
||||
{
|
||||
var line = lines[index];
|
||||
var slice = line.Slice;
|
||||
|
||||
if (slice.Text == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var lineText = slice.Text.Substring(slice.Start, slice.Length);
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
code.AppendLine();
|
||||
}
|
||||
|
||||
code.Append(lineText);
|
||||
}
|
||||
|
||||
return code.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user