【Godot4.3】MarkDown编辑和控件事实渲染

news2024/9/24 19:14:52

概述

这是本人2024年5月份左右编写的一个简易的MarkDown编辑和渲染测试项目,基于自己编写的MarkDown解析和生成类MDdoc编写。之前是作为一个试验性的内容混乱的放置在另一个测试项目中,现在独立为一个单独项目。因为测验成功后就一直没改动,所以这仍然是一个很初期的版本。

项目核心

在这里插入图片描述

它的核心是有两部分:

  • MDdoc类:一个MarkDown纯文本解析类,可以将MarkDown文档元素按其顺序解析为对象,从存入内部的数组。每个MarkDown文档元素对应MDdoc的一个内部类:
    • CodebBlock:代码块
    • Headding:标题,H1-H6
    • Paragraph:普通段落
    • Img:图片
    • UL:无序列表
    • OL:有序列表
    • Table:表格
  • 主编辑器:采用传统的左侧编写,右侧渲染的形式。其主要是在左侧编辑器编辑时,利用MDdoc类实时的生成MarkDown元素列表,再借由右侧的一个VBoxContainer顺序渲染相应的控件显示内容。

在这里插入图片描述

编辑器语法高亮

为了让MarkDown代码显得不那么无聊,在对应的CodeEdit上手动用代码添加了一些语法高亮规则。

extends CodeEdit

@export var Hedding_color:= Color.GOLD
@export var codeblock_color:= Color.AQUAMARINE

func _ready() -> void:
	var highlighter = CodeHighlighter.new()
	# H1 - H6
	for i in range(6):
		highlighter.add_color_region("%s " % "#".repeat(i+1)," ",Hedding_color,true)
	
	highlighter.add_color_region("```","```",codeblock_color,false)
	highlighter.add_color_region("- "," ",codeblock_color,true)
	for i in range(100):
		var start = "1. " % (i+1)
		highlighter.add_color_region(start," ",codeblock_color,true)
	#highlighter.add_color_region("- "," ",codeblock_color,true)
	syntax_highlighter = highlighter

实时渲染

mdTest(VBoxContainer)节点上,我们通过遍历MDdoc解析后生成的MarkDown元素数组,并根据对应的元素类型添加不同的控件为mdTest的子节点,从而实现MarkDown内容渲染和显示。

  • 每次调用render,都会先清空mdTest(VBoxContainer)上的所有子节点,然后重新渲染MDdoc解析后生成的MarkDown元素
# ==================== 核心渲染方法 ====================
# 渲染为控件
func render(md):
	# 清空原来的
	for child in get_children():
		remove_child(child)
	# 渲染
	var doc := MDdoc.parse(md)
	for ele in doc._doc:
		if ele is MDdoc.Headding:
			add_child(H(ele.level,ele.text))
		if ele is MDdoc.CodebBlock:
			add_child(CodeBlock(ele.language,ele.code))
		if ele is MDdoc.Paragraph:
			add_child(p(ele.text))
		if ele is MDdoc.UL:
			add_child(ul(ele))
		if ele is MDdoc.OL:
			add_child(ol(ele))
		if ele is MDdoc.Img:
			add_child(img(ele.src,ele.desc))

其中render()_ready()CodeEdit发生文本改变时调用,从而实现运行后的解析和编辑时的实时渲染。

func _ready() -> void:
	render(code_edit.text)

# 文本发生改变时
func _on_code_edit_text_changed() -> void:
	render(code_edit.text)
	pass

为了让代码清晰,为控件生成编写了对应的函数。

# ==================== 获取对应的控件 ====================
# H1- H6
func H(level:int,text:String) -> Label:
	var lab := Label.new()
	lab.text = text
	lab.set("theme_override_font_sizes/font_size",H_size[level-1])
	lab.set("theme_override_colors/font_color",font_color)
	return lab
	
# 段落
func p(text:String) -> Label:
	var lab := Label.new()
	lab.text = text
	lab.set("theme_override_font_sizes/font_size",p_size)
	lab.set("theme_override_colors/font_color",font_color)
	return lab

# 代码块
func CodeBlock(language:String,code:String) -> CodeEdit:
	var txt := CodeEdit.new()
	txt.text = code
	txt.custom_minimum_size.y = 200
	txt.gutters_draw_line_numbers = true
	return txt

# 无序列表
func ul(ele) -> Label:
	var lab := Label.new()
	lab.text = ele.to_string()
	lab.set("theme_override_font_sizes/font_size",p_size)
	lab.set("theme_override_colors/font_color",font_color)
	return lab

