catcode 5「行尾」何時發揮作用?

catcode 5「行尾」何時發揮作用?

我的目標是理解之間的關係字元位元組字元標記關於新行位元組。我可能沒有掌握事實。

當 TeX 讀取位元組檔案時,必須考慮編碼。拋開這一點來說,

  • 我們可以觀察到一個單一換行字元位元組(假設 LF 和 CRLF)被轉換為空格。但幕後發生了什麼事?令牌是使用資料對(LF 位元組數,catcode=10)創建的嗎?

  • 兩個連續的換行字元位元組與資料對(空間位元組數,catcode 5)成為一個單一的令牌?

catcode 5「行尾」何時發揮作用?

我知道 LaTeX\par在遇到兩個連續的行結尾時會插入 a 。

程式碼

我嘗試用​​catcode 5直觀地顯示令牌,但我仍然不確定是否\tmp真的成為catcode 5。

\documentclass{article}
\usepackage{fontspec}% xelatex

\long\def\scan#1{#1\par\rule{\textwidth}{2pt}\par\xscan#1\relax}
\long\def\xscan{\afterassignment\xxscan\let\tmp= }
\long\def\xxscan{%
\ifx\tmp\relax\else%
\ifcat\tmp\space10 \else%
\ifcat\tmp a11 \else%
\ifcat\tmp 112 \else%...
\ifcat\tmp

5
\else%
\fi\fi\fi\fi
\expandafter\xscan
\fi}

\begin{document}
\scan{  mac::exception  ==

a
}
\end{document}

在此輸入影像描述

筆記

答案1

從來沒有任何帶有catcode 5 的令牌。

Initex成立

\catcode`\^^M=5

但這的作用類似

\catcode`\%=14

這使得%catcode 14,但是沒有帶有該 catcode 的標記,如果掃描了帶有 catcode 14 的字符,則該字符和該行的其餘部分將被丟棄。

catcode 5 的字元產生一個空格字符,並將 tex 的掃描器置於特殊模式,導致緊接著的 catcode 10 字元被丟棄“行首的空白”,並且 catcode 5 的後續字元被標記為\par不存在空格標記“空白行相當於\par

因此請注意,第一個換行符總是會產生一個空格,後續的換行符會產生\par一個空格,因此空行通常相當於space\par

答案2

角色有類別代碼;他們在標記化階段產生字元標記,但它們不需要到。

類別代碼有雙重用途:在標記化期間(當 TeX 從輸入檔案或終端吸收文字時)以及標記清單處理期間查看它們。

僅限帶有類別代碼的字符

1 2 3 4 6 7 8 10 11 12 13

可以分別產生字元標記(具有相同的類別代碼)

開始組
結束組
數學移位
對齊
參數
上標下標 空格
字母 其他字元 活動 字符



類別代碼為 0 5 9 14 15 的字元將絕不產生具有相同類別代碼的字元標記:具有這些類別代碼的字元標記無法在 TeX 內部標記處理器中通過:

  • 類別代碼0的字元觸發控制序列的形成

  • 類別代碼為 9 的字元將被忽略

  • 類別代碼 15 的字元會引發錯誤,然後被忽略

  • 類別代碼 14 的字元告訴標記化處理器將其與該行中的所有其他字元一起忽略

更有趣的是類別代碼 5,它是您問題的對象。當 TeX 找到一個時,它會丟棄輸入行上剩餘的任何內容,產生一個空格字符字元代碼 32 和類別代碼 10 就好像它已經在線上一樣,並將掃描器設定為忽略空格(類別代碼 10)的特殊狀態,直到出現不同的內容:如果這是類別代碼的另一個字元5、TeX產生\partoken,否則進入正常狀態。

注意強調空格字符上圖:此空格字元根據正常規則進行標記,因此如果它位於控製字(如\foo)之後但不在控制符號(如\~)之後,它將被忽略。

這樣做的結果是以下輸入

\foo\baz

\foo \baz

\foo \baz

是完全等價的。請注意,如果最後一個輸入中的行尾產生了空間令牌,會有差異。但確實是一個空格字符(尚未標記化)是生成的。

筆記。當面對控制詞的形成時,上面關於被忽略字符的說法可能會產生誤導。控製字的形成以類別代碼 0 字元開始,後面跟著類別代碼 11 之一。類別代碼為9)。

關於 XeTeX 和 LuaTeX 的附錄。當 UTF-8 編碼檔案被輸入 Unicode 識別引擎時,字元在其 UTF-8 表示中是單字節、二位元組、三位元組還是四位元組長並不重要。這兩個引擎執行將 UTF-8 組合轉換為 Unicode 實體的初步步驟,因此標記化處理器看到的只是一個字元(其類別代碼在初始化表中分配)。這兩個引擎也能夠處理 UTF-16 或 UTF-32、小端或大端。

答案3

TeX 確實逐行讀取輸入:將讀取並處理一行輸入。然後另一行輸入將被讀取並處理。 …

TeX 在讀取一行輸入後所做的第一件事就是將字元從電腦平台的字元編碼方案轉換為 TeX 引擎的內部字元編碼方案。對於傳統的 TeX 引擎,內部字元編碼方案是 ASCII,即美國資訊交換標準代碼。對於基於 LuaTeX 或 XeTeX 的 TeX 引擎,內部字元編碼方案是 Unicode,其中 ASCII 是嚴格的子集。

之後 TeX 刪除該行右端的所有空格字元。更精確地說:之後 TeX 刪除該行右端的所有字元代碼為 32 的字元。

然後 TeX 在行的右端插入一個字符,其字符代碼等於整數參數的值\endlinechar
通常值為\endlinechar13,字元13(返回字元)的類別代碼為5(行尾)。

