其他层级表示法
其他层级表示法
写作背景
当时新增了 MarkdownIt 转列表数据功能 (v3.4.12)
mdit2list/mdit2data 与 title2list/title2data 的逻辑基本相同
这里要将Mdit标识 (@xxx)、正文、列表 的等级合为一块,所以存在偏移值:
- Mdit等级, =
@<数字>-100, - 正文等级, = 0, 取值[+1,+Infi]
- 列表等级, =
(.*)-个数+1, 取值[0]
基础设计
:::
@1 AAA
aaa
@2 BBB
@2 B22
ccc
ddd
@1 A22
:::会被转化为
- AAA
- BBB
- B22
- ccc
ddd
- A22
规则补充 - 多行分割标题
和 title2list 不同
- title 中的 title 项一定是单行内容
- list 的所有 list 项都可以是多行内容
- markdownIt 语法中的
@项一般来说也只能是单行内容
但这里希望扩展这种定义,mdit2list 过程中,也希望每个节点都能够是多行内容。
为此我们需要定义一种语法来表示 多行分隔标题
即 @<分割标识> <分割标题> 这里,使 "分割标题" 可以为多行。最后采用的设计如下:
设计1 —— 空分割标题表示法
当分割标题为空时,则后续节点都属于该分割标题,直到下一个分割标题出现。
设计2 —— 强制正文属于标题
这种设计类似于 仅标题表示的 title2list
(1) 非仅标题模式的 title2list
- 特点
标题和列表都能声明层级关系,最后的标题和列表等会混在一起。
单个节点中不会存在列表元素。
类似于markmap的层级设计。适合分级更细的场景。 - 例如会变成
# 标题一 ## 标题二 - 列表一 - 列表二- 标题一 - 标题二 - 列表一 - 列表二
(2) 仅标题的 title2list
- 特点
只能通过标题来声明层级关系
单个节点中可以存在列表元素。
适合分级更粗的场景。 - 例如会变成
# 标题一 ## 标题二 - 列表一 - 列表二- 标题一 - 标题二 - `- 列表一\n- 列表二`
(3) 最后
我需要一些新名字,用来区分这两种不同的转换方式。
以及不同的指令名 (原 title2list) 来区分这两者。
或者需要一些更准确地面对用户的描述,告知他们这两种不同的模式。
最后采用:
finelist
设计3 —— 缩进表示法
类似于列表项中,列表项一个项可以是多行那样。
如果存在不使用 <br> 声明的多级标题,应该会长这样:
## 标题一
标题一的第二行
正文
### 标题二
标题二的第二行
^ 注意这里仅对齐示意,不建议缩进太多行。会被认为是缩进代码块。一般前面统一两空格就好
正文然后mdit也同理
:::mdit2list
@1 标题一
标题一的第二行
正文
@1 标题二
标题二的第二行
正文
:::我们这里使用后者的多行 mdit 分割标识的设计,多行标题的设计我感觉还是太前卫了,不采用。
设计4 —— YAML 的 | 表示法
yaml 的单项能够非常简单轻松地表示单行项和多行项,如:
x:
a: a1
b: |
b1
b2这里我们可以把 @1 看成是一个 匿名: 的 yaml 项,并同时支持单行和多行
设计6 —— 将 mdit 的 @ 标志看作一种标题
并且,这种标题的等级比 h1 还要高。
那么 mdit 以及 heading 转 listdata/c2listdata 的逻辑,其实就可以变得一样了。
通过这种方式抽象逻辑,可以复用更多代码,以及使用户逻辑变得更加清晰。
设计5 —— fine级别
先给出一个 Markdown 情景,并标注了所有行号。先不管,后文会用到这个
1 # heading1
2
3 text0
4
5 ## heading 2
6
7 text1
8
9 - a1
10 - a2
11 - b1
12
13 text2fine2 模式
标题 + 正文 + 列表 中,标题是一个节点,正文和列表会拆分为多个节点
直到下个标题出现。
- 场景: markmap (markmap 就是这样拆分的)
- 例子: 上面可以拆分为:
[1-2, 3-4, 5-6, 7-8, 9, 10, 11, 13]8 个节点 - 不可替代性:这种方式,是 唯一允许 title2listdata 后继续转 list 的方式 (即 title2list,否则会出现
- -的情况)
fine1 模式
标题 + 正文 + 列表 中,标题是一个节点,正文和列表会合并为一个节点
直到下个标题出现。
- 场景: title2xxx (本质是
title2list|list2xxx,并允许弥补list2xxx的节点不能包含列表的问题) - 例子: 上面可以拆分为:
[1-2, 3-4, 5-6, 7-13]4 个节点
fine0 模式
标题 + 正文 + 列表 中,标题和正文和列表都会成为一个节点;
直到下个标题出现。
- 场景: 拆分编辑模式 (例如我只想编辑第二个 h2 及其摘要部分,并屏蔽其他)
- 例子:上面可以拆分为
1-3, 5-132个节点 - 不可替代性:并且这种方式,是 唯一允许非叶子节点使用多行内容 的方式
补充:其中对于 mdit2listdata 处理器来说,@ 及标志会自动隐藏
总结三种模式
- 根据不同的应用场景,似乎总是会分别使用他们。
而并不存在哪种模式是最优的。 - fine0 和 fine1 可以较轻松地互相转换 (所以我们先不管 fine1 模式,只取 fine0 和 fine2)
fine2 则不行,信息损失较多。 - 可能还有其他情景,例如 title2c2listdata 可能只希望保留最外层的标题