# 无序列表
func ol(ele) -> Label:
	var lab := Label.new()
	lab.text = ele.to_string()
	lab.set("theme_override_font_sizes/font_size",p_size)
	lab.set("theme_override_colors/font_color",font_color)
	return lab
# 图片
func img(src:String,desc:String):
	var pic := TextureRect.new()
	pic.expand_mode = TextureRect.EXPAND_FIT_WIDTH
	pic.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
	pic.custom_minimum_size.y = 100
	if load(src):
		pic.texture = load(src)
	else:
		pic.texture = load("res://1.jpeg")
	
	return pic

剩余的就是基础的应用和参数设定了。

extends VBoxContainer

@onready var code_edit: CodeEdit = %CodeEdit

# 文本颜色
@export var font_color:Color = Color.BLACK

# 字号
var H_size = [48,40,36,32,28,26]  # H1-H6字号
var p_size = 20  # 正文字号

其他渲染选择

其实利用VBoxContainer按顺序动态加载控件的形式只是一个很简易甚至粗鄙的形式,完全没有考虑长篇幅文档的性能问题。
在Godot内部,可以选择其他的形式来作为MarkDown内容渲染和显示的选择:

  • RichTextLabel+BBCode:富文本标签,天然支持BBCode语法,也是Godot内置文档的渲染和显示控件,很容易实现,而且可以选择和复制内容
  • 基于绘图函数的渲染:基于CanvasItem的绘图函数,我们可以将MarkDown内容渲染到一个Control

其中RichTextLabel是比较有前途的选项。

代码实时渲染类工具的魅力

其实采用VBoxContainer动态渲染是为了检验一种工具软件类型的可行性,就是代码实时渲染类工具。
它的特点就是一边编写,一边运行代码进行测试。在5月份编写这个工具的同时,我还测试编写了一个用代码测试绘图函数和动画的小工具。

界面和功能分离

MDdoc其实是MarkDown解析和生成的核心,借由这个类,我可以选择不同的MarkDown渲染路线,创建不同的界面,甚至完全不同的程序。甚至也可以将其用于创建游戏项目的内置百科。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IEEE P3233 标准启动会回顾:迈向去中心化存储标准化的第一步

2024 年 8 月 30 日,由 CESS 发起的 IEEE P3233《Standard for Blockchain-Based Decentralized Storage Protocol Specification》标准启动会顺利举行。 此次会议标志着 IEEE P3233 标准制定的正式启动,也代表了去中心化存储技术标准化进程的正式开始。…

数据源10min自动断开连接导致查询抛异常(未获取可用连接)

由于个人能力有限,本文章仅仅代表本人想法,若有不对请即时指出,若有侵权,请联系本人。 1 背景 工作中引入druid来管理数据源连接,由于数据源每隔10分钟强制管理空闲超过10分钟的连接,导致每隔10分钟出现1…

如何构造哈夫曼树

