2023-11-26 17:47:58 +08:00
# Another Typesetter - 另一個排版器
2023-12-02 03:46:41 +08:00
## 摘要
本文是講一個排版器的雛形如何製作的考察, 使用Rust語言。
2023-11-26 17:47:58 +08:00
2023-12-02 03:46:41 +08:00
###序言
以前從國中時候試用Linux以及架站以後, 就開始想用LaTeX排版些自己所寫的東西, 其中包含覺得LaTeX的語法不好想要重造輪子。就算後來大學沒有走上資訊工程這條路, 還是希望有天至少能夠完成個能用的雛形。
但是這是涉及字體檔案的處理、PDF的處理、語法分析, 後來自己因為不知道如何開發, 所以一直停擺。不是遇到很多蟲, 就是效能問題有缺失。因為時間繁忙很少更不消說了。甚至買了Knuth教授的 _Digital Typography_ ,想要瞭解斷行演算法,結果粗估五、六十頁,所以幾乎沒有讀。
另外筆者一個分支興趣是編譯器的相關知識, 所以開始讀和王垠的編譯器思想系出同門的Jeremy G. Siek所著作之 *Essential of Complication: An Incremental Approach in Racket* ( 編譯之要素: Racket語言的遞增的方法) 。我想到: 既然編譯器這種複雜的軟體, 可以一層一層的用pass來遞增功能, 就像水彩從背景、大物體一直由少漸多的完成。而排版軟體也是把使用者輸入的排版之領域特定語言(DSL)轉換成文字、圖形和二維座標對應關係( 最後匯出成PDF或SVG等等) 的編譯器, 若是能夠用層層遞增的方法來完成, 相信也能夠避免結構的複雜化導致錯誤容易發生的挫折。
然而排版語言不只是輸入文字轉圖形而已,更重要的是還要有因應美觀的自動斷行(justification)和斷字(hyphenation)等等的演算法、還有PDF的基本知識、字型函式庫的取用、排版要求( 多欄) 、甚至還牽涉到語言特有的特性: 比如東亞全形文字( 漢字、諺文、日文假名、注音符號) 和非全形文字中間要加空白, 以及從左寫到右的文字( 希伯來字母和阿拉伯字母等) 的排版方法, 不一而足。
為了簡化起見, 且目標讀者是臺灣的受眾, 本書僅涉及到ASCII英文字母——頂多加些一些附加符號(diacritics)和漢字的排版。其他的功能希望讀者可以漸次由少漸多的附加。另外這邊會使用到一些LISP的表達式來表達抽象語法樹, 若是不懂的話, 可以看一點教 Lisp或是Scheme的書, 如SICP。另外這本書不是編譯原理和描述PDF規格的書, 不涉獵底層的知識, 有需要的可以參考相關領域的書。
### 先備知識
2023-12-06 21:42:31 +08:00
這不是教一位入門使用者如從零知識撰寫排版軟體的書, 讀者應該有知道如何使用靜態型別語言的經驗, 比如一點C、或是Rust等等, 還要會些正規表達式regex。另外抽象語法樹為求方便, 使用LISP撰寫, 所以需要會LISP和Scheme的知識( 知名教科書SICP的開頭可以讀一讀) 。
2023-12-02 03:46:41 +08:00
這本書也不教編譯理論和tokenizing、parsing、狀態機等等的, 頂多只會帶到一些很基礎的知識, 有需要的請另外再讀。所以使用者需要會有使用正規表達式(regex)的能力。
2023-12-06 21:42:31 +08:00
操作環境使用Linux作業系統和TypeScript程式語言( Nodejs框架) 。需要安裝fontconfig等套件。
2023-11-26 17:47:58 +08:00
- [定義抽象語法樹和語法 ](./defineASTandGrammar )