dotnet 利用 ColorCode 做代码着色器

打印 上一主题 下一主题

主题 898|帖子 898|积分 2694

本文记录我利用 ColorCode 开源库简朴做一个代码着色器
开源库地点: https://github.com/CommunityToolkit/ColorCode-Universal
我用的是 ColorCode.Core 版本,这个版本是无具体 UI 框架依赖的,于是我就在此基础上,同时做了 WPF 和 Avalonia 框架的版本。这两个框架在对 ColorCode 的利用上近乎毫无差异,大家可以在本文末尾找到本文所有代码的下载方法,下载本文的代码相识两个框架的差异
以下为 WPF 版本的效果图

以下为 Avalonia 版本的效果图

以下是具体的测试逻辑。由于 WPF 和 Avalonia 版本代码几乎没有差异,我这里就利用 WPF 为例子举行演示,完全的代码还请到本文末尾找到下载方法
以下是我编写的一段用来做测试的 C# 测试代码
  1.         var code = """
  2.                    using System;
  3.                    namespace NemficubehayWaybakiwerwhaw.Desktop;
  4.                    class Program
  5.                    {
  6.                        public static void Main(string[] args)
  7.                        {
  8.                            Console.WriteLine("Hello, World!");
  9.                        }
  10.                    }
  11.                    """;
复制代码
咱接下来将对此代码举行着色
编写一个名为 TextEditorCodeColorizer 的范例,让此范例继续 CodeColorizerBase 范例。在此范例里面重写 Write 方法
  1. class TextEditorCodeColorizer : CodeColorizerBase
  2. {
  3.     protected override void Write(string parsedSourceCode, IList<Scope> scopes)
  4.     {
  5.         ... // 忽略其他代码
  6.     }
复制代码
为了能够举行承载着色的代码,我这里利用了之前编写的简朴文本库。将其设置进入 TextEditorCodeColorizer 的构造函数,代码如下
  1. class TextEditorCodeColorizer : CodeColorizerBase
  2. {
  3.     public TextEditorCodeColorizer(TextEditor textEditor, StyleDictionary styles, ILanguageParser languageParser) : base(styles, languageParser)
  4.     {
  5.         _textEditor = textEditor;
  6.     }
  7.     private readonly TextEditor _textEditor;
  8. }
复制代码
对于利用方来说,创建 TextEditorCodeColorizer 的代码如下
  1.         ILanguage language = Languages.CSharp;
  2.         var textEditorCodeColorizer = new TextEditorCodeColorizer(TextEditor, null, null);
复制代码
是的,构造函数的 StyleDictionary 和 ILanguageParser 都传空即可,这个库没有很好处理可空问题
再编写 FormatInlines 方法,让此方法作为接收输入方,代码如下
  1. class TextEditorCodeColorizer : CodeColorizerBase
  2. {
  3.     public void FormatInlines(string sourceCode, ILanguage language)
  4.     {
  5.         _textEditor.TextEditorCore.Remove(_textEditor.TextEditorCore.GetAllDocumentSelection());
  6.         languageParser.Parse(sourceCode, language, (parsedSourceCode, captures) => Write(parsedSourceCode, captures));
  7.     }
  8. }
复制代码
具体的调用方法如下
  1.         ILanguage language = Languages.CSharp;
  2.         var textEditorCodeColorizer = new TextEditorCodeColorizer(TextEditor, null, null);        textEditorCodeColorizer.FormatInlines(code, language);
复制代码
在 protected override void Write(string parsedSourceCode, IList scopes) 方法里面根据 Scope 决定利用什么颜色,代码如下
  1.     protected override void Write(string parsedSourceCode, IList<Scope> scopes)
  2.     {
  3.         SolidColorBrush colorBrush = Brushes.Black;
  4.         if (scopes.Count > 0)
  5.         {
  6.             var name = scopes[0].Name;
  7.             if (name == "Keyword")
  8.             {
  9.                 colorBrush = Brushes.Blue;
  10.             }
  11.             else if (name == "String")
  12.             {
  13.                 colorBrush = BrushCreator.CreateFromARGB(0xFFD69D7F);
  14.             }
  15.             else if (name == "Number")
  16.             {
  17.                 colorBrush = BrushCreator.CreateFromARGB(0xFFADCDA8);
  18.             }
  19.             else
  20.             {
  21.             }
  22.         }
  23.         var runProperty = ((RunProperty) _textEditor.CurrentCaretRunProperty) with
  24.         {
  25.             Foreground = new ImmutableBrush(colorBrush)
  26.         };
  27.         _textEditor.AppendRun(new TextRun(parsedSourceCode, runProperty));
  28.     }
复制代码
以上的 BrushCreator 的实现如下
  1. public static class BrushCreator
  2. {
  3.     public static SolidColorBrush CreateFromARGB(uint argbHex)
  4.     {
  5.         byte a = (byte) ((argbHex & 0xFF000000) >> 24);
  6.         byte r = (byte) ((argbHex & 0x00FF0000) >> 16);
  7.         byte g = (byte) ((argbHex & 0x0000FF00) >> 8);
  8.         byte b = (byte) (argbHex & 0x000000FF);
  9.         var brush = new SolidColorBrush(Color.FromArgb(a, r, g, b));
  10.         return brush;
  11.     }
  12. }
复制代码
在 Avalonia 版本里面,直接利用 Skia 作为绘制底层,利用 SKColor.Parse 举行转换颜色字符串,就不需要和 WPF 一样有额外的 BrushCreator 方法,代码如下
  1.     protected override void Write(string parsedSourceCode, IList<Scope> scopes)
  2.     {
  3.         SKColor color = SKColors.Black;
  4.         if (scopes.Count > 0)
  5.         {
  6.             var name = scopes[0].Name;
  7.             if (name == "Keyword")
  8.             {
  9.                 color = SKColors.Blue;
  10.             }
  11.             else if(name == "String")
  12.             {
  13.                 color = SKColor.Parse("D69D7F");
  14.             }
  15.             else if(name == "Number")
  16.             {
  17.                 color = SKColor.Parse("ADCDA8");
  18.             }
  19.             else
  20.             {
  21.                
  22.             }
  23.         }
  24.         _textEditor.AppendRun(new SkiaTextRun(parsedSourceCode, _textEditor.CurrentCaretRunProperty with
  25.         {
  26.             Foreground = color
  27.         }));
  28.     }
复制代码
本文代码放在 githubgitee 上,可以利用如下命令行拉取代码。我整个代码堆栈比较庞大,利用以下命令行可以举行部分拉取,拉取速率比较快
先创建一个空文件夹,接着利用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
  1. git init
  2. git remote add origin https://gitee.com/lindexi/lindexi_gd.git
  3. git pull origin 5ba7a51c4f77e516eca886192fbbea4fe90d4a4f
复制代码
以上利用的是国内的 gitee 的源,如果 gitee 不能访问,请更换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源举行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码
  1. git remote remove origin
  2. git remote add origin https://github.com/lindexi/lindexi_gd.git
  3. git pull origin 5ba7a51c4f77e516eca886192fbbea4fe90d4a4f
复制代码
获取代码之后,进入 AvaloniaIDemo/NemficubehayWaybakiwerwhaw 文件夹,即可获取到源代码
更多技术博客,请参阅 博客导航

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表