若要辨別自動換行與儲存的換行字元,請在文字編輯器中關閉自動換行,並檢查原始文字。本 Mac 指南說明如何檢查、瀏覽器版面配置如何造成誤判,以及複製的程式碼實際上能證明什麼。

自動換行與換行字元有何不同?

自動換行是指瀏覽器或編輯器為了配合可用寬度,將文字移到另一個顯示列。儲存的換行字元則是文字本身的一部分。W3C 區分自動換行與強制換行;強制換行可能是由保留的換行字元或區塊邊界造成。CSS 空白字元處理會改變呈現方式,但不會改變底層文件資料。CSS Text Module Level 3

程式碼顯示在多個列上時,可能有三種情況:同一個邏輯行自動換行;文字包含多個邏輯行;或頁面的結構強制產生視覺上的換行。單靠螢幕截圖,無法可靠判斷是哪一種。

本文所說的「手動換行」是指在受檢查的來源文字中存在的換行字元。但換行字元的存在,無法證明是誰加入的:它可能是格式化工具、匯出程序或其他轉換所產生。實際上要判斷的是,該邊界屬於文字本身,還是只存在於目前的呈現方式中。

如何在 Mac 桌面編輯器中檢查程式碼?

本流程使用 Visual Studio Code。若有原始程式碼檔案,請從該檔案開始。如果只有公開網頁,請將相關程式碼複製到獨立的編輯器文件中;在能與原始內容比對之前,請將該文件視為複製文字的證據。

關閉自動換行,但不重新格式化文字

  1. 在 VS Code 中開啟檔案或複製的範例。
  2. 編輯器取得焦點時,按下 Option+Z 執行 Toggle Word Wrap。
  3. 觀察原本看似延續的文字是否在關閉自動換行後接回前一個顯示列,並向右延伸。
  4. 如果原本已關閉自動換行,再切換一次以比較兩種狀態。重點是兩種檢視方式之間的差異。

Microsoft 將 Option+Z 列為 macOS 上 Toggle Word Wrap 的預設快捷鍵,命令 ID 為 editor.action.toggleWordWrap。如果你的快捷鍵不同,請在 Keyboard Shortcuts 編輯器中尋找該命令。預設鍵盤快捷鍵參考

當 editor.wordWrap 設為 on 時,VS Code 會依編輯器檢視區的寬度自動換行。因此,關閉自動換行會移除這些視覺上的延續。若文字內容未經變更,而某個邊界仍然存在,那就是邏輯行邊界,而非該編輯器的自動換行。基本編輯

比較檢視畫面時,可參考下表:

觀察結果 可支持的判斷 下一步
關閉自動換行後,延續文字接回前一列 這是編輯器中的自動換行 保持文字不變
關閉自動換行後,兩行仍然分開 受檢查的文字含有行邊界 若檢查的是副本,請與原始內容比對
複製的文字中不再出現頁面上的邊界 頁面與複製後的表示方式不同 檢查頁面的文字與結構
複製的文字仍有邊界,但沒有原始內容可供比對 複製的文字含有該邊界 暫不判定其來源

試用合成範例

將以下單行範例貼到獨立文件中。這是示意用的 JavaScript 文字,無須執行。

const labels = ["Amber", "Birch", "Cedar", "Dune", "Elm", "Fern", "Grove", "Harbor"];

縮窄編輯器寬度,直到文字自動換行。開啟自動換行時,這段陳述可能會占用多個顯示列。關閉自動換行後,這段文字應恢復為一個邏輯行,即使你必須水平捲動才能讀到末尾。

現在比較以下刻意分成多行的版本:

const labels = [
  "Amber", "Birch", "Cedar", "Dune",
  "Elm", "Fern", "Grove", "Harbor"
];

關閉自動換行後,這四個邏輯行仍會分開。寬度較窄時,其中任何一行也可能自動換行。這就是實用的判別方式:儲存的換行字元與自動換行可能同時出現在同一段程式碼中。

比較時請避免格式化文件。目的是在保持受檢查文字不變的情況下改變檢視方式。否則,行邊界的變化可能是編輯造成的,而非顯示設定造成的。

為什麼調整瀏覽器大小只能做初步檢查?

想像一個抽象的公開頁面,其中有導覽欄和程式碼面板。加寬瀏覽器可能會讓面板有更多空間。如果邊界移到另一個單字的位置,這可支持自動換行的推測。不過,如果面板寬度固定,調整外部視窗大小可能不會改變面板。

