定義巨集時忽略製表符和換行符是否安全?

定義巨集時忽略製表符和換行符是否安全?

我已經編寫了幾個 LaTeX 環境來格式化大學專案的「用例流」序列。作為一名電腦程式設計師,我發現無法使用換行符和縮排(如C/Java 程式碼)來格式化LaTeX 程式碼並使其更具可讀性非常煩人,因為我知道我必須意識到“虛假空格”問題。我知道我可以使用 來建立安全的換行符%,但這仍然很奇怪。

然後,我記得 TeX 讀取的每個字元都分配了一個控制其行為的“catcode”,並且有一個必須忽略的字元的 catcode (9)。因此,我想到暫時更改換行符和製表符的目錄代碼(將用於程式碼格式化)並在定義巨集時忽略它們。例如,這段程式碼:

% UCSubFlow counter definition, etc
\newenvironment{subflow}[1]{%
\subparagraph{Subflow \arabic{UCSubFlow}: #1}%
\stepcounter{UCSubFlow}%
\begin{enumerate}%
}{%
\end{enumerate}%
}

在我看來,讀起來更令人愉悅:

% Ignore tabs and newlines
\catcode9=9
\catcode13=9

% UCSubFlow counter definition, etc
\newenvironment{subflow}[1]{
    \subparagraph{Subflow \arabic{UCSubFlow}: #1}
    \stepcounter{UCSubFlow}
    \begin{enumerate}
}{
    \end{enumerate}
}
% More macro definitions...

% Return tabs and newlines back to normal
\catcode9=10
\catcode13=5

行首的間距是製表符,而不是空格(它們仍然使用)。我假設:

  • 大多數時候,巨集<tab>在其定義中不使用 s
  • 大多數時候,巨集沒有大段文字。如果我想在巨集中開始一個段落,最好使用\par
  • 宏總是可以寫在一行(很長的宏,但無論如何都是一行)

我已經在我的文檔中使用了它,似乎一切正常。環境按預期運行,似乎沒有破壞任何東西。當然,我的環境非常簡單(一個特殊的清單)。我的問題是:當涉及到巨集編寫時,這種「駭客」總體上安全嗎? (特別是如果我在我的巨集中使用其他套件的巨集)

答案1

首先,你的意圖可以透過簡單的設定來實現\endlinechar=-1。不需要設定catcode,因為^^M\endlinechar-1導致該字元未被插入。您不需要為^^I(tab) 設定 catcode,因為空格和製表符的 catcode 為 10,並且它們在每行的開頭都會被忽略。

但這樣的設定是危險的。當然,這不能放在文檔的普通文本中,因為之後:

 Hello
 world!

我們得到Helloworld!作為結果。並且僅在巨集讀取時使用此設定?想像一下定義:

\def\a{Hello
       world!}

那麼就會出現和上面同樣的問題。而且問題還可以更隱蔽,例如:

\def\b{\ifnum\something=0
            123%
        \else
            456%
        \fi
}

現在,如果每行末尾存在空格,那麼我們就有了,if(somenthing=0) 123 else 456 fi但是如果這裡不存在空格,那麼我們就有了if(something=0123) else 456 fi,這是此類宏的完全不同的行為。

相關內容