summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-04-03 16:08:52 +0800
committereltrac <hi@eltr.ac>2026-04-03 16:08:52 +0800
commit9fcd9e411183cc4d7642301bd6bbeb23e8227d82 (patch)
tree0254feed1d0872242ac9c39d12580578402dec2f /content
parentfc4ea2b8b95d847932b9e1d4c113f58a7e1b5d97 (diff)
docs: new weekly draft
Diffstat (limited to 'content')
-rw-r--r--content/weekly/75.md121
1 files changed, 121 insertions, 0 deletions
diff --git a/content/weekly/75.md b/content/weekly/75.md
new file mode 100644
index 00000000..cb3b0552
--- /dev/null
+++ b/content/weekly/75.md
@@ -0,0 +1,121 @@
++++
+title = "稻草人周刊 Vol."
+subtitle = ""
+tags = ["Lisp"]
+date = 2026-04-02T23:52:12+08:00
+draft = true
+toc = true
++++
+
+{{< music cover="" title="" artist="" apple="" spotify="" netease="" >}}
+
+<!--more-->
+
+## 连接
+
+### 控制你的标记语言
+
+> [!note] 📜
+> [控制你的标记语言 - 空栈顶](https://emptystack.top/control-your-markup-language/)
+
+作者介绍了几种 Markdown 和 Org Mode 以外的用于写作的标记语言,其中 Lisp 含量达到了~~惊人的~~ 80%。
+
+和我之前写过的《[网页即列表!](/posts/webpage-as-lists/)》的思想类似,既然要把标记语言编写的文本转化为 HTML,而 HTML 构成的嵌套的 DOM 树本身就是树形结构,那么用 S-expression(Lisp 语言所采用的表达式,即列表或者说括号的嵌套)编写网页就非常合理,并且比用 XML 或 HTML 干净不少。
+
+首先是 [Pollen](https://docs.racket-lang.org/pollen/index.html),据说是 Matthew Butterick 用 WordPress 写在线书时嫌弃它不够灵活,所以开发了 Pollen。这个标记语言把一篇文章(或者一本书)都当作 X-expression(用来表示 XML 数据的 S-Expression,常在 Racket 这门 Lisp 方言里使用),为了让更多人使用它,它还兼容 Markdown。*为什么这么多新标记语言都在兼容 Markdown,是因为用的人实在太多了吗?*
+
+如果这么写:
+
+```pollen
+#lang pollen
+
+Deep Thought
+============
+
+I am **so** happy to be writing this.
+```
+
+就会被 Pollen 解析为:
+
+```racket
+'(root
+ (h1 ((id "deep-thought")) "Deep Thought")
+ (p "I am " (strong "so") " happy to be writing this."))
+```
+
+最后被转化为 HTML:
+
+```html
+<root>
+ <h1 id="deep-thought">Deep Thought</h1>
+ <p>I am <strong>so</strong> happy to be writing this.</p>
+</root>
+```
+
+Pollen 的灵活性体现在自定义标签(custom tagst),比如图片写作 `◊image["图片地址"]{图片描述}` 而链接写作 `◊link["链接地址"]{链接文本}`(*Org Mode 正在攻击我,混杂着 Markdown 和奇怪的东西*),`image` 和 `link` 可以换成自己定义的函数。
+
+可以用类似的方式定义如何把某个标签转换为 X-expression:
+
+```racket
+(define (image url alt)
+ `(img ([alt ,alt] [src ,url])))
+```
+
+之后就可以把 X-expression 转化为 HTML,或者 PDF 等任何标记语言。在我看来,Pollen 有点像是 [Pandoc](https://pandoc.org/),可以自己编写某个语言的 Reader 和 Writer,前者用于把源语言转换为 AST(抽象语法树),后者把 AST 转换为目标语言,不过对 Pollen 而言,Lisp(X-expression)充当了 AST 的作用。
+
+另外 Pollen 可以一边定义语法一边写文,说实话,看起来很爽。
+
+```pollen
+#lang pollen
+◊(define ($ . xs)
+ `(mathjax ,(apply string-append `("$" ,@xs "$"))))
+◊(define ($$ . xs)
+ `(mathjax ,(apply string-append `("$$" ,@xs "$$"))))
+
+◊h1{I wonder if ◊${2^{\aleph_\alpha} = \aleph_{\alpha+1}}?}
+```
+
+这篇文章还介绍了 Alain Marty 的 Lambda Talk,不过引用的两个链接都需要 JavaScript 才能加载内容,我拒绝为了读文档而加载 JavaScript,加上这个标记语言看起来也没有特别吸引我的地方,所以就没有去了解了。作者还提出用 Tcl 这门不需要括号和引号的**编程**语言来写文档,也是有趣的实践,而且编程语言无疑要比标记语言灵活得多。
+
+作者还讨论了在 Markdown 里插入代码的方法(不是代码块),首先排除了 MDX(本质上是 Markdown 加上 JSX 这个邪恶的东西),需要 Node.js 才能运行;又排除了 Org Mode,原因如下:
+
+> Org-mode 相对 markdown 有更多的功能以及根植于 Emacs 的可扩展性。然而正是因为 Org-mode 功能太丰富我才选择扩展 Markdown——扩展的平台必须足够简单,才能让扩展完的成果保持简单。
+>
+> 当然,Org-mode 只有在 Emacs 中才能获得良好体验也是我选择 Markdown 的原因之一。
+
+作者目前的解决方案是使用 Pandoc filter,这其实就是在对 Pandoc Reader 解析得到的 AST 做处理,比如把标记为 `mermaid` 的代码块转换为 SVG 代码再由 Pandoc Writer 输出为指定格式。我由于使用 Hugo 写博客,所以短代码(shortcode)在大多数时候就够用了,不过体验上是没有 Pollen 一边造语法一边写文的体验爽的,也没有 Pandoc 那样的兼容性。
+
+很有意思的文章,说不定哪天我真的开始用 Lisp 写文章了呢。
+
+### 用 Vim 写 Lisp
+
+> [!note] 📜
+> [Lisp in Vim](https://susam.net/lisp-in-vim.html)
+
+书接上文,前面说到 Org-Mode 只有在 Emacs 中才能获得良好体验,而 Lisp 也非常适配 Emacs,毕竟这个编辑器的核心就是一个 Emacs Lisp 解释器(或者说 REPL?)。不过,我非常固执,始终不太愿意选择 Emacs(兴许会用 Emacs 写文或者记笔记,但写代码我还是更喜欢 (Neo)vim),幸好 Vim 也可以通过插件和配置得到很好的 Lisp 编辑体验。
+
+要获得良好的 Lisp 编程体验,需要两个工具:
+
+1. 用于编辑 S-expression 的结构化编辑功能(否则就真的 *Lost In Stupid Parentheses* 了)
+2. 内嵌 REPL[^1] 以实现交互式编程(否则和非 Lisp 语言还有什么区别)
+
+作者在文章介绍了如何使用 Vlime(类似于 Emacs 的 SLIME,用于交互式编程)和 Paredit(括号编辑,或者说结构化编辑)。前者本质上是启动了一个服务器,这个服务器运行 REPL,接收来自编辑器的表达式,计算表达式后返回值给编辑器。比如,在 Vim 里选中 `(+ 1 2)`,执行 Eval 操作,Vlime 就会把这个字符串发送给 REPL 服务器,然后得到返回值 `3` 显示出来。
+
+这有点像 LSP(语言服务器协议),编辑器把代码发送给语言服务器,然后把语言服务器分析得到的警告、报错和优化建议显示给用户。不过 REPL 要更强大,不仅仅是计算。比如,如果把一个函数定义发送给 REPL,它就会记住它,在同一个会话下,可以在之后的 Eval 操作里直接使用这个函数。这就是交互式编程,可以直接对 S-expression 求值,不需要手写 `print` 或者 `console.log` 之类的。
+
+不过 Vlime 有点老了,而且是给 Vim 写的。对于 Neovim 用户,可以选择用 Fennel(用来写 Lua 的 Lisp 方言)实现的 [Conjure](https://github.com/Olical/conjure),这个插件甚至还能实现 Lua、Python 和 SQL 等语言的交互式编程。
+
+至于 Paredit,我的选择是 [nvim-paredit](https://github.com/julienvincent/nvim-paredit) 插件,Paredit 的实现大概都没有太多区别。
+
+###
+
+> [!note] 📃
+> [Why free stuff makes us irrational](https://thehustle.co/why-free-stuff-makes-us-irrational)
+
+## 星群
+
+## 切片
+
+
+[^1]: REPL:Read-Eval-Print-Loop,输入-计算-打印-循环。
+