這表示在標記行到達行尾時,TeX 通常會遇到類別代碼為 5(行尾)的字元。

然後 TeX 開始標記該行。即,TeX「查看」該行包含的字符,並根據類別代碼表和根據閱讀設備的狀態產生控制序列標記和字符標記。

在讀取和標記輸入時,TeX 的讀取設備可以處於以下三種狀態之一:

狀態:跳過空格。讀取裝置將處於狀態S

  • 處理來自類別代碼為 10(空格)的輸入的字元後。
  • 在處理類別代碼7(上標)的兩個相等字元的序列之後,後面跟著形成類別代碼為10(空格)的字元的小寫十六進位表示法的字元代碼的兩個字元序列。
    [範例:通常 的類別代碼為^7(上標),而字元 32(空格字元;十六進位 20)的類別代碼通常為 10(空格)。因此,符號^^20通常被視為處理輸入中的字元 32(空格字元),其類別代碼通常為 10(空格)。
  • 在處理類別代碼 7(上標)的兩個相等字符的序列後,後跟一個字符,其中 - 如果字符的字符代碼在 64 到 127 的範圍內 - 通過減去其字符代碼獲得的字符的類別代碼64是10(空格)。
    [例:由於 的類別代碼^通常為 7(上標),而 的字元代碼`為 96,而 96-64=32,而字元 32(空格字元)的類別代碼通常為 10(空格),因此^^`通常將符號處理就像處理類別代碼通常為 10(空格)的輸入中的字元 32(空格字元)一樣。
  • 在處理類別代碼 7(上標)的兩個相等字符的序列後,後跟一個字符,其中 - 如果字符的字符代碼在 0 到 63 的範圍內 - 通過添加其字符代碼獲得的字符的類別代碼64 是10(空格)。
  • 在產生控製字令牌之後。
  • 在產生一個控制符號令牌之後,該控制符號令牌的名稱由類別代碼10(空格)的字元組成。例如,在產生控制符號標記\␣(控制空間)之後。

在狀態 S 中,處理類別代碼為 10(空格)的字元和處理被視為等同於類別代碼 10(空格)的字元的^^..-sequence/ <superscript-char><superscript-char>..-sequence 都不會產生任何標記,也不會改變狀態閱讀裝置。

通常,空格字元(字元代碼 32)和水平製表符(字元代碼 9)是唯一類別代碼為 10(空格)的字元。

這就是為什麼你可以在輸入中包含多個連續的空格字元或水平製表符,通常只產生一個空格標記,反過來,在TeX 處於其中一種空格標記產生模式的情況下,僅產生一個水平空格的水平黏合水平黏合(即,在水平模式下、在受限水平模式下,但既不在垂直模式下、也不在內部垂直模式下、也不在數學模式下、也不在顯示數學模式下)。

狀態 M:線的中間。讀取裝置將處於狀態M

  • 產生非空格字元標記後。
  • 在產生一個控制符號令牌之後,該令牌的名稱由不屬於類別代碼 10(空格)的字元組成。

當處於狀態 M 時,處理類別代碼為 10(空格)的字元和處理被視為等同於類別代碼 10(空格)的字元的^^..-sequence/ -sequence 都會產生一個空格標記,即,一個字元標記,其<superscript-char><superscript-char>..charcode為32(空格字元),catcode為10(空格),將讀取裝置的狀態切換至狀態S。

狀態 N:新隊。當讀取裝置即將開始讀取另一行輸入時,讀取裝置處於狀態N。在狀態 N 中,處理類別代碼為 10(空格)的字元和處理被視為等同於類別代碼 10(空格)的字元的^^..-sequence/ <superscript-char><superscript-char>..-sequence 都將不會產生任何標記,也不會改變狀態閱讀裝置。

如果 TeX 在讀取裝置處於狀態 S 時遇到類別代碼 5(行尾)的字符,則 TeX 將根本不會產生任何標記。

如果TeX 在閱讀裝置處於狀態M 時遇到類別代碼5(行尾)的字符,TeX 將產生一個空格令牌,即字符代碼為32(空格字符)、類別代碼為10(空格)的字符令牌。

如果 TeX 在讀取裝置處於狀態 N 時遇到類別代碼 5(行尾)的字符,TeX 將產生控製字 token \par

遇到類別代碼 5(行尾)的字元後,TeX 將- 無論讀取裝置處於什麼狀態 -無論如何,請刪除當前行上的任何進一步資訊並開始讀取另一行輸入。由此TeX的讀取裝置將切換到狀態N。

由於上述\endlinechar-thingie 通常非空白行後面的空白行將產生 TeX 處理兩個連續的回傳字元(字元代碼 13),其類別代碼為 5(行尾)。

當遇到這些回傳字元中的第一個(位於非空白行)時,讀取裝置可能處於狀態 S 或狀態 M,因此第一個回傳字元可能根本不會產生令牌或產生空間令牌。
無論如何,在遇到這些返回字元中的第一個之後,讀取裝置將切換到狀態N。當遇到這些返回字元中的第二個時,讀取裝置將處於狀態N並且這些返回字元中的第二個將產生控製字令牌 \par
這就是為什麼通常空行被視為“段落分隔符”/像控製字標記一樣,\par它通常(如果沒有重新定義)是用於換行並排版為現在收集/收集的材料的文本段落的指令。

這意味著段落中的最後一個內容可能是產生水平黏合的空格標記。請注意,段落末尾的這種水平粘合通常會被 TeX 丟棄,並根據\parfillskip-glue-參數的值將粘合附加到段落末尾。

相關內容