# Another Typesetter - 另一個排版器 ## 摘要 本文是講一個排版器的雛形如何製作的考察,使用Rust語言。 ###序言 以前從國中時候試用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規格的書,不涉獵底層的知識,有需要的可以參考相關領域的書。 ### 先備知識 這不是教一位入門使用者如從零知識撰寫排版軟體的書,讀者應該有知道如何使用靜態型別語言的經驗,比如一點C、或是Rust等等,還要會些正規表達式regex。另外抽象語法樹為求方便,使用LISP撰寫,所以需要會LISP和Scheme的知識(知名教科書SICP的開頭可以讀一讀)。 這本書也不教編譯理論和tokenizing、parsing、狀態機等等的,頂多只會帶到一些很基礎的知識,有需要的請另外再讀。所以使用者需要會有使用正規表達式(regex)的能力。 操作環境使用Linux作業系統和TypeScript程式語言(Nodejs框架)。需要安裝fontconfig等套件。 - [定義抽象語法樹和語法](./defineASTandGrammar)