因此,邊界位置不變並不能得出結論。瀏覽器可能保留了換行字元、遇到結構上的換行,或是在可用寬度沒有改變的面板中自動換行。請對照文字表示方式確認結果,不要把調整視窗大小當作證明。

CSS 也會決定儲存的換行字元是否可見。MDN 說明了以下常見值:white-space CSS 屬性

CSS 值 對來源換行字元的處理 是否自動換行
normal 與其他空白字元合併 允許
pre 保留 停用
pre-wrap 保留 允許
pre-line 保留;空格與定位字元會合併 允許

因此,pre-wrap 可以同時顯示這兩種邊界,而 normal 可能會隱藏來源換行字元。使用 nowrap 停用自動換行,不足以驗證來源是否保留,因為它也會合併空白字元。對於由你控制的簡單文字區塊,若需要保留空白字元且不自動換行,pre 是適合的比較值。white-space CSS 屬性

複製的文字能顯示原始換行字元嗎?

複製的文字很有用,但它是另一種表示方式。MDN 將 innerText 描述為呈現後的文字,近似於選取並複製某個元素時會得到的內容。它會依據呈現後的外觀做出反應,包括 br 元素等明確換行。因此,貼上的範例中出現換行字元,本身並不能證明原始程式碼字串中就有該字元。HTMLElement:innerText 屬性

對於簡單的靜態程式碼容器,textContent 回答的是另一個問題:它會傳回節點及其子代的文字,串接子代文字時不會採用呈現後的外觀。只要容器確實包含你要查看的程式碼,這個屬性就適合用來檢查 DOM 文字。Node:textContent 屬性

這些屬性不能互換用來還原內容。結構上的換行不一定是 textContent 中的換行字元;反過來說,來源空白字元也可能存在,卻沒有呈現為視覺上的換行。如果頁面文字與版面配置不一致,請精確描述結果:「DOM 文字含有換行字元」、「版面配置強制換行」或「複製的版本含有換行字元」。不要聲稱超出受檢查表示方式所能證明的內容。

瀏覽器版程式碼編輯器有何不同?

瀏覽器編輯器可能會將文件與顯示元素分開管理。例如,CodeMirror 的官方原始碼文件以 Text 模型描述文件行:lines 會計算邏輯行數,line(n) 會取得指定行。行的 to 位置在後續換行字元之前,或位於文件末尾。CodeMirror 文件文字 API 文件

CodeMirror 也指出,其檢視會將可見程式碼及周圍的邊距繪製到 DOM 中。其 lineWrapping 屬性描述檢視中的自動換行。由於這些邊界,計算呈現後的列數或擷取可見的編輯器 DOM,不足以判定完整文件包含哪些行。CodeMirror 編輯器檢視 API 文件

進行一般桌面檢查時,若有提供,請使用主應用程式中有文件說明的檔案下載、匯出或複製命令,然後在關閉自動換行的狀態下檢查結果。如果你維護 CodeMirror 整合,請使用其文件模型判定邏輯行。函式庫 API 的存在,不能證明每個應用程式都提供相同的使用者操作功能。

表單會加入從未輸入過的換行字元嗎?

會。WHATWG HTML 標準區分 textarea 的目前 API 值與提交表示方式。使用 wrap="soft" 時,文字可能在視覺上自動換行,但提交內容不會因此額外換行。使用 wrap="hard" 時,提交表示方式可能會增加換行;此狀態必須指定 cols。API 值會將行尾正規化為 LF。HTML 標準:textarea 元素

比較表單工作流程前後的文字時,這點很重要。若某個邊界只出現在提交或匯出的結果中,可能是由該處理階段造成。請檢查與你的任務相關的表示方式:要辨識輸入的邊界,就檢查編輯器目前的文字;要判定實際匯出的內容,則檢查產生的檔案。

如何保留瀏覽器與文字塑形的邊界?

讓瀏覽器或編輯器處理視覺換行。W3C 規定,overflow-wrap: anywhere 會讓字素叢集保持完整,並在新增的換行處保留文字塑形。每隔固定字元數插入換行字元來重建各行,無法重現這些版面配置規則。CSS Text Module Level 3

若要重複使用程式碼範例,請先取得最可靠的來源,比較開啟與關閉自動換行時的結果,並保留其中儲存的行邊界,除非你打算編輯內容。如果只有呈現後的頁面可用,請記錄你能從該表示方式確認的內容,並讓不確定的邊界維持未判定。這樣便能以可重複的方式進行檢查,也不會因調整顯示方式而意外改動文字。

來源