Skip to content

zago programming zh tw

Weizhong Yang a.k.a zonble edited this page Aug 25, 2026 · 16 revisions

zago programming

zago 內建了一套以 LOGO 方言為基礎的直譯語言 Editor LOGO,主要用於終端機純文字排版、ASCII 框線繪圖、文字處理巨集,以及搭配 UNIX 命令行管線(Pipeline)進行批次處理。

您可以透過簡單的指令繪製架構圖、在編輯器中執行文字轉換,或透過 Shell 腳本生成 Markdown 格式的內容。


目錄

  1. 執行環境與操作方式
  2. 文字排版與 ASCII 繪圖基礎
  3. 變數、字串與算術運算
  4. 流程控制與條件判斷
  5. 迴圈與重複迭代
  6. 清單與屬性清單 Plist
  7. 自訂程序與模組化
  8. 格式化、度量衡與資料工具
  9. 編輯器 Buffer 整合與 UNIX Pipe 實戰
  10. 附錄:經典海龜繪圖

1. 執行環境與操作方式

zago 支援 4 種執行程式碼的途徑:

  • ESC 命令列:按 ESC 鍵輸入單行命令即時執行。
  • Ctrl+Q 行內執行:游標移至該行或反白程式碼直接在文件內執行。
  • CLI 快速評估 (-e):終端機直接執行字串(例如 zago -e 'BOX 10 3')。
  • 獨立腳本執行 (-s):終端機直接執行腳本檔案(例如 zago -s script.logo)。

1.1 ESC 命令列 (Command Line)

按鍵盤上的 ESC 鍵,游標會跳到底部的命令列,直接輸入任何 LOGO 指令並按 Enter 即可執行。

  • 例如:BOX "Hello, zago!"

1.2 在編輯器中直接執行 (Eval at Cursor: Ctrl+Q)

