Header logo.
极北人工智障
主页逐年标签自述RSS

静态网站生成器

这个 blog 一直是用自己写的静态网站生成器 (Static-Site Generator),从一堆 Markdown 文件里生成 HTML,再用 git 推到 Cloudflare Pages 上。

之前的生成器是 Python 写的。本来一直能用,然而去年有一天,一个 dependency 不知怎么回事坏掉了。(有可能是因为电脑上有几个版本的 Python 在打架吧。)不是什么大问题,创建了一个新的虚拟环境,重新装一下 Markdown 的库就又能跑了。又过了一阵子,生成 feed 的库里面有一行代码开始报错说「缺一个参数」。奇妙的是我这段时间根本没动过那写代码。

于是大过年的,决定用 Go 写了一个新的。其实还是有一些小问题的,比如 CSS 什么的。

上一版的 blog 生成器花了一星期。这一版的用了 3 天时间,但是实际写码的时间只有 11 个小时。中间用了很多 GitHub Copilot。

试图直接把一堆 Python 甩给 Copilot 让它「翻译」成 Go,但是它只是生成了一个简单的文件夹结构和一些并不重要的函数。

但是很多具体的功能,很多时候写个开头,一路按 tab 就行了。比如排序、regex、读写文件,都是它直接生成的。

该选哪些库也是 Copilot 教我的,比如用来解析 Markdown 的 goldmark,用来生成 feed 的 gorilla/feeds。这两个库实际用起来感觉也比 Python 的两个库更舒服。

而且我心想,既然都重写了,比如干脆加上语法高亮和 Mermaid 的支持,幸好 goldmark 的扩展都有现成的。

我之前一直用中文的楷体来表示强调,因为斜体汉字太难看了,手段是手动加 CSS。所以这次还试图写一个新的 goldmark 扩展,找个特殊符号,在解析的时候替换成 <span class="kai">。但是有点复杂,Copilot 提示的做法都不能用,直接跑去读 goldmark 的代码对照,好像 Copilot 生成的一些函数用法已经 deprecated 了。于是后来放弃了。

Go 本身写起来就挺舒服的,再加上 Copilot 的助推,整个过程相当 pleasant。不过,虽然确实需要检查生成的代码,看它是不是在做正确的事,但在脑袋里形不成什么深刻的印象。

「殖民三百年」

最近想起来刘晓波曾经说过的「殖民三百年」,今天从网上找到了这样的出处,据说是 1988 年的采访:

金鐘是這麼問劉曉波的:「什麼條件下,中國才有可能實現一個真正的歷史變革呢?」劉曉波回答:「300年殖民地。香港100年殖民地變成今天這樣,中國那麼大,當然需要300年殖民地,才會變成今天香港這樣。300年夠不夠?我還有懷疑。」

1988 年看来,香港自然是一个发达的城市。然而移交之前,港英政府的政治架构是服务于殖民者的,其施政风格一直是「行政领衔」(executive-dominant),民主制约并不存在。总督兼任立法会主席,立法会一半议员是「官守议员」,由政府官员兼任。另一半「非官守议员」由总督任命。

香港移交之前,港英政府试图加大民主参与。但是大陆官方极力反对。

1997 年移交之后,香港政治机器服务于殖民者的性质是没有变的,只是宗主国从英国变成了中国而已。而秉承「专业精神」的施政团队,换了老板依然兢兢业业,娴熟地运用旧殖民者留下的行政和法律工具,服务新的殖民者。

比如说,雨伞运动、占中等示威期间,特区政府用来逮捕并公诉示威者的法律工具「公安条例」(Public Order Ordinance) 是 1967 年港英时代颁布的。

大陆政府没有信守「基本法」的承诺是确凿的事实。但港英政府没有向香港人赋予民主也是确凿的事实。

实际上,民主本来就不是「被赋予」的。且不论殖民主义这种剥削制度的利弊,幻想「被殖民三百年之后,就成为文明国家」是不成立的。只要是被殖民,三百年不行,八百年都不行。

自己的政治建设是要自己做的。

翻看两年前的代码

现在又开始试着用 Go 写一些小东西。于是买了一个 Web Development With Go 的教程。视频教程的标价是很贵的,于是犹豫不决。看来看去之时,翻到页面最下面,发现还有一个只卖电子书的选项,才 60 刀,于是果断下单。感觉这门课的主创真是定价的人才。

买书之前觉得其实不用任何教程,一边用 ChatGPT 一边看文档,照样可以做出自己想做的东西来。但实际做起来,才发现要收集、整理的信息是很庞杂的。自己通过不断试错、get your hands dirty 还挺花时间的。

而且有可能会犯自己意识不到的错误。

比如看这本书里的代码,发现他很 unorginal 地用了 MVC 架构。(但是 uoriginal 是有 unorginal 的好处的,就是整个东西会更 predictable 一些。)所有接触数据库的代码都在 models 里,数据库连接是在 main 函数里创建的。每次读写数据库,都是把数据库连接传到 models 函数里。数据库连接一直到程序退出才关闭。

