📝 這篇文章只是我個人學習過程中的紀錄與反思,並非正式教材。
網路雖然方便,但無法取代系統性的音樂學習。若時間與預算允許,仍建議跟老師學習,能少走許多彎路。
若本文有任何錯誤,請務必以你自己的音樂老師的建議為準。
本站沒有販售、代理或代言文中或贊助連結所提到的任何產品、樂器或器材。
簡言之:本文僅為個人學習筆記,並非正式教學建議。
寫在前面
LilyPond Guile 很難學,而且用途很窄,脫離了 LilyPond 就沒什麼用。在開始之前,請先給自己打個預防針:
- 語言門檻高:Guile / Scheme 屬於 Lisp 家族,其函數式語法與常見的 Python 或 C 語言截然不同,本來就比較難上手。
- 文件不完整:LilyPond 官方並未完全公開內部的 Guile API,查不到資料、像在盲操黑盒子都是正常的。
- 非必學功能:平常排版完全不需要懂 Guile。它屬於進階擴充功能,不會寫絲毫不影響你製作精美的樂譜。
站在巨人的肩膀上
其實很少人會從頭編寫 Guile 程式碼。建議直接去開源社群尋找現成範例修改:
- LilyPond Snippet Repository (LSR):官方愛用、最龐大的程式碼片段資料庫。
- openLilyLib/snippets:社群維護的進階擴充套件庫。
寫不出來是正常的,千萬不要灰心。
Hello World
\version "2.24.3"
#(display "Hello World\n")
透過終端機執行:
$ lilypond -s program.ly
Hello World
範例說明
- -s 參數的作用:此參數能隱藏 LilyPond 預設的編譯進度與雜訊,讓自訂的 Scheme 輸出結果在終端機中清晰呈現。
- 現階段只要確認環境能成功印出這行字串即可,不需要急著往深處鑽研。
如何學習 Guile?
如果想深入,可以到 Guile 的官方網站了解。但老話一句:看不懂非常正常。
這門語言本身極為小眾,多數軟體工程師都不曾接觸。更核心的問題是,Guile 官方並沒有提供正式的 Windows 原生版本,主要活躍於 GNU/Linux 環境。
此外,LilyPond 內嵌的 Guile 其實是閹割版。為了幫程式瘦身、提高執行效率,官方拿掉了許多不必要的函數。畢竟它在 LilyPond 裡的核心任務只有排版樂譜,本來就沒打算當成通用型程式語言來使用,自然不需要那些多餘的功能。
如何看官方 API?
既然官方文件查不到,最直接的方法就是直接看 LilyPond 的底層原始碼。
- 尋找目錄:前往你的 LilyPond 安裝目錄。
- 尋找檔案:尋找特定目錄底下的 .scm 檔案。
- share/guile/version/scm/ 是 Guile 的 API
- share/lilypond/version/scm/ 是 LilyPond 的 API
- 閱讀工具:強烈建議使用 VS Code 等程式編輯器開啟整個資料夾,利用全域搜尋(Ctrl+F)功能來追蹤與閱讀 API 邏輯。
在 VS Code 的搜尋中,找 (define-public ,就可以找到公開 API。define-public 是 Guile 的語法,用在定義變數、函式等項目後將其公開在模組中。
範例
開啟 REPL 模式
在終端機輸入以下指令:
$ lilypond -e "(begin (use-modules (system repl repl)) (start-repl))"
經實測,這不是一個可用的 REPL,連 (exit) 指令都沒有。這是因為內嵌的 Guile 不是完整版,拿掉了許多功能。
顥示目前系統時間
\version "2.24.3"
#(display
(strftime "%Y-%m-%d %I:%M:%S %p"
(localtime (current-time))))
#(newline)
印出系統支援的 MIDI 樂器
\version "2.24.3"
#(map
(lambda (pair)
(begin
(display (car pair))
(newline)))
instrument-names-alist)
後記
琴子後來並沒有堅持在 LilyPond Guile 的路上死磕。畢竟改用主流程式語言的繪圖函式庫,只要多花點心思慢慢微調、對齊距離,一樣能畫出理想的圖表。回頭想想,把大把青春耗在解開這個排版黑盒子上面,投資報酬率實在不怎麼高。