你说的对,但是 typst 是一款…
最初的故事:2023 年 4 月 -8 月,typst preview
现在居然有点难以想象这个东西已经快一年了
typst 应该是 23 年 3 月左右开源的,当时玩的时候感到非常震惊:
mgt, [2023/3/28 19:11]
试了一下typst的webapp,确实instant
mgt, [2023/3/28 19:11]
快死了
mgt, [2023/3/28 19:17]
呃这个webapp,是wasm??
mgt, [2023/3/28 19:20]
感觉杀死比赛了
后来和群友聊天的时候,想要打破 webapp 垄断:
mgt, [2023/4/8 16:26]
比较好奇typst的webapp是怎么刷新pdf的
mgt, [2023/4/8 16:27]
我在本地的感觉是,编译很快
mgt, [2023/4/8 16:27]
但是刷新pdf很慢
kamiya hinata, [2023/4/8 16:27]
并不存在pdf,就是直接更新一个canvas
mgt, [2023/4/8 16:29]
这下看懂了
mgt, [2023/4/8 16:29]
哎能不能本地也能这样快
kamiya hinata, [2023/4/8 16:30]
我感觉他核心科技都藏起来了..
mgt, [2023/4/8 16:48]
哎能不能在vscode里面搞这个
mgt, [2023/4/8 16:48]
急
然后群友发现 typst 的代码里面,居然默默隐藏了一个 render to bitmap 的后端。于是想法就出现了:在 vscode 里面复刻 webapp 的操作。
mgt, [2023/4/8 23:35]
哎typst这个,还是挺神奇的。。
mgt, [2023/4/8 23:36]
把各种东西都开源了,但是又藏起来了
最开始搓的时候做的很简陋。就是无脑渲染 bitmap, 然后 ws 发给前端。后来这套莫名其妙的技术栈居然 somehow 延续了下来。
kamiya hinata, [2023/4/9 13:43]
怎么不放vscode preview里,那个也是一个浏览器
mgt, [2023/4/9 13:43]
有道理
mgt, [2023/4/9 15:02]
看了下官方的实现
mgt, [2023/4/9 15:03]
它是 一页一个canvas
mgt, [2023/4/9 15:29]
我想在本地搞定渲染,把图给前端
于是在这一天,一个最简单的 demo 就弄出来了,用来测试的文档还是华科毕业论文。。后来逐渐完善,加了很多小功能,以及简单的增量渲染。 随后不断完善,比如从位图变成 svg, 再变成群友的自制科技格式,实现了 in memory file 的监听,还一起踩了 rkyv 在不同平台上的坑。
官方的 svg 支持:2023 年 8-9 月,typst-svg
之前群友做过一版 svg 导出,后来被 laur 觉得太复杂了,他喜欢一个文件的那种。于是我一边学 svg 的格式标准,一边乱搞&抄袭,最后居然还真整了一个看起来挺靠谱的 svg 导出。某种意义上来说,这个是因为 typst 的 frame 设计的非常合理,各种属性都是针对 canvas api(也就是,skia)设计的,而且恰好 svg 也都有一模一样的对应物。 https://github.com/typst/typst/pull/1729 在这个 PR 里面也可以看出来,其实没有改太多的代码。
CJK 的提升:2023 年 10-11 月
之前 peng1999 大哥给 typst 做了很多比较科技的 cjk 功能,标点压缩,自动加空白之类的。我也顺手修了一些 bug, 优先响应了很多中文用户报出来的问题。 比如更多的标点压缩 https://github.com/typst/typst/pull/2456 (原神启动,,),和其他的一些 bug https://github.com/typst/typst/pull/2456
WASM plugin: 2023 年 11 月 -12 月,jogs,wavy, tiaoma, m-jaxon, mino
typst 在九月的 0.8.0 里面就支持了 wasm plugin.本质上是提供了一个 wasm32 的裸机环境,可以为 typst 里面提供一些纯函数来使用。这方面其实有很多意义的应用,比如可以把 graphviz 之类的东西编译成 wasm, 于是就可以在 typst 里面画图了。
jogs: quickjs
也有人尝试把各种语言的解释器嵌入到 typst 里面。比如我就整了个 quickjs 的 wasm 插件版。https://github.com/typst/packages/pull/220 通过一顿 hack 操作之后,居然真的能跑起来 js。甚至各种库也可以运行(前提是,库本身只做计算,不依赖 nodejs 和 browser 的 api)。另一方面,通过 cbor 之类的序列化/反序列化协议,居然能使得 js 和 typst 代码之间直接互相传递复杂的数据结构。
wavy: wavedrom
有了 js 解释器之后,当然想偷一些 js 生态用用。比如各种 mermaid 之类的画图库,可惜它们大部分都是依赖 dom 的。比如需要依赖浏览器来量文本的长度:这是需要 shaping 文本才能做到的。于是一番搜索之后,发现 wavedrom 居然不需要 dom,而且是可以在 qjs 里面运行的!于是就有了 https://github.com/typst/packages/pull/228 这个包还依赖了 jogs.(构成了生态闭环。。)
tiaoma: zint
关于如何画各种条形码,之前有人做了个用 typst script 纯手写生成的版本,确实是非常牛逼。。佩服。但是这个场景太适合 wasm 插件做了。以及还有个大哥居然用 jogs 封装了一个用 js 生成二维码的库,感觉有点令人摸不着头脑。正好我在某个地方看到了 zint 这个库,看起来是最强的条形码&二维码生成器,于是写了一坨 C 和 rust 的胶水代码,顺利编译成 wasm, 也接入了 typst. 命名直接偷懒使用汉语拼音。。进行一个文化的输出
m-jaxon: mathjax & mitex
另一个很有意思的问题是,经常有人会问“为什么 typst 不支持 LaTeX 数学公式”。既然我们已经有了 js 解释器,理应是可以跑起来 mathjax 的。于是 m-jaxon 就诞生了。。https://github.com/typst/packages/pull/293 另一方面,我其实考虑过能不能把 pandoc 编译成 wasm,嵌入进来。但是一番折腾之后,发现 haskell 到 wasm 的编译工具链实在是不成熟。于是还是放弃了。
群友更进一步,直接把 pandoc 的转换给 RIIR 了,有了 https://github.com/mitex-rs/mitex 。由于 rust 代码速度快,甚至可以即时预览转换的结果。。于是 typst 现在真的支持 LaTeX 公式了
mino: 俄罗斯方块画图
作为 tetris 老玩家,在很早之前搓过一个用来学 dpc 的网站:https://dpc.mgt.moe/ 。甚至还把 pc finder 给编译成了 wasm, 在前端来 solve pc. 于是这次也顺手在 typst 里面写了一下方块场地的渲染,fumen 格式的解析则由 js 代码来做。
https://github.com/typst/packages/pull/320
总结
感觉玩的挺开心的,得到了朋友们非常积极的反馈。很多人都说 typst preview 非常好用。希望今年能继续有时间做更多更有趣的事情。