-
Notifications
You must be signed in to change notification settings - Fork 3
zago programming zh tw
zago 內建了一套以 LOGO 方言為基礎的直譯語言 Editor LOGO,主要用於終端機純文字排版、ASCII 框線繪圖、文字處理巨集,以及搭配 UNIX 命令行管線(Pipeline)進行批次處理。
您可以透過簡單的指令繪製架構圖、在編輯器中執行文字轉換,或透過 Shell 腳本生成 Markdown 格式的內容。
- 執行環境與操作方式
- 文字排版與 ASCII 繪圖基礎
- 變數、字串與算術運算
- 流程控制與條件判斷
- 迴圈與重複迭代
- 清單資料結構與高階函式
- 自訂程序與模組化
- 編輯器 Buffer 整合與 UNIX Pipe 實戰
- 附錄:經典海龜繪圖
zago 支援 4 種執行程式碼的途徑:
- ESC 命令列:按 ESC 鍵輸入單行命令即時執行。
- Ctrl+Q 行內執行:游標移至該行或反白程式碼直接在文件內執行。
-
CLI 快速評估 (
-e):終端機直接執行字串(例如zago -e 'BOX 10 3')。 -
獨立腳本執行 (
-s):終端機直接執行腳本檔案(例如zago -s script.logo)。
按鍵盤上的 ESC 鍵,游標會跳到底部的命令列,直接輸入任何 LOGO 指令並按 Enter 即可執行。
- 例如:
BOX "Hello, zago!"
在編輯 Markdown 或文字檔時:
- 將游標移到任何含有 LOGO 指令的行,按下 Ctrl+Q 即可執行該行。
- 選取多行程式碼(例如 Markdown 中的
```logo程式碼區塊),按下 Ctrl+Q 即可批次執行選取區塊內的程式碼。
不需要開啟互動式編輯器,直接在 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
無論是單行命令還是複雜的巨集腳本,Editor LOGO 的所有操作皆具備交易原子性(Atomic Undo)。任何腳本繪製的內容,按下 Ctrl+Z 即可一步完整復原。
Editor LOGO 嚴格區分「寫入文件內容」與「狀態列提示」:
-
TYPE "文字(或PRINT):在編輯器當前游標處插入文字(不自動換行)。TYPE "Hello TYPE "World" -
NEWLINE(或NL、CHAR 10):在游標位置插入換行符號。TYPE "First Line" NEWLINE TYPE "Second Line" -
SHOW "內容:在螢幕最底部的狀態列顯示除錯訊息或數值,絕不修改文件檔案。SHOW "Process completed successfully!"
-
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)。
| 風格關鍵字 | 範例 | 說明 |
|---|---|---|
SINGLE |
┌───┐ |
預設單線 Unicode 框線(─ │ ┌ ┐ └ ┘) |
HEAVY |
┏━━━┓ |
粗線 Unicode 框線(━ ┃ ┏ ┓ ┗ ┛) |
DOUBLE |
╔═══╗ |
雙線 Unicode 框線(═ ║ ╔ ╗ ╚ ╝) |
ASCII |
+---+ |
純 ASCII 格式(+ - |) |
DOUBLE-DASH / HEAVY-DOUBLE-DASH
|
┌╌╌╌┐ |
二段細/粗虛線框線 |
TRIPLE-DASH / HEAVY-TRIPLE-DASH
|
┌┄┄┄┐ |
三段細/粗虛線框線 |
QUADRUPLE-DASH / HEAVY-QUADRUPLE-DASH
|
┌┈┈┈┐ |
四段細/粗虛線框線 |
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(三段虛線圓角)
除了使用 ROUND、DOUBLE 等英文關鍵字外,zago 支援直觀的 Style DSL,可直接用字符標記(Tokens)指定框線、圓角與箭頭樣式:
| 符號 | 對應風格 | 範例字元 |
|---|---|---|
- |
單線 (Single) | ─ │ ┌ ┐ └ ┘ |
+ |
粗線 (Heavy) | ━ ┃ ┏ ┓ ┗ ┛ |
= |
雙線 (Double) | ═ ║ ╔ ╗ ╚ ╝ |
a |
ASCII | + - | |
-- / --- / ----
|
二/三/四段細虛線 | ╌ ┄ ┈ |
++ / +++ / ++++
|
二/三/四段粗虛線 | ╍ ┅ ┉ |
在任何邊框符號後方加上 ) 即可切換為圓角:
-
-):單線圓角 (╭ ╮ ╰ ╯) -
=):雙線圓角 (╭ ╮ ╰ ╯) -
+):粗線圓角 (╭ ╮ ╰ ┛) -
a):ASCII 圓角 (/ \ \ /) -
---):三段虛線圓角
-
</>:標準箭頭(←/→/↑/↓) -
<</>>:實心三角箭頭(◀/▶/▲/▼) -
<|/|>:空心三角箭頭(◁/▷/△/▽) -
<~/~>:帶柄箭頭(◄/►/↑/↓) -
<./.>:小型三角箭頭(◂/▸/▴/▾)
; 繪製 12x4 單線圓角框
BOX 12 4 -)
; 繪製帶文字的雙線框
BOX "Database" =
; 繪製長度 15、向右標準箭頭的單線
LINE 15 "->"
; 繪製長度 20、雙向實心箭頭的雙線
LINE 20 "<<=>>"
; 繪製長度 18、雙向空心箭頭的三段粗虛線
LINE 18 "<|+++|>"
; 建立欄寬為 8 的 3x3 圓角表格
TABLE 3 3 8 -)
-
定義全域變數:使用
MAKE "變數名 數值。 -
讀取變數內容:在變數名前加上冒號
:(例如:title、:width)。 -
定義區域變數:在程序內使用
LOCAL "變數名或LOCALMAKE "變數名 數值。
MAKE "boxWidth 20
MAKE "title "User Service"
BOX :boxWidth 4 ROUND
LOGO 提供了三種靈活的字串表示方式:
-
前綴引號(UCBLogo 慣例):單一單字前加上
"即可,不需結尾引號(例如"Server、"round)。 -
完整雙引號字串:含有空白或特殊符號的字串使用雙引號包覆(例如
"Hello World")。 -
裸單字 (Bare Words):在指令參數中,未加引號的單詞會自動視為字串常數(例如
GOTO 10 5、BOX Title DOUBLE)。
; 1. 字串串接 (WORD)
MAKE "full (WORD "Hello " " " "World!")
SHOW :full ; 顯示 Hello World!
; 2. 長度與字元擷取 (COUNT / ITEM)
SHOW COUNT "zago ; 顯示 4
SHOW ITEM 2 "zago ; 顯示 a
; 3. 取子字串 (SUBSTRING)
SHOW SUBSTRING "abcdef" 2 4 ; 顯示 bcd (從第 2 個字元起取 3 個字元)
; 4. 去除首尾空白 (TRIM)
SHOW TRIM " spaced text " ; 顯示 "spaced text"
; 5. 大小寫轉換 (UPPERCASE / LOWERCASE)
SHOW UPPERCASE "zago" ; 顯示 ZAGO
SHOW LOWERCASE "ZAGO" ; 顯示 zago
-
算術運算子:
+,-,*,/,%(取餘數),^(次方)。 -
數學函式:
SQRT(開根號),ABS(絕對值),ROUND(四捨五入),SIN,COS,TAN。
MAKE "radius 5
MAKE "area 3.14159 * (:radius ^ 2)
SHOW (WORD "Area: " :area)
Editor LOGO 具備完整的條件分支與模式匹配機制。
- 比較:
=(相等),!=(不等於),<,>,<=,>= - 邏輯:
AND,OR,NOT
IF :count > 0 AND :name != "" [
TYPE (WORD "Active: " :name)
]
; 單一條件
IF :width > 40 [
SHOW "Width is very wide"
]
; 二分條件分支
IFELSE :env = "production" [
BOX "PROD SERVER" HEAVY
] [
BOX "DEV SERVER" ROUND
]
承襲經典 LOGO 的狀態旗標判斷,可將條件評估與執行動作解耦:
TEST :score >= 60
IFTRUE [ TYPE "PASS" ]
IFFALSE [ TYPE "FAIL" ]
當有多個互斥條件需要依序比對時,使用 COND 比巢狀 IFELSE 更清晰:
COND [
[ :level = 1 [ BOX "Junior" ROUND ] ]
[ :level = 2 [ BOX "Senior" SINGLE ] ]
[ :level = 3 [ BOX "Lead" HEAVY ] ]
[ "ELSE [ BOX "Unknown" ASCII ] ]
]
針對單一變數的不同枚舉值進行分支匹配:
SWITCH :role [
[ "admin [ TYPE "[Administrator Access Granted]" ] ]
[ "editor [ TYPE "[Editor Access Granted]" ] ]
[ "viewer [ TYPE "[Read-Only Access]" ] ]
[ DEFAULT [ TYPE "[Access Denied]" ] ]
]
在 REPEAT 迴圈中,:#(或 :repcount)代表當前第幾次循環(1-based):
; 自動輸出帶序號的 1. ~ 5. 清單
REPEAT 5 [
TYPE :# TYPE ". Item Description" NEWLINE
]
-
WHILE [ 條件 ] [ 區塊 ]:當條件為真時持續執行。 -
UNTIL [ 條件 ] [ 區塊 ]:當條件為真時終止。
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
]
-
FOR [變數 起始 結束 步長] [ 區塊 ]: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 |
在 FOREACH 中,? 代表當前走訪到的元素項目:
FOREACH ["Planning" "Development" "Testing" "Deploy"] [
BOX ? ROUND
TYPE " --> "
]
Important
安全防護機制:為了防止死迴圈或遞迴爆炸導致編輯器凍結,zago 內建兩大安全保護:
- 所有迴圈單次執行上限為 10,000 次。
- 程序遞迴呼叫深度上限為 256 層。
清單(List)是 Editor LOGO 的主要複合資料結構,使用中括號 [ ... ] 包裹。
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]
對清單中的每一項元素套用運算(? 代表當前元素):
MAKE "nums [1 2 3 4 5]
MAKE "squares MAP [? * ?] :nums
SHOW :squares ; 顯示 [1 4 9 16 25]
保留運算結果為真(非 0)的元素:
MAKE "scores [45 82 59 90 73 61]
MAKE "passed FILTER [? >= 60] :scores
SHOW :passed ; 顯示 [82 90 73 61]
將清單元素逐一聚合(?1 為累加值,?2 為下一個元素):
MAKE "nums [1 2 3 4 5]
MAKE "sum REDUCE [?1 + ?2] :nums
SHOW :sum ; 顯示 15
SHOW SORT [42 10 99 5 23] ; 顯示 [5 10 23 42 99]
SHOW SORT DESC ["Banana" "Apple" "Cherry"] ; 顯示 [Cherry Banana Apple]
使用 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"
-
OUTPUT 數值:回傳計算結果並結束程序。 -
STOP:立即終止程序執行(無回傳值)。
TO MAX_VAL :a :b
IF :a > :b [ OUTPUT :a ]
OUTPUT :b
END
SHOW MAX_VAL 42 99 ; 顯示 99
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 ""
將常用的 LOGO 程序寫入 ~/.zagorc 的 logo-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"| 指令 | 說明 | 範例 |
|---|---|---|
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 |
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 | ; 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
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 ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
在純文字編輯器中,直接使用 BOX、LINE 與 TABLE 等指令通常較為方便。不過為了延續經典 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
繪製結果:
─────┐
└────┐
└────┐
└────┐
│