情況

情況

#當我在命令和環境中使用井號/數字符號/井號時,這指的是參數。然而,不應該\detokenize{#}成功不是一個論點?

情況

井號是日誌檔中很好的分隔符號。

例子

嘗試取消註釋第二個\detokenize以獲取錯誤。

\documentclass{article}
\usepackage{fontspec}% compile with xelatex
\newenvironment{detokenizetest}[1]
{% firstoftwo
 \detokenize{##############################################################################}%
 %\detokenize{##BEGIN#######################################################################}% uncommenting this causes a compile error
}%
{% secondoftwo
}%
\begin{document}
\null
\end{document}

錯誤輸出

僅當取消註解包含 的行時才會發生此錯誤BEGIN

! Illegal parameter number in definition of \detokenizetest.
<to be read again>
                   }
l.9 }
     %
?

答案1

由於#類別代碼為 6,因此它在 TeX 中具有非常特殊的含義,因為它用於表示巨集定義中的參數。

TeX 的規則告訴你,當你想要店鋪a#在巨集的替換文字中,您需要將其加倍。

在處理巨集定義的替換文字時,單一字元後面#必須跟一個數字(1 到 9),表示指向對應參數的指針,而##將儲存為#.這是允許類似的事情的技巧

\def\foo{\def\baz##1{-##1-}}

\foo因此is的替換文字\def\baz#1{-#1-}和 will 的呼叫\foo定義\baz為單一參數巨集。

\detokenize替換文本中的原語將完成其工作當巨集被呼叫並展開時,不在定義時,除非定義是用 完成的\edef,它將首先執行完全擴展,然後將替換文字儲存在記憶體中。

請注意,當您這樣做時\meaning\foo(假設上述定義),您將看到

macro:->\def \baz ##1{-##1-}

\detokenize使用相同機制也會發生同樣的情況。因此像

\edef\hashmarks{\detokenize{####}}

實際上會在替換文字中看到兩個#,但最終結果將是其中四個。處理時的標準機制\edef將首先將數量減半#,然後\detokenize將其加倍。特別是,你不能以這種方式產生奇數個#

如果要產生分隔符號行,最好使用間接方法,提前製作由#類別代碼 12 組成的所需標記清單。

\documentclass{article}

\begingroup\lccode`?=`# \lowercase{\endgroup
  \newcommand{\lineofhashsigns}{???}
}

\newenvironment{delimitedtext}
  {\par\lineofhashsigns\par}
  {\par\lineofhashsigns\par}

\begin{document}

\begin{delimitedtext}
abc
\end{delimitedtext}

\end{document}

在此輸入影像描述

\lineofhashsigns不需要的不同定義\lowercase是透過更改類別代碼:

\catcode`#=12
\newcommand{\lineofhashsigns}{###}
\catcode`#=6

您可以在替換文字中新增任何標記,只要您不希望巨集有參數即可。

答案2

\detokenize語確實意味著#不被視為參數,而是在擴展時被視為參數。請記住,在正常的賦值中(\newcommand在 LaTeX 中,\def作為 TeX 原語)不會發生擴展。在這裡,\newenvironment執行與「僅儲存」令牌完全相同的操作\newcommand。這意味著我們有通常的 TeX 規則,即在創建巨集時,我們必須為每個#呈現提供匹配的參數,否則我們必須將#標記加倍。

由於\newenvironment最終解析為 a \def,我們可以使用以下命令執行您想要的操作\edef

\edef\detokenizetest#1{%
 \detokenize{##############################################################################}%
 \detokenize{##BEGIN#######################################################################}%
}
\def\enddetokenizetest{}% As \newenvironment will do this
\show\detokenizetest

相關內容