@anyblock/any-block-core 3.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,650 @@
1
+ /**
2
+ * 处理器_列表版
3
+ *
4
+ * - md_str <-> 列表数据
5
+ * - 列表数据 <-> html
6
+ * - 表格数据 -> 列表数据
7
+ */
8
+
9
+ import { ABReg } from '../ABSetting'
10
+ import {ABConvert_IOEnum, ABConvert, type ABConvert_SpecSimp} from "./ABConvert"
11
+ import {ABConvertManager} from "../ABConvertManager"
12
+
13
+ /**
14
+ * 通用列表数据,一个元素等于是一个列表项
15
+ *
16
+ * 例如:
17
+ * - a1
18
+ * - a2
19
+ * - a3
20
+ * to
21
+ * {
22
+ * {a1, 0},
23
+ * {a2, 2},
24
+ * {a3, 2},
25
+ * }
26
+ * to (nomalization)
27
+ * {
28
+ * {a1, 0},
29
+ * {a2, 1},
30
+ * {a3, 1},
31
+ * }
32
+ */
33
+ export interface ListItem {
34
+ content: string; // 内容
35
+ level: number; // 级别 (缩进空格数/normalization后的递增等级数)
36
+ }
37
+ export type List_ListItem = ListItem[]
38
+
39
+ // 列表节点结构
40
+ export type listNodes = {
41
+ content: string;
42
+ children: listNodes[];
43
+ }
44
+
45
+ /// 一些列表相关的工具集
46
+ export class ListProcess{
47
+
48
+ // ----------------------- str -> listData ------------------------
49
+
50
+ /**
51
+ * 列表文本转列表数据
52
+ * @bug 不能跨缩进,后面再对异常缩进进行修复
53
+ * @bug 内换行` | `可能有bug
54
+ * @param modeG: 识别符号 ` | ` (ABReg.inline_split)
55
+ * (该选项暂时不可用,目前强制开启且为1。原设计: 0为不识别,1为识别为下一级,2为识别为同一级,转ulTable时会用到选项2)
56
+ */
57
+ static list2data(text: string, modeG=true){
58
+ /** 内联补偿列表。只保留comp>0的项 */
59
+ let list_inline_comp:{
60
+ level:number,
61
+ inline_comp:number
62
+ }[] = []
63
+ /** 更新 list_level_inline 的状态,并返回该项的补偿值
64
+ * 流程:先向左溯源,再添加自己进去
65
+ */
66
+ function update_inline_comp(
67
+ level:number,
68
+ inline_comp:number
69
+ ): number{
70
+ // 完全不用` | `命令就跳过了
71
+ if (list_inline_comp.length==0 && inline_comp==0) return 0
72
+
73
+ // 向左溯源(在左侧时)直到自己在补偿列表的右侧
74
+ while(list_inline_comp.length && list_inline_comp[list_inline_comp.length-1].level>=level){
75
+ list_inline_comp.pop()
76
+ }
77
+ if (list_inline_comp.length==0 && inline_comp==0) return 0 // 提前跳出
78
+
79
+ // 计算总补偿值(不包括自己)
80
+ let total_comp
81
+ if (list_inline_comp.length==0) total_comp = 0
82
+ else total_comp = list_inline_comp[list_inline_comp.length-1].inline_comp
83
+
84
+ // 添加自己进去
85
+ if (inline_comp>0) list_inline_comp.push({
86
+ level: level,
87
+ inline_comp: inline_comp+total_comp
88
+ })
89
+
90
+ return total_comp
91
+ }
92
+
93
+ // 列表文本转列表数据
94
+ let list_itemInfo:List_ListItem = []
95
+
96
+ let m_line_cache = null // 缓存上次列表行的信息,以便非列表行 (内换行) 去除缩进前缀
97
+ const list_text = text.split("\n")
98
+ for (let line of list_text) { // 每行
99
+ const m_line = line.match(ABReg.reg_list_noprefix) // 是否为列表行
100
+ if (m_line) {
101
+ m_line_cache = m_line
102
+ let list_inline: string[] = m_line[4].split(ABReg.inline_split) // 内联分行
103
+ /** @bug 制表符长度是1而非4 */
104
+ let level_inline: number = m_line[1].length
105
+ let inline_comp = update_inline_comp(level_inline, list_inline.length-1)
106
+ // 不保留缩进(普通树表格)
107
+ for (let index=0; index<list_inline.length; index++){
108
+ list_itemInfo.push({
109
+ content: list_inline[index],
110
+ level: level_inline+index+inline_comp
111
+ })
112
+ }
113
+ }
114
+ else{ // 内换行
115
+ let itemInfo = list_itemInfo.pop()
116
+ if(itemInfo){
117
+ // 如果有开头有 m_line_cache[1].length+2 个空白字符 (tab/space) (+2是 `- ` 的长度),则去除这些数量的空格字符
118
+ if (m_line_cache && /^\s*$/.test(line.slice(0, m_line_cache[1].length+2))) {
119
+ line = line.slice(m_line_cache[1].length+2)
120
+ } else {
121
+ line = line.trim()
122
+ }
123
+ list_itemInfo.push({
124
+ content: itemInfo.content+"\n" + line,
125
+ level: itemInfo.level
126
+ })
127
+ }
128
+ }
129
+ }
130
+ return list_itemInfo
131
+ }
132
+
133
+ /**
134
+ * listStream结构 转 树型结构
135
+ *
136
+ * @detail
137
+ * 与list2data不同,这里仅识别 `: ` 作为分割符
138
+ *
139
+ * @param text
140
+ * @return
141
+ * {
142
+ * content: string; // 内容
143
+ * level: number; // 级别 (缩进空格数)
144
+ * }
145
+ * to
146
+ * {
147
+ * content: string
148
+ * children: []
149
+ * }
150
+ */
151
+ static list2listnode(text: string): listNodes[]{
152
+ let data: List_ListItem = ListProcess.list2data(text, false)
153
+ data = ListProcess.data2strict(data)
154
+ let nodes: listNodes[] = []
155
+ let prev_nodes: listNodes[] = [] // 缓存每个level的最新节点
156
+
157
+ let current_data: listNodes
158
+ for (let index = 0; index<data.length; index++) {
159
+ // 当前节点
160
+ const item = data[index]
161
+ current_data = {
162
+ content: item.content,
163
+ children: []
164
+ }
165
+ prev_nodes[item.level] = current_data
166
+
167
+ // 放入节点树的对应位置中
168
+ if (item.level>=1 && prev_nodes.hasOwnProperty(item.level-1)) {
169
+ prev_nodes[item.level-1].children.push(current_data)
170
+ } else if (item.level==0) {
171
+ nodes.push(current_data)
172
+ } else {
173
+ console.error(`list数据不合规,没有正规化. level:${item.level}, prev_nodes:${prev_nodes}`)
174
+ return nodes
175
+ }
176
+ }
177
+ return nodes
178
+ }
179
+
180
+ static list2json(text: string): object{
181
+ interface NestedObject { // 可递归的节点类型
182
+ [key: string]: NestedObject | string | number | any[];
183
+ }
184
+ let data: List_ListItem = ListProcess.list2data(text, false)
185
+ data = ListProcess.data2strict(data)
186
+ let nodes: NestedObject = {} // 节点树
187
+ let prev_nodes: NestedObject[] = [] // 缓存每个level的最新节点
188
+
189
+ // 第一次变换,所有节点为 "key": {...} 形式
190
+ for (let index = 0; index<data.length; index++) {
191
+ // 当前节点
192
+ const item = data[index]
193
+ const current_key: string = item.content
194
+ const current_value: NestedObject = {}
195
+ prev_nodes[item.level] = current_value
196
+
197
+ // 放入节点树的对应位置中
198
+ if (item.level>=1 && prev_nodes.hasOwnProperty(item.level-1)) {
199
+ let lastItem = prev_nodes[item.level-1]
200
+ if (typeof lastItem != "object" || Array.isArray(lastItem)) {
201
+ console.error(`list数据不合规,父节点的value值不是{}类型`)
202
+ return nodes
203
+ }
204
+ lastItem[current_key] = current_value
205
+ } else if (item.level==0) {
206
+ nodes[current_key] = current_value
207
+ } else {
208
+ console.error(`list数据不合规,没有正规化. level:${item.level}, prev_nodes:${prev_nodes}`)
209
+ return nodes
210
+ }
211
+ }
212
+
213
+ // 第二、三次变换
214
+ let nodes2: NestedObject = nodes
215
+ traverse(nodes2)
216
+
217
+ return nodes2
218
+
219
+ /**
220
+ * 递归遍历json,对obj进行两次变换
221
+ *
222
+ * @detail
223
+ * - 节点 "k:v": {空} 展开为 "k": "v"
224
+ * - 部分转列表
225
+ *
226
+ * @param
227
+ * 后两个参数是为了方便将整个obj替换掉,不然在地址不变的前提下array替换obj会很麻烦
228
+ */
229
+ function traverse(obj: NestedObject|any[], objSource?:any, objSource2?:string) {
230
+ if (Array.isArray(obj)) return
231
+
232
+ // 变换:节点 "k:v": {空} 展开为 "k": "v"
233
+ const keys = Object.keys(obj)
234
+ let count_null = 0
235
+ for (let i = 0; i < keys.length; i++) {
236
+ const key = keys[i]; if (!obj.hasOwnProperty(key)) continue;
237
+ const value = obj[key]
238
+ if (typeof value === 'object' && !Array.isArray(value)) { // (b1) 对象
239
+ if (Object.keys(value).length === 0) { // (b11) k-v展开
240
+ let index = key.indexOf(": ");
241
+ if (index > 0) {
242
+ delete obj[key]; i--; // @warn 希望新插入的k-v在后面,否则顺序问题很严重
243
+ obj[key.slice(0, index)] = key.slice(index+1)
244
+ } else {
245
+ obj[key] = ""
246
+ count_null++
247
+ }
248
+ } else { // (b12) 递归调用
249
+ traverse(value, obj, key);
250
+ }
251
+ } else { // (b2) 非对象/数组对象
252
+ }
253
+ }
254
+
255
+ // 变换:尾判断,满足需求的json转成列表
256
+ if (objSource && objSource2) {
257
+ let newObj: (string|number|{})[] = []
258
+ if (count_null == keys.length) {
259
+ for (let i = 0; i < keys.length; i++) {
260
+ const key = keys[i]; if (!obj.hasOwnProperty(key)) continue;
261
+ newObj.push(key)
262
+ }
263
+ objSource[objSource2] = newObj
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ /**
270
+ * 标题大纲转列表数据(@todo 正文的level+10,要减掉)
271
+ *
272
+ * @detail
273
+ * 这里要将标题、正文、列表 的等级合为一块,所以存在偏移值:
274
+ *
275
+ * 1. 标题等级, = `#`个数-10, 取值[-9,-4]
276
+ * 2. 正文等级, = 0, 取值[+1,+Infi]
277
+ * 3. 列表等级, = `(.*)-`个数+1, 取值[0]
278
+ *
279
+ */
280
+ static title2data(text: string){
281
+ let list_itemInfo:List_ListItem = []
282
+
283
+ const list_text = text.split("\n")
284
+ let mul_mode:"heading"|"para"|"list"|"" = "" // 多行模式,标题/正文/列表/空
285
+ let codeBlockFlag = ''
286
+ for (let line of list_text) {
287
+ // heading和mdit类型 需要跳过代码块内的结束标志
288
+ if (codeBlockFlag == '') {
289
+ const match = line.match(ABReg.reg_code)
290
+ if (match && match[3]) {
291
+ codeBlockFlag = match[1]+match[3]
292
+ list_itemInfo[list_itemInfo.length-1].content = list_itemInfo[list_itemInfo.length-1].content+"\n"+line; continue
293
+ }
294
+ }
295
+ else {
296
+ if (line.indexOf(codeBlockFlag) == 0) codeBlockFlag = ''
297
+ list_itemInfo[list_itemInfo.length-1].content = list_itemInfo[list_itemInfo.length-1].content+"\n"+line; continue
298
+ }
299
+
300
+ //
301
+ const match_heading = line.match(ABReg.reg_heading_noprefix)
302
+ const match_list = line.match(ABReg.reg_list_noprefix)
303
+ if (match_heading && !match_heading[1]){ // 1. 标题层级(只识别根处)
304
+ removeTailBlank()
305
+ list_itemInfo.push({
306
+ content: match_heading[4],
307
+ level: (match_heading[3].length-1)-10
308
+ })
309
+ mul_mode = "heading"
310
+ }
311
+ else if (match_list){ // 2. 列表层级 ~~(只识别根处)~~
312
+ removeTailBlank()
313
+ list_itemInfo.push({
314
+ content: match_list[4],
315
+ level: match_list[1].length+1//+10
316
+ })
317
+ mul_mode = "list"
318
+ }
319
+ else if (/^\S/.test(line) && mul_mode=="list"){ // 3. 带缩进且在列表层级中
320
+ list_itemInfo[list_itemInfo.length-1].content = list_itemInfo[list_itemInfo.length-1].content+"\n"+line
321
+ }
322
+ else { // 4. 正文层级
323
+ if (mul_mode=="para") {
324
+ list_itemInfo[list_itemInfo.length-1].content = list_itemInfo[list_itemInfo.length-1].content+"\n"+line
325
+ }
326
+ else if(/^\s*$/.test(line)){
327
+ continue
328
+ }
329
+ else{
330
+ list_itemInfo.push({
331
+ content: line,
332
+ level: 0//+10
333
+ })
334
+ mul_mode = "para"
335
+ }
336
+ }
337
+ }
338
+ removeTailBlank()
339
+ return list_itemInfo
340
+
341
+ function removeTailBlank(){
342
+ if (mul_mode=="para"||mul_mode=="list"){
343
+ list_itemInfo[list_itemInfo.length-1].content = list_itemInfo[list_itemInfo.length-1].content.replace(/\s*$/, "")
344
+ }
345
+ }
346
+ }
347
+
348
+ // 这种类型的列表只有两层
349
+ private static old_ulist2data(text: string){
350
+ // 列表文本转列表数据
351
+ let list_itemInfo:List_ListItem = []
352
+
353
+ let level1 = -1
354
+ let level2 = -1
355
+ const list_text = text.split("\n")
356
+ for (let line of list_text) { // 每行
357
+ const m_line = line.match(ABReg.reg_list_noprefix)
358
+ if (m_line) {
359
+ let level_inline: number = m_line[1].length
360
+ let this_level: number // 一共三种可能:1、2、3,3表示其他level
361
+ if (level1<0) {level1=level_inline; this_level = 1} // 未配置level1
362
+ else if (level1>=level_inline) this_level = 1 // 是level1
363
+ else if (level2<0) {level2=level_inline; this_level = 2} // 未配置level2
364
+ else if (level2>=level_inline) this_level = 2 // 是level2
365
+ else { // 内换行
366
+ let itemInfo = list_itemInfo.pop()
367
+ if(itemInfo){
368
+ list_itemInfo.push({
369
+ content: itemInfo.content+"\n"+line.trim(),
370
+ level: itemInfo.level
371
+ })
372
+ }
373
+ continue
374
+ }
375
+ list_itemInfo.push({
376
+ content: m_line[4],
377
+ level: this_level
378
+ })
379
+ }
380
+ else{ // 内换行
381
+ let itemInfo = list_itemInfo.pop()
382
+ if(itemInfo){
383
+ list_itemInfo.push({
384
+ content: itemInfo.content+"\n"+line.trim(),
385
+ level: itemInfo.level
386
+ })
387
+ }
388
+ }
389
+ }
390
+
391
+ // 二层树转一叉树
392
+ let count_level_2 = 0
393
+ for (let item of list_itemInfo){
394
+ if (item.level==2){
395
+ item.level += count_level_2
396
+ count_level_2++
397
+ }
398
+ else {
399
+ count_level_2 = 0
400
+ }
401
+ }
402
+
403
+ return list_itemInfo
404
+ }
405
+
406
+ /**
407
+ * 列表数据严格化/normalized
408
+ *
409
+ * 主要是调整level:由空格数调整为递增等级,并乘以2
410
+ */
411
+ static data2strict(
412
+ list_itemInfo: List_ListItem
413
+ ): List_ListItem {
414
+ let list_prev_level:number[] = [-999]
415
+ let list_itemInfo2:List_ListItem = []
416
+ for (let itemInfo of list_itemInfo){
417
+ // 找到在list_prev_level的位置,用new_level保存
418
+ let new_level = 0
419
+ for (let i=0; i<list_prev_level.length; i++){
420
+ if (list_prev_level[i]<itemInfo.level) continue // 右移
421
+ else if(list_prev_level[i]==itemInfo.level){ // 停止并剔除旧的右侧数据
422
+ list_prev_level=list_prev_level.slice(0,i+1)
423
+ new_level = i
424
+ break
425
+ }
426
+ else { // 在两个之间,则将该等级视为右侧的那个,且剔除旧的右侧数据
427
+ list_prev_level=list_prev_level.slice(0,i)
428
+ list_prev_level.push(itemInfo.level)
429
+ new_level = i
430
+ break
431
+ }
432
+ }
433
+ if (new_level == 0) { // 循环尾调用
434
+ list_prev_level.push(itemInfo.level)
435
+ new_level = list_prev_level.length-1
436
+ }
437
+ // 更新列表数据。这里需要深拷贝而非直接修改原数组,方便调试和避免错误
438
+ list_itemInfo2.push({
439
+ content: itemInfo.content,
440
+ level: (new_level-1) // 记得要算等级要减去序列为0这个占位元素
441
+ })
442
+ }
443
+ return list_itemInfo2
444
+ }
445
+
446
+ // 修复任务列表转列表结构后,任务项丢失
447
+ static data2taskData(
448
+ list_itemInfo: List_ListItem
449
+ ) {
450
+ for (let item of list_itemInfo) {
451
+ item.content = item.content.split('\n').map(line => {
452
+ const match = line.match(/\[.\] /)
453
+ if (match) {
454
+ return '- ' + line
455
+ }
456
+ return line
457
+ }).join('\n')
458
+ }
459
+ return list_itemInfo
460
+ }
461
+
462
+ /** 二层树转多层一叉树
463
+ * example:
464
+ * - 1
465
+ * - 2
466
+ * - 3
467
+ * to:
468
+ * - 1
469
+ * - 2
470
+ * - 3
471
+ */
472
+ static data_2L_2_mL1B(
473
+ list_itemInfo: List_ListItem
474
+ ){
475
+ let list_itemInfo2:List_ListItem = []
476
+ let count_level_2 = 0
477
+ for (let item of list_itemInfo){
478
+ if (item.level!=0){ // 在二层,依次增加层数
479
+ // item.level += count_level_2
480
+ list_itemInfo2.push({
481
+ content: item.content,
482
+ level: item.level+count_level_2
483
+ })
484
+ count_level_2++
485
+ }
486
+ else { // 在一层
487
+ list_itemInfo2.push({
488
+ content: item.content,
489
+ level: item.level
490
+ })
491
+ count_level_2 = 0
492
+ }
493
+ }
494
+ return list_itemInfo2
495
+ }
496
+
497
+ /**
498
+ * 列表数据转列表(看起来脱屁股放屁,但有时调试会需要)
499
+ *
500
+ * - title2list会用到
501
+ * - 妙用:list2data + data2list = listXinline
502
+ */
503
+ static data2list(
504
+ list_itemInfo: List_ListItem
505
+ ){
506
+ let list_newcontent:string[] = [] // 传入参数以列表项为单位,这个以行为单位
507
+ // 每一个level里的content处理
508
+ for (let item of list_itemInfo){
509
+ const str_indent = " ".repeat(item.level) // 缩进数 (通常反转的话会先走listdata2strict,level是缩进符的数量。默认缩进两空格)
510
+ let list_content = item.content.split("\n") // 一个列表项可能有多个行
511
+ for (let i=0; i<list_content.length; i++) {
512
+ if(i==0) list_newcontent.push(str_indent+"- "+list_content[i])
513
+ else list_newcontent.push(str_indent+" "+list_content[i])
514
+ }
515
+ }
516
+ const newcontent = list_newcontent.join("\n")
517
+ return newcontent
518
+ }
519
+
520
+ /**
521
+ * 将多列列表转 `节点` 结构
522
+ *
523
+ * .ab-nodes
524
+ * .ab-nodes-node
525
+ * .ab-nodes-content
526
+ * .ab-nodes-children
527
+ * (递归包含)
528
+ * .ab-nodes-node
529
+ * .ab-nodes-node
530
+ */
531
+ static data2nodes(listdata:List_ListItem, el:HTMLElement): HTMLElement {
532
+ const el_root = document.createElement("div"); el.appendChild(el_root); el_root.classList.add("ab-nodes")
533
+ const el_root2 = document.createElement("div"); el_root.appendChild(el_root2); el_root2.classList.add("ab-nodes-children") // 特点是无对应的content和bracket
534
+ let cache_els:{node: HTMLElement, content: HTMLElement, children: HTMLElement}[] = [] // 缓存各个level的最新节点 (level为0的节点在序列0处),根节点另外处理
535
+
536
+ for (let item of listdata) {
537
+ // 节点准备
538
+ const el_node = document.createElement("div"); el_node.classList.add("ab-nodes-node"); el_node.setAttribute("has_children", "false"); // 为false则: chileren不应该显示、content线短一些
539
+ const el_node_content = document.createElement("div"); el_node.appendChild(el_node_content); el_node_content.classList.add("ab-nodes-content");
540
+ ABConvertManager.getInstance().m_renderMarkdownFn(item.content, el_node_content)
541
+ const el_node_children = document.createElement("div"); el_node.appendChild(el_node_children); el_node_children.classList.add("ab-nodes-children");
542
+ const el_node_barcket = document.createElement("div"); el_node_children.appendChild(el_node_barcket); el_node_barcket.classList.add("ab-nodes-bracket");
543
+ const el_node_barcket2 = document.createElement("div"); el_node_children.appendChild(el_node_barcket2); el_node_barcket2.classList.add("ab-nodes-bracket2");
544
+ cache_els[item.level] = {node: el_node, content: el_node_content, children: el_node_children}
545
+
546
+ // 将节点放入合适的位置
547
+ if (item.level == 0) { // 父节点是树的根节点
548
+ el_root2.appendChild(el_node)
549
+ } else if (item.level >= 1 && cache_els.hasOwnProperty(item.level-1)) {
550
+ cache_els[item.level-1].children.appendChild(el_node)
551
+ cache_els[item.level-1].node.setAttribute("has_children", "true") // 要隐藏最后面括弧
552
+ }
553
+ else {
554
+ console.error("节点错误")
555
+ return el
556
+ }
557
+ }
558
+ return el
559
+ }
560
+ }
561
+
562
+ export const abc_list2listdata = ABConvert.factory({
563
+ id: "list2listdata",
564
+ name: "列表到listdata",
565
+ process_param: ABConvert_IOEnum.text,
566
+ process_return: ABConvert_IOEnum.list_stream,
567
+ detail: "列表到listdata",
568
+ process: (el, header, content: string): List_ListItem=>{
569
+ return ListProcess.list2data(content) as List_ListItem
570
+ }
571
+ })
572
+
573
+ export const abc_title2listdata = ABConvert.factory({
574
+ id: "title2listdata",
575
+ name: "标题到listdata",
576
+ process_param: ABConvert_IOEnum.text,
577
+ process_return: ABConvert_IOEnum.list_stream,
578
+ detail: "标题到listdata",
579
+ process: (el, header, content: string): List_ListItem=>{
580
+ return ListProcess.title2data(content) as List_ListItem
581
+ }
582
+ })
583
+
584
+ const _abc_listdata2list = ABConvert.factory({
585
+ id: "listdata2list",
586
+ name: "listdata到列表",
587
+ process_param: ABConvert_IOEnum.list_stream,
588
+ process_return: ABConvert_IOEnum.text,
589
+ detail: "listdata到列表",
590
+ process: (el, header, content: List_ListItem): string=>{
591
+ return ListProcess.data2list(content) as string
592
+ }
593
+ })
594
+
595
+ const _abc_listdata2nodes = ABConvert.factory({
596
+ id: "listdata2nodes",
597
+ name: "listdata到节点图",
598
+ process_param: ABConvert_IOEnum.list_stream,
599
+ process_return: ABConvert_IOEnum.el,
600
+ detail: "listdata到节点图",
601
+ process: (el, header, content: List_ListItem): HTMLElement=>{
602
+ return ListProcess.data2nodes(content, el) as HTMLElement
603
+ }
604
+ })
605
+
606
+ const _abc_listdata2strict = ABConvert.factory({
607
+ id: "listdata2strict",
608
+ name: "listdata严格化",
609
+ process_param: ABConvert_IOEnum.list_stream,
610
+ process_return: ABConvert_IOEnum.list_stream,
611
+ detail: "将列表数据转化为更规范的列表数据。统一缩进符(2空格 4空格 tab混用)为level 1、禁止跳等级(h1直接就到h3)",
612
+ process: (el, header, content: List_ListItem): List_ListItem=>{
613
+ return ListProcess.data2strict(content)
614
+ }
615
+ })
616
+
617
+ const _abc_listdata2task = ABConvert.factory({
618
+ id: "listdata2task",
619
+ name: "listdata支持任务列表",
620
+ process_param: ABConvert_IOEnum.list_stream,
621
+ process_return: ABConvert_IOEnum.list_stream,
622
+ detail: "当列表中存在任务列表项时,令此列表项支持任务项",
623
+ process: (el, header, content: List_ListItem): List_ListItem=>{
624
+ return ListProcess.data2taskData(content)
625
+ }
626
+ })
627
+
628
+ export const abc_list2listnode = ABConvert.factory({
629
+ id: "list2listnode",
630
+ name: "列表到listnode (beta)",
631
+ process_param: ABConvert_IOEnum.text,
632
+ process_return: ABConvert_IOEnum.json,
633
+ detail: "列表到listnode",
634
+ process: (el, header, content: string): string=>{
635
+ const data: listNodes[] = ListProcess.list2listnode(content)
636
+ return JSON.stringify(data, null, 2) // TMP
637
+ }
638
+ })
639
+
640
+ export const abc_list2json = ABConvert.factory({
641
+ id: "list2json",
642
+ name: "列表到json (beta)",
643
+ process_param: ABConvert_IOEnum.text,
644
+ process_return: ABConvert_IOEnum.json,
645
+ detail: "列表到json",
646
+ process: (el, header, content: string): string=>{
647
+ const data: object = ListProcess.list2json(content)
648
+ return JSON.stringify(data, null, 2) // TMP
649
+ }
650
+ })