Alhagi实现记录
参考资料
https://spec.commonmark.org/0.31.2/
CommonMark解析策略
- 先将文档分解为块结构,但不解析文本,链接引用定义可以先收集起来
- 将标题和段落中的纯文本解析为行内元素,此时可使用之前收集好的链接引用定义
强调和链接的解析策略
使用分隔符栈来解析,每个栈元素需要包含如下信息:
- 分隔符类型
[
,![
,*
,_
- 分隔符数量?
- 分隔符是否激活状态
- 分隔符是否为潜在的开启符号,或者潜在的关闭符号,或者都是
当碰到符号]
的时候,调用look for link or image
当碰到输入结束时,调用强调语法处理流程,此时直到碰到栈底元素为NULL
look for link or image
从分隔符栈顶倒找[
或者![
- 如果没找到,则返回纯文本的
]
- 如果找到一个,但没激活,则从栈里移除那个没激活的分隔符,接着返回纯文本的
]
- 如果找到一个并且是激活的,则查看是否为行内/引用/压缩/short cut的链接或者图像
- 如果不是,则从栈中移除开始标签,并且返回纯文本的
]
- 如果是,则
- 返回链接或者图像节点,添加到开启符号的文本节点后
- 在当前行内元素中执行
process emphasis
,将[
作为栈底(碰到[
则结束) - 移除栈中的
[
- 如果当前行内元素是链接而不是图片,则将前面所有的
[
符号都设为非激活状态,防止后面解析到嵌套的链接
- 如果不是,则从栈中移除开始标签,并且返回纯文本的
process emphasis
该流程需要一个参数stack_bottom
,来确认可以抵达的元素,NULL代表可以到栈底,否则,在碰到stack_bottom中的元素之前停止查找。
将当前指针current_position指向stack_bottom上面的一个元素
为每种分隔符类型(_*
)都设置一个openers_bottom,初始化为stack_bottom,根据关闭分隔符运行的长度(模3)和关闭分隔符是否同时为开启分隔符来索引,用于记录每种分隔符类型搜索开启分隔符的下限。
接着循环如下步骤直到没有潜在的关闭结构
- 将当前指针向前移动(栈底向栈顶),直到找到第一个潜在的关闭结构(有可能当前符号就是)
- 向栈底移动(这里应该不是动当前指针),注意要在stack_bottom和当前分隔符类型的openers_bottom之上,找到第一个匹配的(相同的分隔符以及数量)开启结构
- 如果找到
- 判断是强调还是强烈强调,如果开启结构和结束结构的长度都大于等于2,则为强烈强调,否则为强调(强调优先级低)
- 在开启节点的文本节点后插入对应的强调节点
- 移除开启结构和结束结构中间的所有分隔符
- 从开启结构和结束结构中移除一个或者两个分隔符(根据当前判断为强调还是强烈强调),如果该结构变空,则从栈中移除,同时设置当前指针为下一个元素
- 如果没有找到
- 设置当前类型分隔符的openers_bottom到当前指针之前,因为当前指针之前没有当前类型的开启结构了
- 如果说当前指针所指的关闭结构并不同时是一个开启结构,则从栈中移除当前结构,因为它也已经当不成关闭结构了
- 设置当前指针为下一个元素
- 如果找到
源码阅读记录
1 | // 反斜杠 |