在編輯 Markdown 或文字檔時:

  • 將游標移到任何含有 LOGO 指令的行,按下 Ctrl+Q 即可執行該行。
  • 選取多行程式碼(例如 Markdown 中的 ```logo 程式碼區塊),按下 Ctrl+Q 即可批次執行選取區塊內的程式碼。

1.3 終端機 Headless 模式 (-e-s)

不需要開啟互動式編輯器,直接在 Shell 中執行 LOGO 並輸出最終結果到標準輸出(stdout):

  • -e / --eval:執行傳入的程式碼字串。
    zago -e 'BOX "Server" MOVE DOWN LINE ARROW 5 MOVE LEFT 5 MOVE UP TYPE "     " BOX "Database"'
  • -s / --script:執行指定的 .logo 腳本檔案。
    zago -s generate_report.logo

1.4 一鍵完整復原 (Ctrl+Z)

無論是單行命令還是複雜的巨集腳本,Editor LOGO 的所有操作皆具備交易原子性(Atomic Undo)。任何腳本繪製的內容,按下 Ctrl+Z 即可一步完整復原。


2. 文字排版與 ASCII 繪圖基礎

2.1 輸出指令:TYPEPRINTNEWLINESHOW

Editor LOGO 嚴格區分「寫入文件內容」與「狀態列提示」:

  • TYPE "文字(或 PRINT):在編輯器當前游標處插入文字(不自動換行)。
    TYPE "Hello 
    TYPE "World"
    
  • NEWLINE(或 NLCHAR 10):在游標位置插入換行符號。
    TYPE "First Line" NEWLINE TYPE "Second Line"
    
  • SHOW "內容:在螢幕最底部的狀態列顯示除錯訊息或數值,絕不修改文件檔案。
    SHOW "Process completed successfully!"
    

2.2 框線與圖形繪製指令

  • BOX [寬度] [高度] [風格]:繪製文字方框。若不給寬高,會自動依照內容計算。新方框會自動將右側原有文字往右推擠。
    BOX "Architecture" ROUND
    
  • DRAWBOX [寬度] [高度] [風格]:繪製方框,但直接覆蓋底層內容(不推擠右側文字)。
  • LINE [長度] [風格]:向右繪製水平連接線。不給長度時,會自動偵測並連接到同行的下一個方塊
    LINE ARROW 8      ; 畫出 ────────▶
    
  • VLINE [長度] [風格]:向下繪製垂直連接線。不給長度時自動向下連接。
  • TABLE 行數 列數:在游標位置建立純文字網格表格。
    TABLE 3 3
    
  • FILL "字元:在目前選取區塊或所在的封閉格子內進行文字填滿(Flood Fill)。
  • GOTO 行 欄:將游標精準移動到指定的行號與欄號(1-based)。
  • MOVE 方向 [步數]:相對移動游標(UP, DOWN, LEFT, RIGHT, HOME, END)。

支援的基礎框線風格(Border Styles)

風格關鍵字 範例 說明
SINGLE ┌───┐ 預設單線 Unicode 框線(─ │ ┌ ┐ └ ┘
HEAVY ┏━━━┓ 粗線 Unicode 框線(━ ┃ ┏ ┓ ┗ ┛
DOUBLE ╔═══╗ 雙線 Unicode 框線(═ ║ ╔ ╗ ╚ ╝
ASCII +---+ 純 ASCII 格式(+ - |
DOUBLE-DASH / HEAVY-DOUBLE-DASH ┌╌╌╌┐ 二段細/粗虛線框線
TRIPLE-DASH / HEAVY-TRIPLE-DASH ┌┄┄┄┐ 三段細/粗虛線框線
QUADRUPLE-DASH / HEAVY-QUADRUPLE-DASH ┌┈┈┈┐ 四段細/粗虛線框線

圓角修飾參數(ROUND / ROUNDED

ROUND 是獨立的修飾參數,可與任何基礎框線風格組合使用:

  • BOX 20 4 ROUND(預設單線圓角 ╭ ╮ ╰ ╯
  • BOX 20 4 DOUBLE ROUND(雙線圓角)
  • BOX 20 4 HEAVY ROUND(粗線圓角)
  • BOX 20 4 ASCII ROUND(ASCII 圓角 / \ \ /
  • BOX 20 4 TRIPLE-DASH ROUND(三段虛線圓角)

2.3 Style DSL 簡寫語法

除了使用 ROUNDDOUBLE 等英文關鍵字外,zago 支援直觀的 Style DSL,可直接用字符標記(Tokens)指定框線、圓角與箭頭樣式:

1. 邊框風格符號(Border Tokens)

符號 對應風格 範例字元
- 單線 (Single) ─ │ ┌ ┐ └ ┘
+ 粗線 (Heavy) ━ ┃ ┏ ┓ ┗ ┛
= 雙線 (Double) ═ ║ ╔ ╗ ╚ ╝
a ASCII + - |
-- / --- / ---- 二/三/四段細虛線 ╌ ┄ ┈
++ / +++ / ++++ 二/三/四段粗虛線 ╍ ┅ ┉

2. 圓角修飾符(結尾加上 )

在任何邊框符號後方加上 ) 即可切換為圓角:

  • -):單線圓角 (╭ ╮ ╰ ╯)
  • =):雙線圓角 (╭ ╮ ╰ ╯)
  • +):粗線圓角 (╭ ╮ ╰ ┛)
  • a):ASCII 圓角 (/ \ \ /)
  • ---):三段虛線圓角

3. 箭頭形狀符號(用於 LINEVLINE

符號 風格名稱 水平箭頭 (左/右) 垂直箭頭 (上/下) 說明
<~ / ~> stemmed / / 帶柄細線箭頭
<< / >> solid / / 實心三角箭頭
`< / >` hollow /
<. / .> small / / 小型三角箭頭
< / > ascii < / > ^ / v ASCII 純文字箭頭

4. 指令組合範例

; 繪製 12x4 單線圓角框
BOX 12 4 -)

; 繪製帶文字的雙線框
BOX "Database" =

; 繪製長度 15、向右帶柄細線箭頭的單線 (─────────→)
LINE 15 "-~>"

; 繪製長度 15、向右 ASCII 箭頭的單線 (--------->)
LINE 15 "->"

; 繪製長度 20、雙向實心箭頭的雙線 (◀═════════▶)
LINE 20 "<<=>>"

; 繪製長度 18、雙向空心箭頭的三段粗虛線 (◁┅┅┅┅┅┅┅┅▷)
LINE 18 "<|+++|>"

; 建立欄寬為 8 的 3x3 圓角表格
TABLE 3 3 8 -)

3. 變數、字串與算術運算

3.1 變數操作 (MAKE:變數)

  • 定義全域變數:使用 MAKE "變數名 數值
  • 讀取變數內容:在變數名前加上冒號 :(例如 :title:width)。
  • 定義區域變數:在程序內使用 LOCAL "變數名LOCALMAKE "變數名 數值
MAKE "boxWidth 20
MAKE "title "User Service"

BOX :boxWidth 4 ROUND

3.2 字串表示法 (String Literals)

LOGO 提供了三種靈活的字串表示方式:

  1. 前綴引號(UCBLogo 慣例):單一單字前加上 " 即可,不需結尾引號(例如 "Server"round)。
  2. 完整雙引號字串:含有空白或特殊符號的字串使用雙引號包覆(例如 "Hello World")。
  3. 裸單字 (Bare Words):在指令參數中,未加引號的單詞會自動視為字串常數(例如 GOTO 10 5BOX Title DOUBLE)。

3.3 字串與字元處理函式

指令 說明 範例
WORD 字串1 字串2 ... 串接多個字串 WORD "Hello "World $\rightarrow$ HelloWorld
COUNT 字串或清單 取得字串長度或清單元素個數 COUNT "zago $\rightarrow$ 4
ITEM 索引 字串或清單 取得指定索引的字元或清單項目(1-based) ITEM 2 "zago $\rightarrow$ a
MEMBER 目標 字串或清單 取得自目標首次出現起算的子字串或子清單 MEMBER "b "abcdef $\rightarrow$ bcdef
MEMBER 3 [1 2 3 4 5] $\rightarrow$ [3 4 5]
ASCII 字元(別名 ORD 取得字元對應的 ASCII / Unicode Code Point 整數值 ASCII "A $\rightarrow$ 65
CHAR 數值(別名 CHR 依 Unicode Code Point 整數值回傳對應字元 CHAR 65 $\rightarrow$ A
SUBSTRING 字串 起始 長度 擷取子字串(1-based) SUBSTRING "abcdef" 2 3 $\rightarrow$ bcd
TRIM 字串 去除字串前後的多餘空白與換行 TRIM " hello " $\rightarrow$ hello
UPPERCASE 字串 / LOWERCASE 字串 英文字串大小寫轉換 UPPERCASE "zago $\rightarrow$ ZAGO
LOWERCASE "ZAGO $\rightarrow$ zago
STANDOUT 字串 以終端機 ANSI 反白反顯(Reverse video)效果包覆字串 STANDOUT "Alert"

3.4 語系轉換與 CJK 排版 (ICU Transliteration & CJK Spacing)

zago 內建 ICU Transliteration 引擎與中文排版規範處理:

指令 說明 範例
TRANSLIT 規則 字串(別名 TRANSFORM 套用 ICU 轉換規則(如字型、大小寫、假名轉換) TRANSLIT "Traditional-Simplified "繁體 $\rightarrow$ 繁体
TRANSLIT "Fullwidth-Halfwidth "123 $\rightarrow$ 123
TOHANS 字串(別名 TRANSFORM.TOHANS 繁體中文轉簡體中文 TOHANS "繁體中文" $\rightarrow$ 繁体中文
TOHANT 字串(別名 TRANSFORM.TOHANT 簡體中文轉繁體中文 TOHANT "简体中文" $\rightarrow$ 簡體中文
TOLATIN 字串(別名 TRANSFORM.TOLATIN 中文/日文漢字轉拉丁羅馬拼音 TOLATIN "台北" $\rightarrow$ tái běi
TOHIRAGANA 字串 / TOKATAKANA 字串 日文假名互相轉換(片假名轉平假名 / 平假名轉片假名) TOHIRAGANA "カタカナ" $\rightarrow$ かたかな
TOKATAKANA "ひらがな" $\rightarrow$ ヒラガナ
TOROMAJI 字串(別名 TRANSFORM.TOROMAJI 日文假名轉羅馬字拼音 TOROMAJI "とうきょう" $\rightarrow$ tōkyō
SPACING.CJK 字串 依中文文案排版指針在 CJK 漢字與英數字間自動插入半形空格 SPACING.CJK "使用Zago編輯器" $\rightarrow$ 使用 Zago 編輯器

3.5 文字統計與字元計數函式 (Text Statistics)

指令 說明 範例
CHARCOUNT 字串 計算 Unicode Grapheme Cluster 完整字元數 CHARCOUNT "Hello 世界 🚀" $\rightarrow$ 10
CHARCOUNT.CJK 字串 計算字串中的 CJK 漢字個數 CHARCOUNT.CJK "Hello 世界 🚀" $\rightarrow$ 2
CHARCOUNT.WORDS 字串 計算自然語言單詞數(Word Count) CHARCOUNT.WORDS "Quick brown fox" $\rightarrow$ 3
CHARCOUNT.EMOJI 字串 計算字串中的 Emoji 表情圖示數量 CHARCOUNT.EMOJI "🚀✨🎉" $\rightarrow$ 3
CHARCOUNT.LINES 字串 計算多行字串的總行數 CHARCOUNT.LINES :content

3.6 算術運算與數學函式

  • 算術運算子+, -, *, /, %(取餘數), ^(次方)。
  • 數學函式SQRT(開根號), ABS(絕對值), ROUND(四捨五入), SIN, COS, TAN
MAKE "radius 5
MAKE "area 3.14159 * (:radius ^ 2)
SHOW (WORD "Area: " :area)

4. 流程控制與條件判斷

Editor LOGO 具備完整的條件分支與模式匹配機制。

4.1 比較運算子與邏輯結合

  • 比較:=(相等), !=(不等於), <, >, <=, >=
  • 邏輯:AND, OR, NOT
IF :count > 0 AND :name != "" [
  TYPE (WORD "Active: " :name)
]

4.2 基礎條件分支:IFIFELSE

zago 中,IF 同時支援單一區塊(條件成立時執行)與雙區塊(分別為條件成立與不成立時執行),其行為與 IFELSE 一致:

; 1. 單一區塊:條件成立時執行
IF :width > 40 [
  SHOW "Width is wide"
]

; 2. 雙區塊:分別指定成立與不成立時執行的區塊(IF 與 IFELSE 皆支援)
IF :env = "production" [
  BOX "PROD SERVER" HEAVY
] [
  BOX "DEV SERVER" ROUND
]

4.3 旗標測試:TESTIFTRUEIFFALSE

承襲經典 LOGO 的狀態旗標判斷,可將條件評估與執行動作解耦:

TEST :score >= 60
IFTRUE  [ TYPE "PASS" ]
IFFALSE [ TYPE "FAIL" ]

4.4 條件列表:COND

當有多個條件需要依序比對時,使用 COND 比巢狀 IF 更簡潔。各條件子句需以中括號包裹 [ [ 條件 ] [ 動作 ] ],預設分支使用 ELSE 關鍵字:

COND [
  [ [ :level = 1 ] [ BOX "Junior" ROUND ] ]
  [ [ :level = 2 ] [ BOX "Senior" SINGLE ] ]
  [ [ :level = 3 ] [ BOX "Lead" HEAVY ] ]
  [ ELSE           [ BOX "Unknown" ASCII ] ]
]

4.5 多值匹配選擇:CASE

針對單一目標值進行多選一分支比對。每個子句的第一項為匹配值清單 [ 值1 值2 ... ](清單內元素以空白分隔),若匹配成功則執行對應的動作區塊;若皆未匹配則進入 ELSE 預設分支:

; 範例 1:角色權限匹配(支援單一或多個候選值)
CASE :role [
  [ [ "admin ]            [ TYPE "[Administrator Access Granted]" ] ]
  [ [ "editor "author ]   [ TYPE "[Editor Access Granted]" ] ]
  [ [ "viewer "guest ]    [ TYPE "[Read-Only Access]" ] ]
  [ ELSE                  [ TYPE "[Access Denied]" ] ]
]

; 範例 2:HTTP 狀態碼分類
CASE :statusCode [
  [ [ 200 201 204 ]       [ BOX "Success" ROUND ] ]
  [ [ 400 401 403 404 ]   [ BOX "Client Error" SINGLE ] ]
  [ [ 500 502 503 ]       [ BOX "Server Error" HEAVY ] ]
  [ ELSE                  [ BOX "Unknown Status" ASCII ] ]
]

5. 迴圈與重複迭代

5.1 計數迴圈:REPEAT (搭配 :#)

REPEAT 迴圈中,:#(或 :repcount)代表當前第幾次循環(1-based):

; 自動輸出帶序號的 1. ~ 5. 清單
REPEAT 5 [
  TYPE :# TYPE ". Item Description" NEWLINE
]

5.2 條件迴圈:WHILEUNTILDO.WHILEDO.UNTIL

zago 支援前置條件檢查與後置條件檢查兩組迴圈指令:

  • 前置條件檢查(先判斷再執行)
    • WHILE [ 條件 ] [ 區塊 ]:當條件為真時持續執行。
    • UNTIL [ 條件 ] [ 區塊 ]:當條件為假時持續執行,直到條件為真時終止。
  • 後置條件檢查(先執行一次再判斷)
    • DO.WHILE [ 區塊 ] [ 條件 ]:先執行一次區塊,當條件為真時繼續重複。
    • DO.UNTIL [ 區塊 ] [ 條件 ]:先執行一次區塊,直到條件為真時終止。
; 1. WHILE 範例
MAKE "n 1
WHILE [ :n <= 4 ] [
  BOX (WORD "Stage " :n) ROUND
  MOVE DOWN LINE 2 MOVE LEFT 2 MOVE UP 1
  MAKE "n :n + 1
]

; 2. DO.WHILE 範例(先執行一次區塊,再檢查條件)
MAKE "x 3
DO.WHILE [
  TYPE :x TYPE " "
  MAKE "x :x - 1
] [ :x > 0 ]
; 輸出:3 2 1

5.3 範圍迴圈:FORDOTIMES

  • FOR [變數 起始 結束 [步長]] [ 區塊 ]: 步長為選填(預設為 1 或自動遞減):

    ; 1. 預設步長 1
    FOR [i 1 5] [
      TYPE :i TYPE " "
    ]
    ; 輸出:1 2 3 4 5
    
    ; 2. 自訂步長 10
    FOR [i 10 50 10] [
      TYPE :i TYPE " "
    ]
    ; 輸出:10 20 30 40 50
    
  • DOTIMES [變數 次數] [ 區塊 ](從 0 迭代至 次數 - 1):

    DOTIMES [i 3] [
      TYPE (WORD "Index: " :i " | ")
    ]
    ; 輸出:Index: 0 | Index: 1 | Index: 2 |
    

5.4 清單走訪:FOREACH (搭配 ?)

FOREACH 中,? 代表當前走訪到的元素項目:

FOREACH ["Planning" "Development" "Testing" "Deploy"] [
  BOX ? ROUND
  TYPE "  -->  "
]

Important

安全防護機制:為了防止死迴圈或遞迴爆炸導致編輯器凍結,zago 內建兩大安全保護:

  1. 所有迴圈單次執行上限為 10,000 次
  2. 程序遞迴呼叫深度上限為 256 層

6. 清單與屬性清單 Plist

清單(List)與屬性清單(Property List)是 Editor LOGO 中處理多筆與鍵值資料的複合資料結構。

6.1 清單基礎操作

MAKE "fruits ["Apple" "Banana" "Cherry" "Date"]

SHOW FIRST :fruits           ; 顯示 Apple
SHOW LAST :fruits            ; 顯示 Date
SHOW BUTFIRST :fruits        ; 簡寫 BF,顯示 [Banana Cherry Date]
SHOW BUTLAST :fruits         ; 簡寫 BL,顯示 [Apple Banana Cherry]
SHOW ITEM 3 :fruits          ; 顯示 Cherry
SHOW COUNT :fruits           ; 顯示 4

; 快速產生整數數列清單 (ISEQ / RANGE)
SHOW ISEQ 1 5                ; 顯示 [1 2 3 4 5]
SHOW ISEQ 5 1                ; 自動反向,顯示 [5 4 3 2 1]
SHOW (ISEQ 10 50 10)         ; 自訂步長 10,顯示 [10 20 30 40 50]

; 產生實數等分數列清單 (RSEQ 起始 結束 個數)
SHOW RSEQ 0 1 5              ; 顯示 [0 0.25 0.5 0.75 1]

6.2 陣列與多維陣列 (Arrays & Multi-dimensional Arrays)

除了動態長度的清單(List)外,zago 亦支援固定大小且支援隨機存取的一維陣列(Array,以 { ... } 表示)多維網格陣列(MDArray,以 {{...} {...}} 表示)

指令 說明 範例
ARRAY 大小 建立指定大小的一維陣列(預設為空字串) MAKE "arr ARRAY 3 $\rightarrow$ {"" "" ""}
MDARRAY 空間清單 建立多維巢狀陣列(如 3x3 網格) MAKE "grid MDARRAY [3 3]
SETITEM 索引 "變數名 數值 就地更新陣列(或字串/清單)指定索引的值(1-based) SETITEM 2 "arr "Updated
ITEM 索引 陣列 讀取陣列指定索引的值(1-based) ITEM 2 :arr
MDSETITEM [座標] "變數名 數值 就地更新多維陣列指定座標的值 MDSETITEM [2 1] "grid 99
MDITEM [座標] 陣列 讀取多維陣列指定座標的值 MDITEM [2 1] :grid
LISTTOARRAY 清單 將動態清單轉換為一維陣列 LISTTOARRAY [A B C] $\rightarrow$ {A B C}
ARRAYTOLIST 陣列 將陣列轉換為動態清單 ARRAYTOLIST {A B C} $\rightarrow$ [A B C]

陣列實戰範例:建立與修改 2D 矩陣

; 1. 定義 2x2 矩陣
MAKE "matrix {{10 20} {30 40}}

; 2. 更新第 2 列第 1 欄的元素 (將 30 替換為 99)
MDSETITEM [2 1] "matrix 99

; 3. 讀取座標 [2 1] 元素
SHOW MDITEM [2 1] :matrix        ; 顯示 99
SHOW :matrix                     ; 顯示 {{10 20} {99 40}}

6.3 函數式高階函式 (Higher-Order Functions)

1. MAP template list (映射轉換)

對清單中的每一項元素套用運算(? 代表當前元素):

MAKE "nums [1 2 3 4 5]
MAKE "squares MAP [? * ?] :nums
SHOW :squares                ; 顯示 [1 4 9 16 25]

2. FILTER template list (條件篩選)

保留運算結果為真(非 0)的元素:

MAKE "scores [45 82 59 90 73 61]
MAKE "passed FILTER [? >= 60] :scores
SHOW :passed                 ; 顯示 [82 90 73 61]

3. REDUCE template list (折疊累加)

將清單元素逐一聚合(?1 為累加值,?2 為下一個元素):

MAKE "nums [1 2 3 4 5]
MAKE "sum REDUCE [?1 + ?2] :nums
SHOW :sum                    ; 顯示 15

4. SORT list [ASC|DESC] (自動排序)

SHOW SORT [42 10 99 5 23]            ; 顯示 [5 10 23 42 99]
SHOW SORT DESC ["Banana" "Apple" "Cherry"] ; 顯示 [Cherry Banana Apple]

6.4 屬性清單(Property Lists / Plist 鍵值表)

Property List 是 LOGO 中用於管理「鍵值關聯(Key-Value pairs)」的資料結構(類似字典 Dictionary 或物件 Object)。每個屬性清單具備一個全域名稱,內部可儲存多個屬性名稱與對應的值:

指令 說明 範例
PPROP plistName propName value 設定指定 Plist 的屬性值 (Put Property) PPROP "server "host "127.0.0.1"
GPROP plistName propName 讀取屬性值 (Get Property),不存在時回傳 [] GPROP "server "host
REMPROP plistName propName 移除指定屬性 (Remove Property) REMPROP "server "tempKey
PLIST plistName(或 PROPLIST 取得該 Plist 的所有鍵值項目(回傳清單) PLIST "server
PLISTS(或 PROPLISTS 列出目前所有已存在的 Plist 名稱 PLISTS

Plist 實戰範例:管理服務配置並繪製資訊卡片

; 1. 寫入服務設定
PPROP "app "name "Payment Gateway"
PPROP "app "host "api.payment.internal"
PPROP "app "port 8443
PPROP "app "status "Healthy"

; 2. 讀取特定欄位
MAKE "name   GPROP "app "name
MAKE "host   GPROP "app "host
MAKE "port   GPROP "app "port
MAKE "status GPROP "app "status

; 3. 繪製服務狀態資訊框
BOX (WORD :name " (" :status ")") ROUND
MOVE DOWN
TYPE "  Endpoint: https://" TYPE :host TYPE ":" TYPE :port
MOVE HOME MOVE UP 1

7. 自訂程序與模組化

7.1 定義程序 (TO ... END)

使用 TO 名稱 :參數1 :參數2 ... END 定義自訂程序:

TO DRAW_CARD :title :desc
  BOX :title ROUND
  MOVE DOWN
  TYPE "  Desc: " TYPE :desc
  MOVE HOME MOVE UP 1
END

; 呼叫自訂程序
DRAW_CARD "Auth Service" "Handles OAuth2 and JWT tokens"

7.2 回傳值與流程中斷 (OUTPUTSTOP)

  • OUTPUT 數值:回傳計算結果並結束程序。
  • STOP:立即終止程序執行(無回傳值)。
TO MAX_VAL :a :b
  IF :a > :b [ OUTPUT :a ]
  OUTPUT :b
END

SHOW MAX_VAL 42 99           ; 顯示 99

7.3 遞迴程序設計 (Recursion)

Editor LOGO 支援標準程序遞迴,非常適合繪製樹狀圖或進行階層計算:

# 遞迴繪製階層樹狀標籤
TO DRAW_TREE :level :prefix
  IF :level = 0 [ STOP ]
  TYPE :prefix TYPE "└── Node Level: " TYPE :level NEWLINE
  DRAW_TREE (:level - 1) (WORD :prefix "    ")
END

DRAW_TREE 3 ""

7.4 在 ~/.zagorc 中持久化自訂巨集

將常用的 LOGO 程序寫入 ~/.zagorclogo-prelude 區塊,啟動 zago 時便會自動載入:

# 定義開機自動載入的 LOGO 前導碼
logo-prelude
TO HEADING_BOX :text
  BOX :text DOUBLE
  MOVE DOWN LINE ARROW 4
END
endlogo

# 綁定快捷鍵 Alt+B 直接執行該巨集
bind alt-b logo: HEADING_BOX "Service"

8. 格式化、度量衡與資料工具

zago 內建了豐富的現代資料處理工具箱,涵蓋在地化格式化、物理單位度量衡計算、智慧資料偵測、UUID 生成以及編解碼與雜湊運算。

8.1 在地化格式化套件 (Formatting Suite)

指令 說明與參數 範例
FORMAT.NUMBER num [style] [locale] [currency] [precision] 格式化數值(支援貨幣、百分比、中文大寫財務金額、羅馬數字) FORMAT.NUMBER 10050208 "financial $\rightarrow$ 壹仟零伍萬零貳佰零捌
FORMAT.NUMBER 1234.5 "currency "en_US "USD $\rightarrow$ $1,234.50
FORMAT.LIST list [type] [locale] 將清單轉為自然語言連接字串(and, or, unit FORMAT.LIST [A B C] "and "en_US $\rightarrow$ A, B, and C
FORMAT.RELATIVETIME value [unit] [locale] 格式化相對時間描述 FORMAT.RELATIVETIME -2 "hour "zh_TW $\rightarrow$ 2小時前
FORMAT.BYTES bytes [style] [locale] 將位元組數轉為易讀檔案大小(KB, MB, GB FORMAT.BYTES 1048576 $\rightarrow$ 1 MB
FORMAT.NAME components [style] [locale] 格式化人名組件(支援 short, medium, long, abbreviated) FORMAT.NAME "Arthur "Conan "Doyle "long $\rightarrow$ Arthur Conan Doyle
FORMAT.NAME "Steve "Jobs "abbreviated $\rightarrow$ S. Jobs
CONVERT.CALENDAR dateStr [fromCal] [toCal] 轉換日期曆法(公曆、農曆、民國曆、伊斯蘭曆等) CONVERT.CALENDAR "2026-12-31 "gregorian "roc

8.2 物理單位轉換與度量衡計算 (Measurement Suite)

支援長度、質量、溫度、面積、體積、速度、時間、壓力、能量等 22 種物理維度的單位轉換、四則運算與在地化自動縮放:

指令 說明 範例
CONVERT.MEASURE val fromUnit [toUnit] 在相容單位間進行數值轉換 CONVERT.MEASURE 100 "c "f $\rightarrow$ 212
CONVERT.MEASURE 1000 "m "km $\rightarrow$ 1
FORMAT.MEASURE val unit [style] [locale] [naturalScale] 在地化物理單位顯示(支援自動進位縮放) FORMAT.MEASURE 1500 "m "long "zh_TW "true $\rightarrow$ 1.5公里
MEASURE.ADD val1 unit1 val2 unit2 [targetUnit] 跨單位加法運算 MEASURE.ADD 1 "km 300 "m "m $\rightarrow$ [1300 m]
MEASURE.SUB val1 unit1 val2 unit2 [targetUnit] 跨單位減法運算 MEASURE.SUB 1 "hr 15 "min "min $\rightarrow$ [45 min]
MEASURE.SCALE val unit factor 乘上倍率縮放度量衡 MEASURE.SCALE 2.5 "km 3 $\rightarrow$ [7.5 km]
MEASURE.EQUAL? val1 unit1 val2 unit2 比較兩度量衡物理量是否相等 MEASURE.EQUAL? 1000 "m 1 "km $\rightarrow$ true
MEASURE.LESS? / MEASURE.GREATER? 比較度量衡大小 MEASURE.GREATER? 1500 "m 1 "km $\rightarrow$ true
MEASURE.MIN / MEASURE.MAX 取得兩度量衡中的極小 / 極大值 MEASURE.MIN 500 "m 1 "km $\rightarrow$ [500 m]

8.3 智慧資料偵測 (Data Detection)

可從長篇非結構化純文字中,自動辨識並萃取結構化資料清單:

指令 說明 範例
DETECT.URL text 偵測並萃取文字中的網址 URL 清單 DETECT.URL "Visit https://zago.dev today" $\rightarrow$ [https://zago.dev]
DETECT.EMAIL text 偵測並萃取電子郵件信箱清單 DETECT.EMAIL "Mail team@example.com" $\rightarrow$ [team@example.com]
DETECT.PHONE text 偵測並萃取電話號碼清單 DETECT.PHONE "Call 555-123-4567" $\rightarrow$ [555-123-4567]
DETECT.DATE text 偵測並萃取日期與時間清單 DETECT.DATE "Release on August 25, 2026" $\rightarrow$ [August 25, 2026]
DETECT.ADDRESS text 偵測並萃取實體郵政地址清單 DETECT.ADDRESS "1600 Pennsylvania Ave"

8.4 識別碼、編解碼與雜湊 (UUID, Codecs & Hashes)

指令 說明 範例
UUID [flavor] 產生唯一識別碼(支援 v4, v7, nil, short UUID "v7 $\rightarrow$ 018f4a3c-...
UUID "nil $\rightarrow$ 00000000-0000-...
UUID? string 驗證字串是否為合法的 UUID 格式 UUID? "f47ac10b-58cc-4372-a567-0e02b2c3d479 $\rightarrow$ true
UUID.TIME uuidV7 從 UUID v7 識別碼中萃取 ISO8601 時間戳記 UUID.TIME (UUID "v7)
BASE64.ENCODE text 將 UTF-8 字串編碼為 Base64 格式 BASE64.ENCODE "Hello $\rightarrow$ SGVsbG8=
BASE64.DECODE b64 將 Base64 字串解碼回原始文字 BASE64.DECODE "SGVsbG8= $\rightarrow$ Hello
BASE64? string 檢查字串是否為合法的 Base64 格式 BASE64? "SGVsbG8= $\rightarrow$ true
URL.ENCODE text 將文字進行 URL 百分比編碼(Percent-encoding) URL.ENCODE "你好 $\rightarrow$ %E4%BD%A0%E5%A5%BD
URL.DECODE urlText 解碼 URL 百分比編碼字串 URL.DECODE "%E4%BD%A0%E5%A5%BD $\rightarrow$ 你好
HEX.ENCODE val 將整數轉為 0x 格式或將文字轉為十六進位 Byte 碼 HEX.ENCODE 255 $\rightarrow$ 0xFF
HEX.ENCODE "abc $\rightarrow$ 616263
HEX.DECODE hexStr 將十六進位字串還原為整數或原始文字 HEX.DECODE "0xFF $\rightarrow$ 255
HEX.DECODE "616263 $\rightarrow$ abc
HASH.SHA256 text 計算文字的 64 位元 SHA-256 雜湊摘要 HASH.SHA256 "zago $\rightarrow$ a8c9c415...
HASH.SHA1 text 計算文字的 40 位元 SHA-1 雜湊摘要 HASH.SHA1 "zago
HASH.MD5 text 計算文字的 32 位元 MD5 雜湊摘要 HASH.MD5 "zago

9. 編輯器 Buffer 整合與 UNIX Pipe 實戰

9.1 編輯器狀態與游標查詢指令

指令 說明 範例
ROW 取得游標當前行號(1-based) MAKE "r ROW
COL 取得游標當前欄號(1-based) MAKE "c COL
GETLINE [行號] 讀取目前行(或指定行)的文字內容 MAKE "txt GETLINE
SETLINE 行號 "文字 替換指定行的整行內容 SETLINE 1 "# New Title"
SELECTION 取得目前編輯器反白選取的文字內容 TYPE UPPERCASE SELECTION
ISMODIFIED 檢查 Buffer 是否有尚未儲存的修改(回傳 1 或 0) IF ISMODIFIED [ SHOW "Unsaved!" ]
DATE / TIME 取得系統日期(YYYY/MM/DD)與時間(HH:mm TYPE (WORD "Updated: " DATE " " TIME)
BUFFERTEXT 取得整個 Buffer 的完整文字內容 MAKE "content BUFFERTEXT
CLEARBUFFER 清空當前 Buffer 的所有內容 CLEARBUFFER

9.2 實戰範例 1:自動生成 Markdown 比較表格

MAKE "headers ["Feature" "Basic Plan" "Pro Plan" "Enterprise"]
MAKE "row1    ["Users"   "1 User"     "10 Users" "Unlimited"]
MAKE "row2    ["Storage" "5 GB"       "100 GB"   "1 TB"]
MAKE "row3    ["Support" "Community"  "Email"    "24/7 Phone"]

TO PRINT_MD_ROW :cols
  TYPE "| "
  FOREACH :cols [ TYPE ? TYPE " | " ]
  NEWLINE
END

; 輸出表頭
PRINT_MD_ROW :headers

; 輸出 Markdown 分隔線
TYPE "| "
REPEAT (COUNT :headers) [ TYPE "--- | " ]
NEWLINE

; 輸出資料列
PRINT_MD_ROW :row1
PRINT_MD_ROW :row2
PRINT_MD_ROW :row3

執行產出的 Markdown:

| Feature | Basic Plan | Pro Plan | Enterprise | 
| --- | --- | --- | --- | 
| Users | 1 User | 10 Users | Unlimited | 
| Storage | 5 GB | 100 GB | 1 TB | 
| Support | Community | Email | 24/7 Phone | 

9.3 實戰範例 2:動態繪製微服務架構圖

; 1. 繪製 API Gateway
GOTO 1 10
BOX "API Gateway" DOUBLE

; 2. 向下畫分支連接線
GOTO 2 1
LINE 30

; 3. 繪製後端服務
GOTO 4 1
BOX "Auth Service" ROUND

GOTO 4 18
BOX "Order Service" ROUND

GOTO 4 35
BOX "Payment Service" ROUND

9.4 實戰範例 3:搭配 UNIX Pipe 進行命令行自動化

zago -e 可以搭配 Shell 腳本或 Makefile 使用。標準輸入(stdin)會直接流入 zago buffer,供 BUFFERTEXT 讀取並進行處理:

# 範例:將系統資訊自動抓取並包覆在雙線 Unicode 方框中
uname -a | zago -e '
  MAKE "sys BUFFERTEXT
  CLEARBUFFER
  BOX (TRIM :sys) DOUBLE
'

終端機輸出結果:

╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ Darwin Mac 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun  9 22:26:22 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T8132 arm64 ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝

10. 附錄:經典海龜繪圖

在純文字編輯器中,直接使用 BOXLINETABLE 等指令通常較為方便。不過為了延續經典 LOGO 語言的精神,zago 也保留了海龜幾何繪圖指令(Turtle Graphics)

在海龜下筆(PD)狀態下移動,zago 會在游標路徑上自動繪製 ANSI 框線,並在交叉與轉角處進行拓撲節點自動融合

       ▲ SETH UP
       │
LT 90  │  RT 90
◄──────┼──────► SETH RIGHT
SETH   │
LEFT   ▼ SETH DOWN

海龜指令集

  • PD (Pen Down):下筆。移動時自動繪製框線。
  • PU (Pen Up):提筆。移動時不繪製框線。
  • FD 步數 (Forward):依當前朝向前進指定字元步數。
  • BK 步數 (Back):依當前朝向後退。
  • RT 角度 (Right):順時針旋轉 90 度(90, 180, 270)。
  • LT 角度 (Left):逆時針旋轉 90 度。
  • SETH 方向 (Set Heading):直接設定朝向(UP, DOWN, LEFT, RIGHT)。

海龜繪圖範例:階梯拓撲圖

; 使用海龜畫出連續的階梯幾何圖形
PD
REPEAT 4 [
  FD 6 RT 90
  FD 2 LT 90
]
PU

繪製結果:

─────┐
     └────┐
          └────┐
               └────┐
                    │

Clone this wiki locally