About this Site

关于本站

MACBETH

She should have died hereafter;
There would have been a time for such a word.
To-morrow, and to-morrow, and to-morrow,
Creeps in this petty pace from day to day
To the last syllable of recorded time,
And all our yesterdays have lighted fools
The way to dusty death. Out, out, brief candle!
Life’s but a walking shadow, a poor player
That struts and frets his hour upon the stage
And then is heard no more: it is a tale
Told by an idiot, full of sound and fury,
Signifying nothing.

Shakespeare, The Tragedy of Macbeth


如你所见,这是一个自由散漫的网站。它的节奏缓慢,因此不是为想要通过阅读来迅速“汲取思想”的人准备的。它的内容将繁冗无章,书写语言以简体中文和繁体中文(涉及传统文化的内容)为主,夹带英文(用于其他语言转译的媒介),间或会有我想要学或正在学的语言(日语、德语),以后可能还会出现一些我想学但这辈子可能都没法学会的语言文字(东巴文?西夏文?线形文字A?)。1

这些看似没有什么意义的东西,存在的最初目的是为了要测试 Monkeydown(一个基于 pandoc filters 的用于精细化网页排版的 Markdown 扩展方言)的排版效果,所以我可以不用手写一行 HTML 而在静态网站上排出这样的效果:(居中、断行、Ruby 注音)

いろは(うた)

(いろ)(にほ)へど ()りぬるを
()()(たれ)ぞ (つね)ならん
有為(うゐ)奥山(おくやま) 今日(けふ)()えて
(あさ)(ゆめ)()じ ()ひもせず

Markdown 粒度太大,只适合不需要太多可控排版的技术文档和博客。HTML + CSS 太繁琐,没法直接用在日常写作中。折衷一下,给 pandoc 生成的文档语法树加上几条额外的自带 style 的过滤规则,就变成这样了。

脑洞之一

提到专业的排版语言,总是少不了 PostScript 和 LaTeX。

但它们有一个共同的问题,就是没法很好地做到内容写作和样式控制相分离。PS 那一套古怪的指令集自然不必说;TeX 那一套宏也是有够纠结的。若是像每个 LaTeX 初学者一样,这里 \begin 过来,那里 \begin 过去,光分散了写作的精力不说,把这些单纯用于控制样式的东西生硬地插入到文章源码里,本该简洁明了的语义全给破坏了;从这种意义上使用 TeX,其实比 Word 也好不了多少(而且至少 Word 是所见即所得,从来不掩饰自己不明确区分样式内容这一点)。

高德纳能够同时做文学和编程两件事情。但我觉得该集中精力写作的时候就好好地专注于写作,不要费精劳神想着怎么写代码弄出一个宏,再让它实现某个逻辑去控制排版效果;对于一般人的大脑来说这不是高效的运作方式。

解决办法说来也简单:不要用单一语言来写内容和控制样式。你看,用 Markdown 写作的时候一行接一行,一段又一段,行云流水,从来不用停下来查询某条命令或者某个宏的调用语法——这些东西本来就不属于内容本身。想要明确区分语义,比如这一段文本是正文,另一段是附注,还有一段是摘要?去填 HTML 模板,<header><footer><aside><article><section> 随你选,加上 classid,让他们各自尘归尘、土归土就好了。想要控制样式?CSS 让你随心所欲。万一真的需要“宏”这种东西,依然有 JavaScript 可以办到一切。(当然,仅限于浏览器的沙盒内,但你只是用它排版而已,又不是拿它造核弹)

Semantic Web 至今无法取代现有的桌面排版技术,最大的障碍有二:其一,这需要一种能实际用于写作的标记语言、一种模板引擎、加之 HTML 和 CSS 或许还有 JavaScript 的密切配合,而当前哪怕是最简单容易上手的 CSS,也缺乏严肃的在 Web 排版方向上的努力(CSS reset 当然远远不够!);其二,Web 矢量绘图这块始终是一块短板,SVG 的相应软件支持(主要是编辑器)太少又太滞后,想要 SVG 真正应用于网页设计恐怕还有很长一段路要走。

理想中,HTML + CSS + SVG 可以作为一个排版引擎的后端(目标码);所有其他的标记语言,从比较高级而表达能力有限的 Markdown,可以完整描述语义的 DocBook 等 XML,再到比较底层的可以控制任意排版细节和矢量绘图的 PostScript、PDF 可以全部编译到这上面去。浏览器可以如装插件一样装上不同的编译器(负责语法解析和代码生成),然后浏览器负责渲染最终的目标码;再加上 ECMAScript 这个负责处理逻辑的宏语言,一切就完美了!对于用户来说,任何格式的文档均可一致在浏览器里显示,无需额外的阅读器;对于作者来说,写一次意味着可同时横跨 Web 和传统出版媒介,既保留了语义又拥有 HTML 强大的浏览器交互能力,又能够达到工业级别的无损排版。


传统东亚文字的右起竖排方式,看起来是这个样子的:Demo 1Demo 2(需要 Firefox 41 或 IE 9 以上浏览器支持)。当然光有 CSS writing-mode 还是不够的,至少在 Linux 系统上,默认的 TrueType 文泉驿字体对于竖排似乎不能做到正确的文字偏移;花园明朝(HanaMinA)和 Adobe Song Std 可以正常显示,却没法相应地转化标点符号(中国大陆和日本的竖排规范是标点居右偏上),所以需要一些额外的 hack 让它们更接近正规的排版。当然有一些竖排效果更好的开放字体,hinting 出来的效果古风典雅,比如 Oradano 明朝,遗憾的是这是个纯日文字体,并不涵盖全部泛 CJK 字符集。

