输出
解析器交出的是事件,不是 HTML。这一部分讲输出主线:事件怎么变成 HTML 文本,文档里的字符串在写出前怎么转义,以及在解析器和写出器之间怎么改写事件流。三者都只是 Iterator<Item = Event> 的消费者或适配器,换掉任何一个都不影响解析;本站就把写出器整个换成了自己的 RSX 渲染(08 在本站中)。
代码分布(按 tag v0.13.5 统计):pulldown-cmark/src/html.rs 631 行,单独发布的 pulldown-cmark-escape(tag 上是 0.11.0)只有 src/lib.rs 470 行,pulldown-cmark/src/utils.rs 181 行,pulldown-cmark/examples/ 八个文件共 515 行。0.13.4 到 0.13.5 这几处都没有改动,本站锁定的 0.13.4 输出行为与本部分相同。
- HTML 写出器:
HtmlWriter是一个循环加八个字段,不记嵌套;表格的<tbody>在表头结束时补上,脚注编号按名字首次出现分配且区分大小写,图片alt由raw_text压平子事件;三个入口函数和不对外导出的StrWrite,write_html_io不缓冲。 - 转义:正文转
&<>,属性再加两个引号,href做百分号编码但不看协议;256 项查表的标量版和 x86_64 的 SSSE3 版在 Rosetta 下的相对快慢;HTML 事件和javascript:链接原样通过,净化是调用方的事。 - 改写事件流:
map、filter、flat_map,TextMergeStream合并被切开的文字,into_offset_iter映射回行号,标题锚点、文末脚注、目录为什么必须缓冲;上游八个例子在 tag 上都能编译运行。
flowchart TB parser["Parser"] --> adapt["迭代器适配器"] adapt --> writer["HtmlWriter"] writer --> esc["pulldown-cmark-escape"] esc --> sink["String 或 io Write"] parser --> rsx["本站 RSX 渲染"]
写出器只依赖事件,不碰解析器的树;所以事件模型里每种事件带什么数据,就是这一部分能用的全部信息。紧凑列表不输出 <p>、链接引用定义早已解析完毕这类结果,都在解析阶段就定了,写出器只是照着事件写。
💬 关联讨论
发起讨论加载中...