最新文章
最新碎记
15. 选择 markdown-it 而不是 remarkjs
发布于:这是一条关于之前吐槽 remarkjs 的后续。
remarkjs 封闭、固执、复杂,很难自定义,让我吃到很多苦头,它唯一吸引我的是树形的 mdast 结构。
于是在一个新的项目中,我用 markdown-it 重写了一套从 markdown 到通用富文本编辑器 ast 的方案,其中包含了全量和适配 SSE 打字机场景的增量能力(此处的增量指的是编辑器排版渲染层的增量更新)。
效果也是非常好,不仅在支持的标记格式上完全对齐并超越了 remarkjs 版本,而且几乎没有再收到什么特殊 case 导致大面积解析出错的反馈了。
之前一直打算写篇文章讲讲这个方案,去年打了个草稿,一年了也没写出来。
一方面我还没有搞明白 AI 时代技术文章的价值和意义,另一方面只要一提笔就能被 AI 续写出来,会直接失去写下去的兴趣。
我要再想一想。
14. Word 的文字行高是如何计算的
发布于:在 OOXML 里有一个段落属性标签 Spacing,该标签上有 lineRule、line 这两个常用的属性,它俩会直接影响文字的行高。
lineRule 可以是 exact(精确值)、atLeast(最小值)、auto(自动),前两个比较好理解,auto 的规则不是很明确。
当 lineRule 为 auto 时,line 中的数值除以 240 表示多倍行距的倍率,比如值为 240 对应的就是单倍行距,值为 360 对应的就是 1.5 倍行距。
核心问题在于,这个多倍的基数是什么?或者说单倍行距到底是多高呢?
在 OOXML 规范中,关于这一点并不是很明确,行高的计算有很多复杂的逻辑,WPS 实现的效果也难以做到和 Office Word 完全一致。
简单来讲,它应该是根据当前 run 文字的字体、字重、字号等属性测量出来的文字行高,对于 CJK 文字,可能会额外乘以一个 extendScale,通常为 1.3。除此之外,还有大量优化细节的逻辑,等后续我对此有更深理解之后再单独展开讲讲。
这里讲一种特殊场景,此场景下的行高规则稍微简单一些,那就是对齐文档网格。
文档网格整体概念比较简单,包含了行网格和字符网格,段落可以设置对齐行网格属性,run 也可以设置对齐文字网格属性。
当一个文档节中设置了行网格,并且段落也开启了对齐网格(默认开启)时,实际文字的行高应该是「文字轮廓行高向上对齐整数个网格线」与「多倍行距(多倍网格线)」中的较大值。
多倍行距这个属性,在对齐网格的场景下,基准将变成单个网格线行高。这一点并不是 OOXML 规范内的要求,而是我通过测试一些 Office Word 实际渲染效果后猜测出来的规则。
实际测试了金山文档、石墨文档、腾讯文档,自由组合对齐网格、段落间距、段前段后、字号等属性,均符合这条规则。
不过也发现,各家的 Word 编辑器行内文字在垂直方向上的基线对齐方式存在一些差异,后面有时间再进一步了解吧。