然后想起两年多以前写的 Go,发现自己是在每次查询的时候,连接数据库、查询、关闭连接。每查询一次,就要这么折腾一下。当时怎么没意识到打开、关闭数据库是很 expensive 的。

当时还困惑,为什么每次打开某个页面,列出来的数据总是少开头的两行,有可能就是某次查询的时候数据库喘了……

看来这两年其实没白过吧。

一些想法

记得 2015 年的一个周末,那时还在北京。一共四个人在西北三环的一家砂锅粥店吃饭,有 J 和 X,当然当时还有前妻。

年份和地点记得不是很确凿。说是 2015 年是因为记得当时还在 N 报社上班,之所以说是砂锅粥店,是因为 N 社旁边不远处有个同名砂锅粥店,我还蛮喜欢。(老板是潮汕人,早先还可以用比特币结账。) J 提出要吃饭问想去哪儿,我不明就里可能就提了这家店的名字。这次会面我总会想起,每次想起就查一下地图。西北三环那个犄角的内侧,一直有一家「蟹老宋」,并没有砂锅粥店的名字。但当时确实是在西北三环的那个犄角。

一边吃一边聊,J 问我那时都在通过什么渠道获取信息。我不明就里,直率地说,我正在「收缩」自己的信息摄取,越来越觉得新闻也好、公共事件也好,没什么关系。J 君语塞,我当时恐怕还蛮迟钝的,丝毫没有感觉到冷场。回家路上前妻告诉我,J 想和你聊,其实是看能不能把你挖过来。后来才知道 J 那时正在策划一个好友分享新闻链接的社交产品,产品形态有点像「即刻」。

之后不久,我从 N 社辞职。没做什么后面的打算,就是觉得不想再继续干下去了。用现在的话说可能是叫 burned out 加「政治性抑郁」。然而 that's not something I want to say, because that doesn't sound like something I would say. 一个原因是现在每天讲英语的时候,很多词尽管知道字面的意思,但如果不是确切知道 “how it cuts”,我是不想说的。另一个原因是对 N 社印在纸上的词感到可疑,对汉人知识界的一些词也时常感到有距离。

同一段时间,我的一个微信群里聚集了很多有趣的、年轻的朋友。虽然记不清对话发生的背景了,但是我记得跟朋友 M 有一次讲,感觉人生每一步都是在「逃跑」。

这种感觉一直持续了很多年。现在回想起来,之后经历的若干次更大的挫折,其实都可以追溯到那次砂锅粥谈话。但很奇怪,有一次问过前妻记不记得那次吃饭,再后来也问过 X 是不是记得这样一件事,两人都说毫无印象。

之所以又想起这件事,是因为上周或者上上周自己出去跑步,停下脚步的时候突然觉得此刻挺好。意识到自己已经有一阵子没觉得自己在「逃跑」或者「收缩」了。此刻 “I am”,自己在做的事情是 to be 或者说 être。这状态不是很好,但也不是很坏。是一个 state of being。

「脑后」

仔细一看聊天记录,这已经是 8 个月之前聊过的事情了。

Bakhuvud 意思是后脑勺。

但是有次跟朋友聊到,“ha i bakhuvudet” 瑞典语的意思是 “keep something in mind”,也就是记着那件事。但汉语里类似的表达「抛诸脑后」就是要忘掉那件事了。

还有一个读小说发现的。

“Lämna” 直译成英语是 “leave”,“ut” 则是 “out”。

但是小说里的这句话是 “För henne är det ett svek att lämna ut intima detaljer.” 正确的理解翻译成中文是「在她看来,把私密的琐事 晾出来 是一种背叛。」有种「家丑不可外扬」的意思。

但是英语的 “leave out” 就变成了「省略」的意思了,愣是照着字面字字对应地置换成英语,“For her, it is a betrayal to leave out the intimate details.” 听起来就像是在说,聊家长里短的破事,所有细节都不能从叙事中删除。

所以瑞典语的 lämna ut 是「把情节晾到外面」让公众看见,英语的 leave out 是「把情节丢到『叙事』的外面」不提也罢。

结论:

Words are treacherous!

绝食的第三天

蒙古人民革命党从 1921 年领导革命,到 1989 年已经执政近七十年。1989 年 12 月 10 日是国际人权日。这一天执政党在乌兰巴托市中心的苏和巴特尔广场举行庆典。庆典的模式似曾相识,其中的节目有爱国歌曲、民族舞蹈等文艺表演,也有射箭、赛马、摔跤这样的传统艺能。

苏和巴特尔广场在乌兰巴托的地位相当于北京的天安门广场。广场正中有一尊英雄骑马的塑像,这就是 1921 年发动革命、赶走中国殖民者(北洋政府)的革命英雄苏和巴特尔。1989 年的时候,广场还像天安门广场上一样,有一座供奉英雄遗骨的陵寝。长眠在此的是开国元勋苏和巴特尔(Sükhbaatar「斧子英雄」)和他的战友乔巴山。(陵寝已于 2005 年拆除。)

