印刷侧的默认实现
印刷器这边的默认实现要薄得多,因为成品页面没有交互,不需要按钮、面板和快捷键。 它提供的主要是一套排版部件和一份配置,让不同渲染器写出来的东西在版面上协调一致。
DefaultPrinterComponent
这个组件做三件事:套上印刷配置的上下文、铺一层带正文字体的背景纸、渲染印刷器组件。 它接受的参数是:
| 参数 | 作用 |
|---|---|
printer | 印刷器核心 |
root | 要渲染的文档树 |
config | 部分印刷配置,只写想改的项 |
onUpdateCache | 每次预处理完成后收到整份缓存,交叉引用的目标选择器可以据此构建 |
onUpdateCache 在教程第 6 章出现过,当时用它把缓存打到控制台以确认引用名确实写进去了。
在真实应用里它的用途是给编辑侧提供数据:想做一个「选择要引用哪个定理」的下拉框,
候选项就来自这份缓存。
印刷配置
印刷配置也是部分覆盖式的,分成边距和字体两块:
| 字段 | 内容 |
|---|---|
margins | paragraph(段落间距)、special(特殊元素前后的间距)、colon(一个小间隔)、level(缩进一级的宽度)、structure(结构性文字的横向偏移) |
fonts | body、title、structure、display、weaken |
字体比编辑器那边多两种:display 用于展示性文字,比如整段引文;
weaken 用于弱化文字,比如证明的正文。中文排版里这两种通常要换字体,
比如引文用楷体、弱化用仿宋。
level 这一项决定缩进一级有多宽,它同时被下面几个部件使用,
所以改一处就能让全文的层级缩进统一变化。
<DefaultPrinterComponent
printer={printer}
root={tree}
config={{
margins: {paragraph: "0.6rem", level: "2.5rem"},
fonts : {display: {fontFamily: "KaiTi"}, weaken: {fontFamily: "FangSong"}},
}}
/>
排版部件
写印刷渲染器时,应当用下面这些部件而不是裸的 div 和 span。
原因是它们会自动从印刷配置里取字体和间距,从而保证同一种角色的文字在全文各处长得一样;
用裸标签则等于把间距和字体硬编码在某一个渲染器里,改配置时改不动它。
| 部件 | 用途 |
|---|---|
PrinterPartBox | 一个逻辑段落块,subtitle_like 打开时用标题字体 |
PrinterStructureBoxText | 结构性文字,比如「定理 一」这样的题头 |
PrinterParagraphBox | 普通段落容器,带标准的段间距 |
PrinterDisplayText | 展示性文字,比如引文 |
PrinterWeakenText | 弱化文字,比如证明的正文 |
PrinterNewLevelBox | 向内缩进一级 |
PrinterOldLevelBox | 占住一级缩进的宽度,用来在左侧空出编号的位置 |
PrinterDivider | 分隔线,带印刷配置里的特殊元素间距 |
AutoStack | 按内容自动选择横排或纵排的容器 |
最后两个缩进部件是一对,配合起来才能做出「编号在左、内容在右」的效果:
外层用 PrinterNewLevelBox 把内容整体推进一级,
再用 PrinterOldLevelBox 在左边那一级的宽度里放编号。
教程第 6 章给条目加编号时用的就是这个组合。
教程第 4 章和第 5 章写定理渲染器时其实已经在用这些部件了, 当时只是把它们当作普通的布局组件;现在可以理解为,它们是印刷配置在渲染器里的出口。
渲染器工厂
印刷侧也有一组渲染器工厂,和编辑侧对应:
get_default_group_renderer、get_default_inline_renderer、
get_default_structure_renderer、get_default_abstract_renderer,
以及不属于任何具体类型的 auto_renderer。
它们的选项(outer、inner、pre_element、
contexters 等)在教程第 4 章和第 6 章讲过,那里是按使用顺序逐个引入的,
比在这里列一张表更容易理解,所以不再重复。
另外还有一组 useless_renderer_block、useless_renderer_inline、
useless_renderer_text,作用和编辑侧的 get_default_editors() 一样:
填 Printer 构造函数的默认渲染器位,保证没注册渲染器的节点也能显示出来。