dotnet 使用 ColorCode 做代码着色器

news/2025/1/23 7:25:44/文章来源:https://www.cnblogs.com/lindexi/p/18687046

开源库地址: https://github.com/CommunityToolkit/ColorCode-Universal

我用的是 ColorCode.Core 版本,这个版本是无具体 UI 框架依赖的,于是我就在此基础上,同时做了 WPF 和 Avalonia 框架的版本。这两个框架在对 ColorCode 的使用上近乎毫无差别,大家可以在本文末尾找到本文所有代码的下载方法,下载本文的代码了解两个框架的差异

以下为 WPF 版本的效果图

以下为 Avalonia 版本的效果图

以下是具体的测试逻辑。由于 WPF 和 Avalonia 版本代码几乎没有差别,我这里就使用 WPF 为例子进行演示,完全的代码还请到本文末尾找到下载方法

以下是我编写的一段用来做测试的 C# 测试代码

        var code = """using System;namespace NemficubehayWaybakiwerwhaw.Desktop;class Program{public static void Main(string[] args){Console.WriteLine("Hello, World!");}}""";

咱接下来将对此代码进行着色

编写一个名为 TextEditorCodeColorizer 的类型,让此类型继承 CodeColorizerBase 类型。在此类型里面重写 Write 方法

class TextEditorCodeColorizer : CodeColorizerBase
{protected override void Write(string parsedSourceCode, IList<Scope> scopes){... // 忽略其他代码}

为了能够进行承载着色的代码,我这里使用了之前编写的简单文本库。将其设置进入 TextEditorCodeColorizer 的构造函数,代码如下

class TextEditorCodeColorizer : CodeColorizerBase
{public TextEditorCodeColorizer(TextEditor textEditor, StyleDictionary styles, ILanguageParser languageParser) : base(styles, languageParser){_textEditor = textEditor;}private readonly TextEditor _textEditor;
}

对于使用方来说,创建 TextEditorCodeColorizer 的代码如下

        ILanguage language = Languages.CSharp;var textEditorCodeColorizer = new TextEditorCodeColorizer(TextEditor, null, null);

是的,构造函数的 StyleDictionary 和 ILanguageParser 都传空即可,这个库没有很好处理可空问题

再编写 FormatInlines 方法,让此方法作为接收输入方,代码如下

class TextEditorCodeColorizer : CodeColorizerBase
{public void FormatInlines(string sourceCode, ILanguage language){_textEditor.TextEditorCore.Remove(_textEditor.TextEditorCore.GetAllDocumentSelection());languageParser.Parse(sourceCode, language, (parsedSourceCode, captures) => Write(parsedSourceCode, captures));}
}

具体的调用方法如下

        ILanguage language = Languages.CSharp;var textEditorCodeColorizer = new TextEditorCodeColorizer(TextEditor, null, null);textEditorCodeColorizer.FormatInlines(code, language);

protected override void Write(string parsedSourceCode, IList<Scope> scopes) 方法里面根据 Scope 决定使用什么颜色,代码如下

    protected override void Write(string parsedSourceCode, IList<Scope> scopes){SolidColorBrush colorBrush = Brushes.Black;if (scopes.Count > 0){var name = scopes[0].Name;if (name == "Keyword"){colorBrush = Brushes.Blue;}else if (name == "String"){colorBrush = BrushCreator.CreateFromARGB(0xFFD69D7F);}else if (name == "Number"){colorBrush = BrushCreator.CreateFromARGB(0xFFADCDA8);}else{}}var runProperty = ((RunProperty) _textEditor.CurrentCaretRunProperty) with{Foreground = new ImmutableBrush(colorBrush)};_textEditor.AppendRun(new TextRun(parsedSourceCode, runProperty));}

以上的 BrushCreator 的实现如下

public static class BrushCreator
{public static SolidColorBrush CreateFromARGB(uint argbHex){byte a = (byte) ((argbHex & 0xFF000000) >> 24);byte r = (byte) ((argbHex & 0x00FF0000) >> 16);byte g = (byte) ((argbHex & 0x0000FF00) >> 8);byte b = (byte) (argbHex & 0x000000FF);var brush = new SolidColorBrush(Color.FromArgb(a, r, g, b));return brush;}
}

在 Avalonia 版本里面,直接使用 Skia 作为绘制底层,使用 SKColor.Parse 进行转换颜色字符串,就不需要和 WPF 一样有额外的 BrushCreator 方法,代码如下

    protected override void Write(string parsedSourceCode, IList<Scope> scopes){SKColor color = SKColors.Black;if (scopes.Count > 0){var name = scopes[0].Name;if (name == "Keyword"){color = SKColors.Blue;}else if(name == "String"){color = SKColor.Parse("D69D7F");}else if(name == "Number"){color = SKColor.Parse("ADCDA8");}else{}}_textEditor.AppendRun(new SkiaTextRun(parsedSourceCode, _textEditor.CurrentCaretRunProperty with{Foreground = color}));}

本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 5ba7a51c4f77e516eca886192fbbea4fe90d4a4f

以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 5ba7a51c4f77e516eca886192fbbea4fe90d4a4f

获取代码之后,进入 AvaloniaIDemo/NemficubehayWaybakiwerwhaw 文件夹,即可获取到源代码

更多技术博客,请参阅 博客导航

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873561.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读量子霸权12人工智能

读量子霸权12人工智能1. 人工智能 1.1. 马文明斯基1.1.1. 麻省理工学院教授1.1.2. “人工智能之父”1.2. 人工智能领域似乎每年都有新的突破1.2.1. 数字计算机第一次可以下棋,甚至在简单的游戏中击败人类1.3. 物理学家正在探索单一“统一场论”​,以提供一个连贯、优雅的宇宙…

1. 基于单片机从零写bootloader之第1个bootloader(APP无异常向量表)

1. Bootloader烧写在Flash上,APP也在Flash上直接运行,BootLoader直接跳转到APP位置即可。

VScode配置X11转发!让你彻底摆脱显示屏!!!

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 在我们远程SSH使用开发板或者是服务器开发的时候,你是否总是苦于没有图像显示环境导致OpenCV的cv2.show()操作总是报没有xcb的错?你是否总算是烦恼于在电脑上写完视觉代码想进行验证时还需反复给开发板插…

做题小结-1.23

我今年真的不想打铁了 https://codeforces.com/contest/2049/problem/C这个题 我是优先队列过的 求和次数 最大 实际上 是一个结论题 很重要if ((a + b + c) & 1) {cout << "-1\n";return;}if ((b + a) < c)cout << a + b << nl;elsecout &…

小智带货助手人物模板制作以及抠除视频背景

小智在视频生成过程中,会用到一个必不可少的材料,就是人物模板(可以简单的理解为AI数字人)。人物模板具体要求以及如何制作如下: 1:可以自行用手机录制一段真人出镜的竖版视频,人物上半身出镜即可,建议站立姿势,随意说一段话或者朗读一段文字均可。简单的手势动作以及…

IO复用 select函数

I/O复用使得程序能同时监听多个文件描述符,这对提高程序的性能至关重要。 通常,网络程序在下列情况下需要使用I/O复用技术: 客户端客户端程序要同时处理多个socket。比如非阻塞connect技术。 客户端程序要同时处理用户输入和网络连接。比如聊天室程序。服务器TCP服务器要同时…

25.1.22小记

今天终于涉及到了面向对象中的类与对象的内容,在这里进行简单的记录 封装 : 把数据和对于数据的操作放在一起 对象 : 属性(数据) + 服务(操作) 一般情况,用户只可进行操作,而数据则被保护 自己定义的class可以作为数据类型定义 对象变量是对象的管理者 this : 成员函…

Vue2_引入及基本功能

介绍了 Vue 核心功能,或者说最基本的功能,包括声明式渲染、条件与循环、处理用户输入、组件化应用构建等,声明式渲染包括文本插值和指令两种方法;条件与循环主要是 v-if 和 v-for 这两个指令;处理用户输入涉及 v-on 和 v-model;组件化应用中指明一个组件本质上是一个拥有…

单纯形法原理

单纯形法的原理介绍及python实现代码单纯形法参考连接:单纯形法单纯形法是针对求解线性规划问题的一个算法,这个名称里的 “单纯形” 是代数拓扑里的一个概念,可以简单将“单纯形”理解为一个凸集,标准的线性规划问题(线性规划标准型)可以表示为: \[max\,(or\,min)\quad…

Tomcat 高并发之道原理拆解与性能调优

上帝视角拆解 Tomcat 架构设计,在了解整个组件设计思路之后。我们需要下凡深入了解每个组件的细节实现。从远到近,架构给人以宏观思维,细节展现饱满的美。 上回👉详情点我【Tomcat】Tomcat 架构原理解析到架构设计借鉴 站在上帝视角给大家拆解了 Tomcat 架构设计,分析 To…

Vue3 —— 安装及配置环境

Vue3的安装、配置(✿◕‿◕✿)Vue官网:https://vuejs.org/配置环境终端:Linux和Mac上可以用自带的终端。Windows上推荐用powershell或者cmd。Git Bash有些指令不兼容。安装Node.js:安装地址:https://nodejs.org/en/安装@vue/cli:执行:npm i -g @vue/cli如果执行后面的操作…

二. Redis 超详细的安装教程((七步)一步一步指导,步步附有截屏操作步骤)

二. Redis 超详细的安装教程((七步)一步一步指导,步步附有截屏操作步骤) @目录二. Redis 超详细的安装教程((七步)一步一步指导,步步附有截屏操作步骤)1. Redis 详细安装教程2. Redis 后台基本启动 & 详细的基本使用3. Redis 服务器的关闭和启动的注意事项4. 如何修改 Re…