Markdown 自渲染
Without further ado
一个很有意思的东西。
水一篇博文,markdown 自渲染。
缘起
这个主意来自于 Markdeep。Markdeep 是挺好用的一个项目,是一个能让纯文本文档在浏览器中直接渲染为美观 HTML 的轻量级工具,无需安装任何软件或插件,只需一行代码即可将 Markdown 文件转化为自包含的网页。
官网有个例子,大概这样 example.md.html
**Example**
Welcome to **Markdeep**. It's the simple way to write
plain text with _style_.
```
.---------. .------. .---------.
| Write +--+->| Edit +-+-->| Share! |
'---------' | '------' | '---------'
'-------------'
```
# Plan
1. Download [starter.md.html](templates/starter/starter.md.html)
2. Edit in any code or text editor
3. Double click to preview in a browser
4. Email, upload, or git commit to share
# More
Learn more at https://casual-effects.com/markdeep.
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js"></script><script src="https://casual-effects.com/markdeep/latest/markdeep.min.js?"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>md
一个 markdown 文件,加载 js 把自己渲染成 html。格格不入的就这一行:<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js"></script><script src="https://casual-effects.com/markdeep/latest/markdeep.min.js?"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>。
虽然看着长,但是确实是一行。前面纯 Markdown。然后文件名是 starter.md.html。
虽然不是规范的 HTML 但是能跑,哦,感谢浏览器宽容。
实现
不过我试了一下 Markdeep 后,发现难改样式。加个切换黑暗模式的功能费点劲,没有预留这个功能的样子。不过也可以理解,毕竟已经是老项目了。所以我自己也搞了一个版本。这个小玩意儿应该算是我笔记网站项目的一部分。使用了几个库: Alpine + AsyncAlpine + Marked + Medium Zoom + Water.css + Basscss
代码在这
流程也很简单。读取内容,切分,渲染。其实是用原生 js 就能很好的完成功能,还轻量。然后加个 classless css 即可。不过这个小玩意儿算是我的笔记项目的一部分。这笔记软件,加上 Alpine.js 增加了很有趣的拓展功能。于是我实现的自渲染也用上了这一堆东西。
现在结果就是,虽然不能直接像 mdx 一样引入 jsx 使用组件。但是可以引入 Alpine.js “组件”。大概下面这样的形式。这总比 markdown 中写 HTML 要方便。而且还有 AsyncAlpine 可用。
km.counter2 = function () {
return {
count: 0,
init() {
this.$root.innerHTML = `<button x-on:click="count--">Decrement</button><span x-text="count" class="px-1"></span>`;
Alpine.initTree(this.$root);
},
// 传入 args
kInit(...args) {
console.log("kInit", args);
}
}
}js
然后我增加了个正则表达式,这样算是与 obsidian 的语法兼容了,大概。现在
![[km.counter|"计数器"]]
![[km.counter|]]
![[km.counter]]
![[km.counter2]]md
这样的写法会被处理为 Alpine.js 的组件 HTML 。
这次本来想介绍一下我的笔记网站来着。但是我记着我好像发过文。最近就是加了个库,js 拆成几个 ts,然后用 Bun 打包。更方便维护拓展了。倒也没什么可说的。
不过 bun 处理这种小项目,运行单 HTML 或 Markdown 文件倒是很方便,开箱即用的 TS。
# 开发
bun src/pages/KMark/KMark.md.html --port=1313
# 运行 markdown
bun -e "await Bun.write('./temp.html', await Bun.file(process.argv[1]).text()); Bun.spawn(['bun', 'run', './temp.html'], { stdio: ['inherit', 'inherit', 'inherit'] })" ./KMark.md
# 创建临时 html 并使用默认程序打开
bun -e "await Bun.write('./temp.html', await Bun.file(process.argv[1]).text()); Bun.spawn(['cmd', '/c', 'temp.html'])" ./KMark.mdbash
以上。