一個完全在瀏覽器中執行的直書文字產生器替代方案,將純文字的 grapheme 叢集重新排列為由上至下的欄位,並明確指定由左至右或由右至左的欄位順序,最多可接受 5,000 個 grapheme 叢集與每欄最多 100 列,並輸出可下載的 UTF-8 TXT 檔案,無需上傳您的原始文字。大多數較舊的直書文字工具會把 emoji 拆成個別的程式碼單位、以隱形方式呈現換行,或依賴無法貼上到聊天視窗、程式碼區塊或純文字欄位的 CSS writing-mode 標記。Lizely 上的 Vertical Text Generator 採取相反的路徑:使用瀏覽器的 Intl.Segmenter 以 grapheme 細粒度切分文字、將每個既有的 CRLF、CR 與 LF 邊界視為一個全形空白儲存格,然後用兩個普通空格與 LF 列分隔符連接產生的欄位。由於每個步驟都在本機進行,您可以貼上包含未完成草稿、機密筆記或測試字串的內容,並在下次造訪時獲得相同的版面,且由於相同輸入、高度與方向會產生決定性的版面,兩次執行會產生完全相同的儲存格。

為什麼搜尋者會尋找直書文字產生器的替代方案
搜尋替代方案的人通常已經嘗試過至少一種常見模式並碰壁。某些產生器會產生包裹在 HTML 中的 CSS writing-mode 標記,在瀏覽器中看起來是直書,但一貼到聊天視窗、README 檔案或試算表儲存格中就會失去形狀。其他產生器則會產生圖片或 SVG,這表示文字變得無法選取、無法搜尋,且必須重新執行整個流程才能編輯。第三類則將您的輸入視為原始 UTF-16 程式碼單位,這會以不符您在鍵盤上輸入的方式反轉或拆開國旗組合、家庭 emoji、膚色修飾符與組合附加符號。
還有一個隱私層面。許多網頁型產生器會將您貼上的文字傳送到後端進行算繪,即使該操作簡單到可以在瀏覽器中執行。如果您要貼上草稿歌詞、未完成的提示,或您較不想上傳的名稱,這個往返過程就是錯誤的細節。對於課堂範例、有字幕的螢幕擷圖,以及來源字串本身就是成果物的短雙語顯示,同樣的疑慮也會出現。
因此,一個實用的替代方案必須同時完成四件事:保持 emoji 叢集完整、讓既有換行以間隙形式可見、產生可貼上到任何地方的純文字,以及無需上傳任何內容即可執行。接下來的章節將說明 Vertical Text Generator 如何處理每項需求、其限制為何,以及它在哪些地方刻意不做到完整版面引擎的程度。
這個替代方案有何不同
第一個差異在於切分。該工具透過以 Unicode grapheme 細粒度為基礎、基於 Intl.Segmenter 的 grapheme 公用程式來切分輸入,並為有需要的瀏覽器提供經過測試的後備方案。這很重要,因為使用者與大多數文字表示方式都是以 grapheme 思考:一個 emoji、一面國旗、一個帶附加符號的字母。將一面國旗的位元組拆成兩個字母,或將讚符號加上膚色修飾符拆成個別欄位,是人們從其他產生器轉換過來時最先注意到的錯誤。參考行為記錄於 Unicode UAX #29, Text Segmentation,並透過 MDN 的 Intl.Segmenter 參考 在瀏覽器中公開。
第二個差異在於換行處理。在 grapheme 版面開始之前,每個辨識出的 CRLF、CR 與 LF 邊界會被正規化為一個全形空白儲存格。該儲存格佔用與一般 CJK 字元相同的水平空間,因此即使在該處沒有輸入可見字元,後續欄位仍會保持對齊。空白儲存格不會啟動新的直書區塊;它存在於同一個矩形版面中,這使得輸出保持矩形而非階梯狀。連續的換行會產生連續的空白儲存格。
第三個差異在於本機處理。切分、版面、預覽算繪,以及用於下載的 UTF-8 Blob URL 都在同一個分頁中建立。不會查詢任何語言對應、字典、字型服務、遠端模型或外部內容資料庫。Blob URL 僅存在於觸發下載的那次點擊,並會立即撤銷。更動文字、頁數或方向會清除先前的結果,因此舊版面不會與目前設定混淆。
第四個差異在於決定性。在相同的瀏覽器切分行為、相同的來源、相同的頁數與相同的方向下,產生的儲存格序列在多次執行間是相同的。這使得輸出易於 diff、易於測試,且易於貼上到程式碼審查中而不會產生意外,這正是替代方案應當提供的能力。
如何使用 Vertical Text Generator 排列直書文字
互動刻意保持精簡。下列每個步驟都是該工具實際公開的功能;沒有精靈、沒有預覽循環,也不需要等待伺服器。
- 開啟 Vertical Text Generator,將您要排列的文字貼上或輸入到輸入欄位中。
- 選擇 1 到 100 的整數作為欄位頁數。此設定控制在下一欄開始之前,從上到下填入第一個邏輯欄的 grapheme 叢集數量。
- 選擇邏輯欄由左至右或由右至左顯示。由左至右會將第一個來源欄放在視覺左側;由右至左則反轉欄位順序,使第一個來源欄位出現在視覺右側。
- 產生版面。工具會回報來源 grapheme 數量與產生的輸出欄數,讓您在下載前確認形狀。
- 檢查等寬預覽,確認 emoji 保持完整,且您的換行在預期欄位位置顯示為可見的空白儲存格。
- 將結果下載為 UTF-8 TXT 檔案。下載的字串與預覽完全一致,並使用 LF 列分隔符,因此在編輯器、聊天視窗與程式碼區塊中貼上的方式相同。
舉一個實際範例,假設您的來源是 ABCDE 五個字元,在 C 與 D 之間有一個換行,且您選擇頁數 2 與由左至右順序。換行會被正規化為一個全形空白儲存格,共有六個位置要排列。第一欄放入 A 與 B。第二欄放入 C 與全形空白儲存格。第三欄放入 D 與 E。預覽會回報六個來源 grapheme 與三個輸出欄,欄與欄之間以兩個空格連接。相同來源與頁數在由右至左順序下會產生相同的儲存格序列,但欄位會在視覺上鏡像:D 與 E 欄出現在視覺左側,空白儲存格欄位在中間,A 與 B 欄出現在視覺右側。
如果較短的頁數會產生超過 50 欄,工具會要求較高的欄位,而不是產生極寬的預覽。此保護機制將輸出維持在下方限制所定義的水平捲動預算內,且這是該工具少數會拒絕算繪而非靜默截斷的位置之一。
限制與輸入一覽
下列數字為官方運作限制,非行銷文案。達到任一限制會在顯示任何部分結果之前產生明確錯誤,且該工具絕不會靜默截斷來源文字。
| 設定 | 允許值 | 達到限制時的行為 |
|---|---|---|
| 輸入 grapheme 叢集 | 1 至 5,000 | 超過 5,000 個叢集:明確錯誤,無部分版面。 |
| 欄位頁數 | 1 至 100 的整數 | 小數或超出範圍的值:明確錯誤。 |
| 輸出欄數 | 1 至 50 | 若較短頁數會產生超過 50 欄:工具會要求較高的欄位。 |
| 欄位顯示順序 | 由左至右或由右至左 | 任何其他方向值:明確錯誤。 |
| 空輸入 | 在切分前拒絕 | 空輸入:明確錯誤。 |
| 格式錯誤的 UTF-16 代理對 | 在切分前拒絕 | 僅代理或未配對輸入:明確錯誤。 |
由於切分在本機執行,且下載的檔案與預覽字串完全一致,相同的限制同時規範頁面上的預覽與儲存的 TXT。沒有預覽層級與較小下載層級的區別,這就是為什麼當規則被違反時永遠不會出現部分結果。
這個替代方案不適用的情境
純文字排列有其上限。Vertical Text Generator 並非排版引擎,將其用於下列用途之一,將會產生在一種字體中看起來正確、在另一種字體中卻錯誤的輸出。
- 日文的縱中橫(直書中旋轉的雙字元序列)、旋轉標點與 ruby 註解需要真正的排版引擎,而不是插入空格。
- 中文斷行、蒙古文由上至下版面與雙向塑型需要具語言感知能力的版面引擎,而不是純文字填補。
- 印刷出版需要能逐字元控制字形旋轉、字型度量與頁面幾何的設計工具,這是插入空格無法做到的。
對於讀者期待可選取、具回應式文字的真實網站,CSS writing-mode 與對應的語言排版是更易於使用的選擇,因為文字保持可選取且無需插入空格即可重排。希望深入純文字工作流程的讀者,可以依照 Vertical Text That Pastes Anywhere in Plain Text 中的步驟操作;若想更廣泛地了解這個工具所屬的替代方案框架,Bold Text Generator Alternative That Runs in Your Browser 遵循相同的純本機模式,但提供不同的輸出形狀。
替代方案適用於真實工作流程之處
這個工具是為可攜式的純文字排列而設計,而非用於可發佈的版面。裝飾性標題、詩詞實驗、垂直標籤、簡短雙語展示、課堂範例、社群貼文以及純文字模型稿,都是插入空格和全形空白恰到好處的場景。一段簡短的雙語問候語、學習卡片上的化學堆疊、有標題的螢幕截圖模型稿,以及論壇橫幅上一整排垂直排列的使用者名稱,這些都是屬於輸出之後必須以純文字形式貼到其他地方的成品類型。
兩個實用的提醒作為本文的結尾。第一個是:可見的字形在不同字型和系統上仍然可能呈現不同的效果,特別是在使用比例字型、備用表情符號字型、定位字元以及混合寬度文字時更是如此,因此發佈前務必在最終目的地的字型中預覽結果。第二個是:對於特定的瀏覽器分段行為、來源、高度和方向而言,版面是確定性的,因此相同的輸入在重新載入後會產生相同的輸出,這也正是純文字垂直版面能作為可重現的成品,而非一次性螢幕截圖的原因。