
#
當我在命令和環境中使用井號/數字符號/井號時,這指的是參數。然而,不應該\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