这一天也是柏林墙推倒后的一个月零一天,例行的国际人权日庆典发生了小小的意外。两百多名年轻人举着横幅走上广场游行,高呼「经济改革」、「自由开放」的口号。两位记者、一位科学家在众人面前发表演说,宣布民主运动从此刻开始。游行过后,年轻人们和平地离开广场。安保人员没有试图驱散。

这次游行的组织者佐日格(Zorig,「意志」)在莫斯科读过哲学。一年之前,他组织了一个名叫「新一代」的小团体,定期在自己家集会,并且在乌兰巴托秘密张贴民主标语。佐日格的妹妹乌云 (Oyun,「智慧」) 在布拉格的查尔斯大学读了地质学的本科和硕士。她说自己那段时间没有站在政治运动的最前线,「只是在家做家务,给哥哥的朋友们做做饭」。她后来读了地质学博士,做过外交部长,还组建过一个政党,名叫「公民意志」(Irgenii Zorig),活用了哥哥的名字。

发表演说的一位记者名叫额勒贝格道尔吉 (Elbegdorj),后来做过一任总统。那位科学家名叫巴特乌勒 (Bat-Uul) 做过首都的市长。

国际人权日的游行之后,12 月 17 日,两千名民众举行集会,民主派正式向执政党递交了请愿书,主张多党制、新闻自由、尊重人权。与此同时,执政党召开全会,原则上同意确实要深化改革,毕竟苏联老大哥也在这么做。但具体怎么做没说。民主派的一个具体诉求是第二年(1990 年)就要实行国会民选。然而人民革命党经过一番讨论,说要等五年。

民主派组织的示威抗议没有遭到武力镇压的原因有:半年之前天安门广场上的血腥镇压惨不忍睹,戈尔巴乔夫不想看到共产阵营再死很多人。蒙古国镇压示威会破坏稳定,恐怕会给中国口实,趁乱侵扰(之前几年苏联因为经济困难,把大部分驻蒙苏军撤走了)。再者就是,上广场的年轻人大都出身精英阶层,留学苏联、东欧,有知识有文化,其中很多是高干子弟,可以说是国家领导人的亲儿子、亲孙子。

之后运动的势头日益高涨。1990 年初,民主派一次又一次举行请愿、集会,民众越来越多。1990 年 2 月,民主派成立了两个反对党(其中有巴特乌勒的民主党),办了一家报纸「新镜」。这段时间里,民主派还和国会议员有过私下接触。

然而党的政治局和国会内部因为温和派、保守派存在分歧,一直举棋不定。1990 年 3 月 4 日政治局开会,仍然莫衷一是,并没有做出什么具体的让步。

3 月 7 日,气温零下十五度。十个人走上苏和巴特尔广场发起绝食。大家都知道一年之前北京的天安门广场上发生过绝食。其中一位带头绝食的懂汉语,对天安门广场的情形很了解。绝食开始之后,市民也开始罢工、罢课表示支持,甘丹寺的僧人也上广场表示慰问。救护车停在广场边上,以防不测。

这一天,政治局开会开了一整天。但最后又没有形成共识。当晚,两位政治局委员上广场慰问、沟通。

3 月 8 日,绝食继续,中间还有更多市民加入绝食。第一副总理下午去跟绝食者谈判,全国电视、广播直播。据说副总理和绝食领袖之一巴特乌勒是亲戚。绝食者说政治局委员都太老了,已经不能代表人民,应当赶紧下台,很多国会议员已经连任四五届,早就应该换人了。这几天街上的局面有点混乱。比如,有人走到苏联大使馆门前辱骂苏联,自然也有人辱骂党和国家领导人。比如,民众有几十人受伤,一人死亡。

3 月 9 日,星期五。绝食的第三天,执政党内的保守派做出让步。最后总书记巴特蒙赫携政治局集体辞职。

民主派号召市民撤离广场。周末平安无事。

3 月 12 日,星期一。国会开会废除了规定一党专政的宪法第 82 条。3 月 15 日,执政党选出一批年轻、开明的官员组成新的政治局,准备向多党制过度。

之后的一段时间里,执政党和民主派谈判,最后双方的共识是 7 月份举行国会普选。接着在 5 月 10 日,国会批准了新的选举规则。

最后在1990 年 7 月的选举中,人民革命党得票 60%,新生的几个民主派政党共得票 30%+(还有一些废票什么的)。然而因为选举制度设计的狡猾,人民革命党拿到了 90% 的席位。

这是蒙古国历史上第一次民主选举。


佐日格 1998 年遇刺。案件直到 18 年后的 2016 年才开庭,闭门审理之后,三名凶手被判有期徒刑二十余年。2017 年,佐日格遇刺案卷宗里的大部分内容解密。但有 74 页没有解密。