赞
踩
之前在《【Godot4.2】Tree控件自定义树形数据ETD及其解析》一文中,实现了对带缩进的层级结构文本的解析,并将其用于Tree控件的列表项构造。
不过当时并没有实现专门的类,今天花了一点时间实现了一下。现在可以更方便的构造和解析ETD数据,并转化为其他格式。
并且EasyTreeData类,可以被理解为一个树型数据结构,可以基于它构造数据结构中的树。
本篇就介绍一下这个类的使用方法。
# ======================================================== # 名称:EasyTreeData # 类型:类 # 简介:专用于构造树形结构数据的类 # 作者:巽星石 # Godot版本:v4.2.2.stable.official [15073afe3] # 创建时间:2024年4月29日23:20:02 # 最后修改时间:2024年4月30日00:57:15 # ======================================================== class_name EasyTreeData var _root:EasyTreeItem # ============================ 内部类 ============================ # 单项数据 class EasyTreeItem: var data:String var deep:int var parent:EasyTreeItem var children:Array[EasyTreeItem] func _init(_data:String,_deep:int) -> void: data = _data deep = _deep children = [] # 输出ETD多行文本格式 func _to_string() -> String: var sttr:= "%s%s\n" % ["\t".repeat(deep),data] for child in children: sttr += child.to_string() return sttr # 输出MarkDown带缩进无序列表字符串 func to_MD_ul() -> String: var sttr:= "%s- %s\n" % ["\t".repeat(deep),data] for child in children: sttr += child.to_MD_ul() return sttr # 输出可识别的LaTex总结字符串 func to_LaTex() -> String: var list_str = "\n/begin{cases}\n%s/end{cases}\n" var sttr:= "%s%s" if children.size()!=0: var subs = "" for child in children: subs += child.to_LaTex() + "//\n" sttr = sttr % [data,list_str % subs] else: sttr = sttr % [data,""] return sttr.replace("/","\\") # ============================ 虚函数 ============================ # 转化为字符串 func _to_string() -> String: return "" if !_root else _root.to_string() # 返回ETD多行文本 func get_data() -> String: return _to_string() # 输出MarkDown带缩进无序列表字符串 func to_MD_ul() -> String: return "" if !_root else _root.to_MD_ul() func to_LaTex() -> String: return "" if !_root else _root.to_LaTex() # ============================ 方法 ============================ # 创建并返回一个EasyTreeItem实例 func create_item(text:String,p_node:EasyTreeItem = null) -> EasyTreeItem: var itm = EasyTreeItem.new(text,0) if _root: if p_node: itm.deep = p_node.deep + 1 itm.parent = p_node p_node.children.append(itm) else: itm.deep = _root.deep + 1 itm.parent = _root _root.children.append(itm) else: _root = itm return itm # 由多行文本创建 static func new_with_etd_str(etd_str:String) ->EasyTreeData: var edt = EasyTreeData.new() var items = etd_str.split("\n",false) # 将ETD字符串按行切分为字符串数组 var pre_itm:EasyTreeItem # 记录前一项 var p_itm:EasyTreeItem = null # 记录父节点 # 遍历每行数据 for i in range(items.size()): # 第1行直接添加为Tree控件的根节点(跳过下面if部分) # 从第2行开始比较当前行与前一行的缩进深度(也就是\t的数目) if i > 0: var d_deep = deep(items[i-1]) - deep(items[i]) # 与前一行数据的缩进差值 match d_deep: -1: # 缩进比前一项深: p_itm = pre_itm # 将前一项作为父节点 0: # 缩进深度与前一项一样: p_itm = pre_itm.parent # 父节点与前一项父节点一样 _: if d_deep>0: # 缩进比前一项浅 # 通过缩进差值计算获得合适的父节点 p_itm = pre_itm for j in range(d_deep+1): p_itm = p_itm.parent # 实际创建和添加TreeItem到Tree控件 var itm:EasyTreeItem = edt.create_item(items[i].replace("\t",""),p_itm) pre_itm = itm # 将当前项记录为前一项 return edt # 返回字符串的Tab缩进值 static func deep(sttr:String): return sttr.rstrip(" ").count("\t")
EasyTreeData
在使用和API名称上模仿了Godot的Tree
控件和TreeItem
类。所以熟悉Tree
控件和TreeItem
的Godoter可以直接零难度上手。
var edt = EasyTreeData.new() # 创建实例
# 创建根节点
var root = edt.create_item("根节点")
var itm = edt.create_item("节点1",root) # 创建根节点的子节点
print(edt) # 打印输出相应的EDT字符串
输出:
根节点
节点1
你可以用多行文本形式构造一个ETD数据字符串,也就是一个带层级关系和缩进关系的多行文本:
var etd = """
条目1
条目1.1
条目1.2
条目1.2.1
条目1.2.2
条目1.3
"""
通过调用new_with_etd_str()
静态方法,并传入上面的ETD数据字符串,可以构造一个新的EasyTreeData
实例。
var edt = EasyTreeData.new_with_etd_str(etd)
print(edt)
输出:
条目1
条目1.1
条目1.2
条目1.2.1
条目1.2.2
条目1.3
可以看到与传入的ETD数据字符串一致,但是你可以在此基础上继续添加新的数据项。
print(edt.to_MD_ul())
输出:
- 条目1
- 条目1.1
- 条目1.2
- 条目1.2.1
- 条目1.2.2
- 条目1.3
这段代码可以直接粘贴到MarkDown编辑器中,变为带层级的无序列表样式,效果如下:
print(edt.to_LaTex())
输出:
条目1
\begin{cases}
条目1.1\\
条目1.2
\begin{cases}
条目1.2.1\\
条目1.2.2\\
\end{cases}
\\
条目1.3\\
\end{cases}
粘贴到MarkDown编辑器的LaTex公式中,显示为:
条
目
1
{
条
目
1.1
条
目
1.2
{
条
目
1.2.1
条
目
1.2.2
条
目
1.3
条目1 \begin{cases} 条目1.1\\ 条目1.2 \begin{cases} 条目1.2.1\\ 条目1.2.2\\ \end{cases}
基于此,我们可以很方便的通过简单的层级缩进文本,或者Markdown中带层级缩进的无序列表,实现比较复杂的Latex公式总结笔记的转化。
比如,我们构造如下的ETD字符串:
数据结构
线性结构
栈
队列
双端列表
列表
非线性结构
图
树
生成的总结笔记:
数
据
结
构
{
线
性
结
构
{
栈
队
列
双
端
列
表
列
表
非
线
性
结
构
{
图
树
数据结构 \begin{cases} 线性结构 \begin{cases} 栈\\ 队列\\ 双端列表\\ 列表\\ \end{cases}
可以将ETD多行文本形式转化为如下的括号嵌套结构的单行字符串。这样更容易压缩存储。
此外,也可以编写相应函数来解析为树形结构数据。
条目1[条目1.1,条目1.2[条目1.2.1,条目1.2.2]条目1.3]
在上面基础上,我们可以获取对应的字典以及JSON字符串。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。