MDCreater.gd
基本信息
脚本信息
项目 | 信息 |
---|
文件名 | MDCreater.gd | is_tool | 否 | extend | - | class_name | - |
文件信息
项目 | 信息 |
---|
项目名称 | myAdd插件v3.0 | 文件路径 | res://addons/myAdd/lib/MDCreater.gd | 绝对路径 | E:/【Godot-项目】/myAdd插件v3.0/addons/myAdd/lib/MDCreater.gd |
其他信息
项目 | 信息 |
---|
作者 | @巽星石 | 备注 | 源码与本文档一起开放,任何人任何使用方式都可以。 一切在此基础上的修改也好,开源也好,闭源也好,商用都可以,也无需著名原作者。 |
文档信息
项目 | 信息 |
---|
文档创建时间 | 2022-09-24 23:13:18 |
概述
这是一个基于Godot3.5的GDScript编写的脚本快速生成Markdown的静态函数库。
其中主要包含Markdown语法生成相关的函数以及生成和保存脚本文档的函数。
用途及用法
1.用于快速生成Markdown文档的源码
你可以使用其中的Markdown语法生成相关的函数来快速生成Markdown文档的源码。
例如像下面这样:
code_editor.text += md.TOC()
code_editor.text += md.quote("这是一个单行引用")
code_editor.text += md.quote("这是一个单行引用2\n22")
code_editor.text += md.H(1,"MDCreater测试")
code_editor.text += md.H(2,"代码块")
code_editor.text += md.Code_Block(self.get_script().source_code,"gdscript") # 显示源码自身
code_editor.text += md.HR()
code_editor.text += md.H(2,"表格")
code_editor.text += md.TH(["属性","值类型","默认值","描述"])
code_editor.text += md.TR(["name","Sting","\"\"","名称"])
code_editor.text += md.TR(["age","int","0","年龄"])
code_editor.text += md.TR(["sex","int","0","性别"])
code_editor.text += md.HR()
code_editor.text += md.H(2,"超链接")
code_editor.text += md.link("https://www.baidu.com/","摆烂的百度")
code_editor.text += md.H(2,"图片")
code_editor.text += md.img("res://360截图20220919201410658.png","项目封面图")
code_editor.text += md.H(2,"列表")
code_editor.text += md.P("列表是用于展示并列信息的。\n分为有序列表和无序列表。")
code_editor.text += md.H(3,"有序列表")
code_editor.text += md.OL(
[
"有序列表是带有编号的列表",
"通常用于表示步骤等"
]
)
code_editor.text += md.H(3,"无序列表")
code_editor.text += md.UL(
[
"无序列表是不带编号的列表",
"通常用于纯粹并列的条目和内容。"
]
)
上面的代码会获得符合Markdown语法的字符串:
@[toc]
> 这是一个单行引用
> 这是一个单行引用2
> 22
# MDCreater测试
## 代码块
```gdscript
extends Control
var md = MDCreater.new()
onready var code_editor = $codeEditor
func _ready():
# md.GDscript_MD(get_script(),"res://22.md")
# md.GDscript_MD_by_path("res://addons/myAdd/lib/MDCreater.gd","res://MDCreater.md")
# md.GDscript_MD_by_path("res://addons/myTreeAdd/lib/GDEditor.gd","res://GDEditor.md")
code_editor.text += md.TOC()
code_editor.text += md.quote("这是一个单行引用")
code_editor.text += md.quote("这是一个单行引用2\n22")
code_editor.text += md.H(1,"MDCreater测试")
code_editor.text += md.H(2,"代码块")
code_editor.text += md.Code_Block(self.get_script().source_code,"gdscript") # 显示源码自身
code_editor.text += md.HR()
code_editor.text += md.H(2,"表格")
code_editor.text += md.TH(["属性","值类型","默认值","描述"])
code_editor.text += md.TR(["name","Sting","\"\"","名称"])
code_editor.text += md.TR(["age","int","0","年龄"])
code_editor.text += md.TR(["sex","int","0","性别"])
code_editor.text += md.HR()
code_editor.text += md.H(2,"超链接")
code_editor.text += md.link("https://www.baidu.com/","摆烂的百度")
code_editor.text += md.H(2,"图片")
code_editor.text += md.img("res://360截图20220919201410658.png","项目封面图")
code_editor.text += md.H(2,"列表")
code_editor.text += md.P("列表是用于展示并列信息的。\n分为有序列表和无序列表。")
code_editor.text += md.H(3,"有序列表")
code_editor.text += md.OL(
[
"有序列表是带有编号的列表",
"通常用于表示步骤等"
]
)
code_editor.text += md.H(3,"无序列表")
code_editor.text += md.UL(
[
"无序列表是不带编号的列表",
"通常用于纯粹并列的条目和内容。"
]
)
pass
```
------
## 表格
| 属性 | 值类型 | 默认值 | 描述 |
| --- |--- |--- |--- |
| name |Sting |"" |名称 |
| age |int |0 |年龄 |
| sex |int |0 |性别 |
------
## 超链接
[摆烂的百度](https://www.baidu.com/)
## 图片
![项目封面图](res://360截图20220919201410658.png)
## 列表
列表是用于展示并列信息的。
分为有序列表和无序列表。
### 有序列表
0. 有序列表是带有编号的列表
1. 通常用于表示步骤等
### 无序列表
- 无序列表是不带编号的列表
- 通常用于纯粹并列的条目和内容。
2.用于生成GDScript脚本文件的文档
就像你看到的这个文档一样,MDCreater可以使用GDscript_MD_by_path()方法生成GDScript脚本文件的Markdown文档。当然只是一个框架,方便继续修改和填充。
var md = MDCreater.new() # 创建MDCreater实例
# 调用GDscript_MD_by_path()方法
# 传入要生成文档的脚本路径,以及生成的文档的保存路径
md.GDscript_MD_by_path("res://addons/myAdd/lib/MDCreater.gd","res://MDCreater.md")
你也可以使用GDscript_MD()方法,传入的第一个参数变为一个gdscript对象。
var md = MDCreater.new() # 创建MDCreater实例
md.GDscript_MD_by_path(get_script(),"res://22.md")
上面的代码如果用在某个打开的场景的脚本中,将会直接生成该这个脚本的Markdown文档。
信号
信号 | 描述 |
---|
click() | | dbl_click(name,button) | |
枚举
aa
aa2
属性
导出变量
变量 | 值类型 | 默认值 | 描述 |
---|
export(String,“12”,“34”) var title | String | “” | 测试用,可选值:“12”,“34” | export var title2 =“12” | String | “12” | 测试用 | export var title3 :=“1212” | String | “1212” | 测试用 |
普通全局变量
变量 | 值类型 | 默认值 | 描述 |
---|
var host | 未知 | null | 测试用 | var db:String | String | “” | 测试用 | var face = Texture.new() | Texture | 一个新的Texture实例 | 测试用 |
onready变量
变量 | 值类型 | 默认值 | 描述 |
---|
onready var mm | 未知 | null | 测试用 |
常量
常量 | 值类型 | 值 | 描述 |
---|
PI2 = 123 | int | 123 | 测试用 | tscn = preload(“res://属性列表测试.tscn”) | PackedScene | preload(“res://属性列表测试.tscn”) | 测试用 |
方法
H(level:int,title:String) -> String
生成Markdown的H1-H6标题,level表示标题层级,title即标题文本。
H(1,"一级标题")
H(2,"二级标题")
H(3,"三级标题")
H(4,"四级标题")
H(5,"五级标题")
H(6,"六级标题")
P(content:String) -> String
生成Markdown的段落。
P("这是一个段落") //生成“\n这是一个段落\n”
可以看到其本质是在原字符串的前后加上了"\n",也就是换行。
quote(content:String) -> String
生成Markdown的引用。
quote("这是一段引用")
生成如下Markdown语法:
> 这是一段引用\n
Code_Block(code:String,languege:String = “”) -> String
生成Markdown的代码块。
Code_Block("export var a:int = 12","GDScript")
生成如下Markdown语法:
```GDScript
export var a:int = 12
```
Code_Inline(code:String) -> String
生成行内代码。
OL(str_list:PoolStringArray) -> String
生成有序列表。
OL([
"item1",
"item2",
"item3",
])
生成如下Markdown语法:
1. item1
2. item2
3. item3
UL(str_list:PoolStringArray) -> String
生成无序列表。
UL([
"item1",
"item2",
"item3",
])
生成如下Markdown语法:
- item1
- item2
- item3
HR() -> String
生成水平分割线。生成如下Markdown语法:
------
TOC() -> String
生成内容目录。生成如下Markdown语法:
@[toc]
link(url:String,title:String="") -> String
生成超链接。无果没有设定title参数,也就是链接的标题,会直接返回url本身。
如果设定了title参数,则生成如下Markdown语法:
[title](url)
img(src:String,title:String="") -> String
生成插入图片的MD代码。生成如下Markdown语法:
![title](src)
TH(fields:PoolStringArray) -> String
遍历fields参数所指定的字段列表生成表头。
TH(["属性","默认值","描述"])
生成如下Markdown语法:
| 属性 | 默认值 | 描述 |
| --- | --- | --- |
也就是生成如下的表头:
TR(vals:PoolStringArray) -> String
根据vals参数给定的值,生成表格的一行。通常需要与TH()函数一块使用。先用TH()函数生成表头和字段,再用TR()函数生成行和字段的值。
注意:请尽量与TH()函数所指定的字段数目和含义保持一致。
TH(["属性","值","描述"])
TR(["name","张三","姓名"])
TR(["sex","0","性别"])
TR(["age","25","年龄"])
生成如下Markdown语法:
| 属性 | 值 | 描述 |
| --- | --- | --- |
| name | 张三 | 姓名 |
| sex | 0 | 性别 |
| age | 25 | 年龄 |
也就是生成如下的表格:
属性 | 值 | 描述 |
---|
name | 张三 | 姓名 | sex | 0 | 性别 | age | 25 | 年龄 |
GDscript_MD_by_path(script_path:String,md_save_path:String)
生成由script_path指定的GDScript脚本文件的Markdown框架文档。
var md = MDCreater.new() # 创建MDCreater实例
md.GDscript_MD_by_path("res://addons/myAdd/lib/MDCreater.gd",res://MDCreater.md")
上面的代码,将会为"res://addons/myAdd/lib/MDCreater.gd"指向的GDScript脚本文件创建Markdown框架文档,保存路径为"res://MDCreater.md"。
注意:其内部是调用GDscript_MD()方法。
GDscript_MD(script:Script,md_save_path:String)
生成由script指定的GDScript脚本对象的Markdown框架文档。
var md = MDCreater.new() # 创建MDCreater实例
md.GDscript_MD_by_path(get_script(),"res://22.md")
上面的代码,会为当前的脚本创建Markdown框架文档,保存为"res://22.md"。
has_class_name(script:Script) -> bool
判断脚本是否为”类脚本“,也就是有没有定义class_name。如果定义了class_name,则返回true。
script_class_name(script:Script) -> String
如果脚本是否为”类脚本“,也就是有定义了class_name。则返回其定义的class_name。
has_extend_name(script:Script) -> bool
判断脚本是否有extends关键字,如果有,返回true。
extend_class_name(script:Script) -> String
如果脚本有extends关键字,返回其extends的类型。
get_script_method_list(script:Script) -> PoolStringArray
返回脚本的方法列表 - 只包含源码内部自己定义的,不包含继承来的。
get_script_enum_list(script:Script) -> Array
返回脚本的枚举列表 - 只包含源码内部自己定义的,不包含继承来的。
返回如下形式:
[[name,vals],[name,vals],[name,vals]...]
其中name是枚举的名称,vals是值列表。
get_script_property_list(script:Script) -> Array
返回脚本的变量列表 - 只包含源码内部自己定义的,不包含继承来的
返回形式如下:
[[导出变量数组],[onready变量数组],[普通全局变量数组]]
get_script_const_list(script:Script) -> PoolStringArray
返回脚本的常量列表 - 只包含源码内部自己定义的,不包含继承来的。
get_script_signal_list(script:Script) -> PoolStringArray
返回脚本的信号列表 - 只包含源码内部自己定义的,不包含继承来的。
saveString(path:String,content:String) -> void
保存字符串到指定路径的文件。函数库内部快速保存纯文本文件的快捷函数。
get_date_time() -> String
返回当前日期时间。函数库内部快速获取当前日期时间的快捷函数。
源代码
这里是完整源代码:
# =======================================
# MDCreater - MarkDown快速生成 - 函数库
# 2022年9月24日12:34:33
# @巽星石
# 说明:本函数库基于Typora编辑器所支持的语法进行创建
# =======================================
class_name MDCreater
# H1-H6
static func H(level:int,title:String) -> String:
level = clamp(level,1,6)
var h_str = "#".repeat(level) + " " + title + "\n"
return h_str
# 普通段落
static func P(content:String) -> String:
return "\n" + content + "\n"
# quote - 引用
static func quote(content:String) -> String:
var return_str = ""
if "\n" in content: # 如果传入的内容为多行文本
var quts = content.split("\n",false)
return_str = "> %s\n".repeat(quts.size())
return_str = return_str % quts as Array
else:
return_str = "> %s\n" % content
return return_str
# 代码块
static func Code_Block(code:String,languege:String = "") -> String:
return "```%s\n%s```\n" % [languege,code]
# 行内代码
static func Code_Inline(code:String) -> String:
return "`%s`" % [code]
# OL - 有序列表
static func OL(str_list:PoolStringArray) -> String:
var return_str =""
for i in str_list.size():
return_str += "%s. %s\n" % [str(i),str_list[i]]
return return_str
# UL - 无序列表
static func UL(str_list:PoolStringArray) -> String:
var return_str =""
for mstr in str_list:
return_str += "- %s\n" % mstr
return return_str
# HR - 水平分隔线
static func HR() -> String:
return "-".repeat(6) + "\n"
# TOC - 内容目录
static func TOC() -> String:
return "[TOC]\n"
# 超链接
static func link(url:String,title:String="") -> String:
var return_str =""
if title == "":
return_str = url
else:
return_str = "[%s](%s)\n" % [title,url]
return return_str
# 图片
static func img(src:String,title:String="") -> String:
return "![%s](%s)\n" % [title,src]
# 表格 - 表头
static func TH(fields:PoolStringArray) -> String:
var th = "| " + "%s | ".repeat(fields.size()) + "\n"
th = th % fields as Array
th += "| " + "--- |".repeat(fields.size()) + "\n"
return th
# 表格 - 一行
static func TR(vals:PoolStringArray) -> String:
var tr = "| " + "%s |".repeat(vals.size()) + "\n"
tr = tr % vals as Array
return tr
# =============== 为GDScript脚本生成Markdown =====================
# 传入路径
static func GDscript_MD_by_path(script_path:String,md_save_path:String):
var script = load(script_path)
GDscript_MD(script,md_save_path)
# 生成一个GDscript的基础结构的Markdown文档
static func GDscript_MD(script:Script,md_save_path:String):
var md_str = ""
md_str += TOC()
# 当前时间
var now_date_time = get_date_time()
# 资源信息
var project_name = ProjectSettings.get_setting("application/config/name") # 项目名称
var resource_path = script.resource_path # 资源路径
var resource_name = resource_path.get_file() # 脚本的文件名
var source_code = script.source_code # 源代码
# tool
var is_tool = script.is_tool() # 是否为工具脚本
# 继承
var has_extend = has_extend_name(script) # 是否有继承的父类型
var extend_name = extend_class_name(script) # 脚本的类名
# 自定义类名
var is_class = has_class_name(script) # 是否为类脚本
var script_class_name = script_class_name(script) # 脚本的类名
md_str += H(1,"%s" % resource_name)
md_str += H(2,"基本信息")
# 脚本信息
md_str += H(3,"脚本信息")
md_str += TH(["项目","信息"])
md_str += TR(["文件名",resource_name])
md_str += TR(["is_tool",("是" if is_tool else "否")])
md_str += TR(["extend",(extend_name if extend_name else "-")])
md_str += TR(["class_name",(script_class_name if script_class_name else "-")])
# 文件信息
md_str += H(3,"文件信息")
md_str += TH(["项目","信息"])
md_str += TR(["项目名称",project_name])
md_str += TR(["文件路径",resource_path])
md_str += TR(["绝对路径",ProjectSettings.globalize_path(resource_path)])
# 其他信息
md_str += H(3,"其他信息")
md_str += TH(["项目","信息"])
md_str += TR(["作者",""])
md_str += TR(["备注",""])
# 文档信息
md_str += H(3,"文档信息")
md_str += TH(["项目","信息"])
md_str += TR(["文档创建时间",now_date_time])
md_str += H(2,"概述")
md_str += P("这里写概述")
# 信号
var signal_names = get_script_signal_list(script)
if signal_names.size() > 0:
md_str += H(2,"信号")
md_str += TH(["信号","描述"])
for signel in signal_names:
md_str += TR([signel,""])
# 枚举
# enum_names返回值形式如下:
# [[name,vals],[name,vals],[name,vals]...]
# 其中name是枚举的名称,vals是值列表
var enum_names = get_script_enum_list(script) # 所有脚本内部方法名
if enum_names.size() > 0:
md_str += H(2,"枚举")
for enu in enum_names:
md_str += H(3,enu[0])
md_str += TH(["可选值","描述"])
var vals = enu[1].split(",")
for val in vals:
md_str += TR([val,""])
# 变量
# 返回形式如下:
# [[导出变量数组],[onready变量数组],[普通全局变量数组]]
var var_names = get_script_property_list(script)
if var_names.size() > 0:
md_str += H(2,"属性")
# 导出变量
if var_names[0].size()>0:
md_str += H(3,"导出变量")
md_str += TH(["变量","值类型","默认值","描述"])
for ver in var_names[0]:
if ver.begins_with("export"):
md_str += TR([ver,"","",""])
# 全局变量
if var_names[2].size()>0:
md_str += H(3,"普通全局变量")
md_str += TH(["变量","值类型","默认值","描述"])
for ver in var_names[2]:
if ver.begins_with("var"):
md_str += TR([ver,"","",""])
# onready变量
if var_names[1].size()>0:
md_str += H(3,"onready变量")
md_str += TH(["变量","值类型","默认值","描述"])
for ver in var_names[1]:
if ver.begins_with("onready"):
md_str += TR([ver,"","",""])
# 常量
var const_names = get_script_const_list(script)
if const_names.size() > 0:
md_str += H(2,"常量")
md_str += TH(["常量","值类型","值","描述"])
for cst in const_names:
md_str += TR([cst,"","",""])
# 方法
var func_names = get_script_method_list(script) # 所有脚本内部方法名
md_str += H(2,"方法")
for fuc in func_names:
md_str += H(3,fuc)
md_str += P("这里是方法的描述。")
md_str += H(2,"源代码")
md_str += P("这里是完整源代码:")
md_str += Code_Block(source_code,"swift")
saveString(md_save_path,md_str)
# 是否为类
static func has_class_name(script:Script) -> bool:
var has = false
var source_code = script.source_code # 完整 - 源代码
var regex = RegEx.new()
regex.compile("class_name .*")
var result = regex.search(source_code)
if result:
has = false
return has
# 如果为类脚本,返回类名
static func script_class_name(script:Script) -> String:
var c_name
var source_code = script.source_code # 完整 - 源代码
var regex = RegEx.new()
regex.compile("class_name (.*)")
var result = regex.search(source_code)
if result:
result.get_string(1)
return c_name
# 是否有继承
static func has_extend_name(script:Script) -> bool:
var source_code = script.source_code # 完整 - 源代码
var regex = RegEx.new()
regex.compile("\"extends (.*)\"|extends (.*)")
var result = regex.search(source_code)
return true if result.get_string(2) else false
# 如果有继承类型,返回继承名
static func extend_class_name(script:Script) -> String:
var source_code = script.source_code # 完整 - 源代码
var regex = RegEx.new()
regex.compile("\"extends (.*)\"|extends (.*)")
var result = regex.search(source_code)
return result.get_string(2)
# 返回脚本的方法列表 - 只包含源码内部自己定义的,不包含继承来的
static func get_script_method_list(script:Script) -> PoolStringArray:
var source_code = script.source_code # 源代码
var regex = RegEx.new()
regex.compile("static func (.*):|func (.*):")
var results = regex.search_all(source_code)
var func_names:PoolStringArray = []
for result in results:
func_names.append(result.get_string(1))
if result.get_string(2) !="":
func_names.append(result.get_string(2))
return func_names
# 返回脚本的枚举列表 - 只包含源码内部自己定义的,不包含继承来的
# 返回如下形式:
# [[name,vals],[name,vals],[name,vals]...]
# 其中name是枚举的名称,vals是值列表
static func get_script_enum_list(script:Script) -> Array:
var source_code = script.source_code # 源代码
var regex = RegEx.new()
regex.compile("enum (.*){(.*)}|enum (.*){\\n*(.*\\n)*}")
var results = regex.search_all(source_code)
var enum_names:Array = []
for result in results:
# [name,vals]
if result.get_string(1) != "":
var enum_info = [result.get_string(1),result.get_string(2)]
enum_names.append(enum_info)
if result.get_string(3) != "":
var enum_info = [result.get_string(3),result.get_string(4).replace("\n","").replace("\t","")]
enum_names.append(enum_info)
return enum_names
# 返回脚本的变量列表 - 只包含源码内部自己定义的,不包含继承来的
# 返回形式如下:
# [[导出变量数组],[onready变量数组],[普通全局变量数组]]
static func get_script_property_list(script:Script) -> Array:
var source_code = script.source_code # 源代码
var regex = RegEx.new()
regex.compile("(export var .*)|(export[(].*[)] var .*)|(onready var .*)|(\\tvar .*)|(var .*)")
var results = regex.search_all(source_code)
var export_var_names:PoolStringArray = []
var onready_var_names:PoolStringArray = []
var global_var_names:PoolStringArray = []
for result in results:
# 导出变量
if result.get_string(1) != "":
export_var_names.append(result.get_string(1))
if result.get_string(2) != "":
export_var_names.append(result.get_string(2))
# onready变量
if result.get_string(3) != "":
onready_var_names.append(result.get_string(3))
# 普通全局变量
if result.get_string(5) != "":
global_var_names.append(result.get_string(5))
return [export_var_names,onready_var_names,global_var_names]
# 返回脚本的常量列表 - 只包含源码内部自己定义的,不包含继承来的
static func get_script_const_list(script:Script) -> PoolStringArray:
var source_code = script.source_code # 源代码
var regex = RegEx.new()
regex.compile("const (.*)")
var results = regex.search_all(source_code)
var const_names:PoolStringArray = []
for result in results:
const_names.append(result.get_string(1))
return const_names
# 返回脚本的信号列表 - 只包含源码内部自己定义的,不包含继承来的
static func get_script_signal_list(script:Script) -> PoolStringArray:
var source_code = script.source_code # 源代码
var regex = RegEx.new()
regex.compile("\"signal (.*[(].*[)])\"|signal (.*[(].*[)])")
var results = regex.search_all(source_code)
var signal_names:PoolStringArray = []
for result in results:
if result.get_string(2) != "":
signal_names.append(result.get_string(2))
return signal_names
# =================== 额外需要的函数 ====================
# 保存字符串到指定路径的文件
static func saveString(path:String,content:String) -> void:
var file = File.new()
file.open(path,File.WRITE)
file.store_string(content) # 整体存储
file.close()
# 保存字符串到指定路径的文件
static func get_date_time() -> String:
return Time.get_datetime_string_from_system().replace("T"," ")
|