目录 一、哈夫曼树的概念 1、结点的权: 2、结点的带权路径长度 3、树的带权路径长度 4、哈夫曼树 二、哈夫曼树的构造 1、构造步骤 三、哈夫曼树的编码 一、哈夫曼树的概念 1、结点的权: 定义: 每个结点的权重(重要性…

fork入门

1哪个分支会打印 如下是fork的典型问题。fork之后有3个分支,分别是pid等于0,pid大于0,pid小于0。如果我们不了解fork的话,那么肯定会认为这里的if else分支只会有一个分支被执行。而实际的执行结果是两个分支都执行了。fork返回之…

客流预测 | 基于Transformer下车站点客流推断研究(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于Transformer的车站客流推断研究是指利用Transformer模型来预测车站的客流情况。Transformer是一种强大的深度学习模型,特别擅长处理序列数据。研究可以为城市交通管理提供重要决策支持,帮…

恢复丢失的数据:iPhone 恢复指南

不小心删除了 iPhone 上的重要数据并意识到它没有备份?您并不孤单。在 iPhone 上恢复永久删除的数据似乎令人生畏,但并非总是不可能。我们将探索各种方法,包括使用专门的软件和备份恢复选项,为您提供恢复丢失数据的最佳机会。 常见…

裸机:LCD

什么是LCD? LCD,全称为Liquid Crystal Display,即液晶显示屏,是一种利用液晶物质的光学特性,通过控制电场来改变光的透过性,从而实现图像显示的技术。以下是关于LCD的详细解释: 一、LCD的基本…

ElementPlus实现页面,上部分是表单,下部分是表格

效果 <template><el-dialog v-model"produceDialogFormVisible" draggable custom-class"dialog-title" :title"title" :close-on-click-modal"false"><el-form label-width"120px"><el-row :gutter&q…

【STM32H743】将全局变量定义到指定内存MDK

STM32H743将全局变量定义到指定内存MDK 2024年8月31日 #elecEngeneer 上链 参考硬汉嵌入式。 这样Target里面的设置就作废了。 把H743的几个SRAM写上 ; ************************************************************* ; *** Scatter-Loading Description File generated by…

5G智慧工地项目汇报方案

1. 项目概述 5G智慧工地项目旨在通过5G技术提升建筑工地的通信、安防、质量管理和精益化管理水平&#xff0c;打造科技感十足的“5G智慧建造体验中心”。 2. 智慧工地需求 当前智慧工地需求集中在实时化、可视化、多元化、智慧化和便捷化&#xff0c;以满足全时段安全管理和…

《机器学习》周志华-CH4(决策树)

4.1基本流程 决策树是一类常见的机器学习方法&#xff0c;又称“判别树”&#xff0c;决策过程最终结论对应了我们所希望的判定结果。 一棵决策树 { 一个根结点 包含样本全集 若干个内部结点 对应属性测试&#xff0c;每个结点包含的样本集合根据属性测试结果划分到子结点中 若…

基于ssm+vue的汽车租赁管理系统

摘要 随着移动应用技术的发展&#xff0c;越来越多的用户借助于移动手机、电脑完成生活中的事务&#xff0c;许多的传统行业也更加重视与互联网的结合&#xff0c;以提高商家知名度和寻求更高的经济利益。针对传统汽车租赁系统&#xff0c;租赁信息、续租信息等问题&#xff0c…

第4章-07-将WebDriver获取的Cookie传递给Requests

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年CSDN全站百大博主。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于专栏:Web爬虫入门与实战精讲,后续完整更新内容如下。 文章…

linux下基本指令(持续更新)

目录 1.adduser 2.passwd 3.userdel 4. su - 5.ls 6.pwd ​编辑 7.cd 8.touch 9.mkdir &#x1f680; 10. rmdir && rm &#x1f680; 11.whoami &#xff08;who am i) 12.clear 13.tree (需要安装 yum install -y tree) 14.who 1.adduser 语法&…

TCP协议(1)

目录 一、TCP协议介绍 二、TCP协议格式 2.1、解包与分用 2.2、TCP的可靠性 2.3、TCP的工作模式 2.4、确认应答(ACK)机制 2.5、32位序号与确认序号 2.6 16位窗口大小 2.7 六个标志位 2.7.1、SYN 2.7.2、FIN 2.7.3、ACK 2.7.4、PSH 2.7.5、URG 2.7.6、RST 2.8、T…

Arco Voucher - 不知道有什么用的凭证单据录入表单插件

关于 Arco Voucher Arco Voucher 插件是一款不知道有什么用的凭证单据录入表单插件&#xff0c;可能只是为了看着像传统的凭证单据。 动态表头 附件上传/预览 添加凭证明细 https://apps.odoo.com/apps/modules/browse?authorzerone40 如有插件定制化需求或其他插件资源…

MATLAB智能优化算法-学习笔记(2)——变邻域搜索算法求解旅行商问题【过程+代码】

旅行商问题 (TSP) 旅行商问题(Traveling Salesman Problem, TSP)是经典的组合优化问题之一。问题的描述是:给定若干个城市以及每对城市之间的距离,一个旅行商需要从某个城市出发,访问每个城市恰好一次,最后回到出发城市,目标是找到一条总距离最短的环路。TSP 是 NP-har…

通用 PDF OCR 到 Word API 数据接口

通用 PDF OCR 到 Word API 数据接口 文件处理&#xff0c;OCR&#xff0c;PDF 高可用图像识别引擎&#xff0c;基于机器学习&#xff0c;超精准识别率。 1. 产品功能 通用识别接口&#xff1b;支持中英文等多语言字符混合识别&#xff1b;formdata 格式 PDF 文件流传参&#xf…

MySql执行计划(Explain关键字详解)

文章目录 预备知识学习本内容的前提必须了解1.什么是Explain?2.如何使用Explain?3.explain字段详解3.1、ID字段(情况1)、id值不同:(情况2)、id值相同:(情况3)、id列为null:(情况4)、子查询优化后3.2、select_type字段:表示那个是主要的查询1.simmple:2.primary:3.derived:…

WeStorm(没有指向JVM)

##一直困扰了好久&#xff0c;之前打开IDEA会弹出这个&#xff1a; 然后重启IDEA就没弹出来了。但是的但是&#xff0c;最近打开WebStorm也弹出来这个&#xff0c;重启也解决不了&#xff0c;一开始以为是JDK的问题&#xff0c;但是检查了好几遍&#xff0c;发现都没问题&…