脑洞之二

像目前这样拿纯 CSS 来做竖排微调并不是很好的方案,这意味着要手动把标点符号放在单独的 HTML 元素中去实现。更甚之,竖排标点符号和对应的横排版本是不同的 Unicode 码位(比如用于横排的方头括号和竖排的),要做到正确的转换,JavaScript 必不可少。理想的实现方案是通过 JavaScript 自动识别标点,然后对 DOM 作出相应的调整,采取相应的样式。

对于现代东亚文字的横排(几乎无一例外地被用在互联网的每个页面上,中国大陆的正式出版物上……),西文排版中的某些舶来元素或多或少已成为约定俗成的规范,比如段落缩进、首字下沉(drop cap)。虽然绝大多数网页并没有做到这个程度,但是这些排版效果确实完全可以通过纯 CSS 实现,这里是一个 demo

另一方面来说,HTML 用于排版中,<pre> 以外的换行符在浏览器中会被自动显示为空格。这一点是基于西文排版使用“段落”而不是“行”作为主要结构组织单元的考量。但这样的设定在东亚以汉字为主导的书写系统(中文、日文)中并不存在;更多的时候,断行即意味着断行。另外,就算要使用换行符来达到连接段落的目的,这个多余的半角空格也是完全不应该出现在全角文字的组合当中的。

换言之,我希望办到这样一件简单的事情:写下一段话,有时是几行。它可以以任意字体、在任何浏览器中,以现代的横排方式或传统的竖排方式(不管是出于实用性还是装饰性的目的)被正确显示;写作者所需要做的就只有指定想要使用的语言规范而已。如果我指定了汉字书写系统,那么排版的时候就不要让浏览器默认把换行符转成半角空格;如果我指定了竖排和台湾标准,那么所有的标点符号都应该调整到相对居中的位置。依此类推。

对于现代汉字文化圈的人而言,提到文字竖排,就不可能不想到临摹传统书法的必备《兰亭集序》。将来如果这个用于排版的东西真能做出来的话,大概就叫 Lanting.js 吧。


脑洞之三

换行也好,标点符号的微调也好,说到底还都是 lexical syntax 级别的东西。对于排版来说做到这个份上已经够用了,但浏览器本身和 JavaScript 所能做到的当然比这更多!

作为一个示例,Chrome / Chromium 有自带的 中文分词功能,这意味着如果你在“中文”、“分词”或“功能”的任何一个字上双击,选中的将是相应的完整词汇,之后便可通过右键菜单在 Google 上搜索选择部分的文字。如果碰巧是在浏览本网站的话(我几乎确信这一点),那么还可以直接用D搜索 DuckDuckGo、W搜索 Wikipedia。

既然用户无论如何都要使用浏览器的话,那么就让浏览器端 JavaScript(也许将来会是 WebAssembly)发挥它最大所能好了。分词、拼写检查和翻译这些外围的(无关网站业务逻辑本身但有利于用户体验的)功能,目前还是和具体浏览器捆绑得太死;我希望把它们抽离出来作为单独的前端库,毕竟网站和网站是不同的,每个站点可以针对自己用户群的语言习惯(也许是某个特定语言/地区的用户)做一些用户体验和 web accessibility 的优化,而且,全部在浏览器端完成。

当下我在做一个叫做 RomKan.js 的东西,它是对 python-romkan 的一个轻量级改写,用来把网页上的日文假名转换成罗马字。大体上是这么个效果:

なにはづに さくやこのはな ふゆごもり いまははるべと さくやこのはな

如果查看上面一行的 HTML 源码,它是这样的:

<span id="kanji">
    なにはづに さくやこのはな ふゆごもり いまははるべと さくやこのはな
</span><span id="romaji"></span><script src="https://cdn.soimort.org/romkan/latest/romkan.min.js"></script>
<script>
    document.getElementById('romaji').innerText =
        document.getElementById('kanji').innerText.hiragana_to_hepburn();
</script>

对于并非网页主体内容(不需要被搜索引擎收录),又能够从某种意义上改善用户体验的东西,这样实现可能是最好的选择。

当然,这还仅仅是万里长征的第一步而已。也许未来某一天,浏览器所处理的将不再单单是文档的 DOM(文档对象模型),甚至会包含从自然语言解析得到的 AST(抽象语法树)吧。


最后,虽然纯粹技术细节的东西说了这么多,一切的排版仍然是为了内容服务的。这里也不例外。虽初衷如是,却又不能止步于此。

这个站点的定位是“语言文学博客”,所以今后也许会把一些严肃的又不那么实用的东西放上来,哪怕只是一些片段的摘录,一些琐碎的笔记,一些翻译,一些读后感;用母语、用孩童牙牙学语的词汇、用我心仪但不甚熟知的文字、乃至用这个星球上已无人通晓的死语。

希望在这里所出现的一切,可以让字符的排列组合产生别样的意义。如在广袤宇宙的无穷图书馆间,行经此地,在某首诗句前流连,而所见绝非冰冷的黑与白、混沌的0与1构成的像素,可以或痴笑,或泪流;以有限的生命窥知无限,用短暂书写漫长。好过一切荣华富贵和无疾而终。

是以为序。


  1. 因此,叫它“巴别图书馆”再合适不过了。