情况

情况

#当我在命令和环境中使用井号/数字符号/散列符号时,这指的是参数。然而,不应该\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将定义为单参数宏。\def\baz#1{-#1-}\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最终解析为\def,我们可以使用来做你想做的事情\edef

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

相关内容