状況

状況

#コマンドや環境内でポンド記号/数字記号/ハッシュ記号を使用すると、これは引数を指し\detokenize{#}ます。ただし、ない引数?

状況

ポンド記号はログ ファイル内の区切りとして便利です。

\detokenizeエラーを取得するには、2 番目のコメントを解除してみてください。

\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 が含まれる場合は、それを 2 重にする必要があります。

マクロ定義の置換テキストを処理する場合、単一の#後には対応する引数へのポインタを示す数字(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{####}}

置換テキストでは実際には2つ表示されます#が、最終結果は4つになります。処理時の標準的なメカニズムでは、\edefまず数を半分にして#から\detokenize2倍に戻します。特に、できないこのようにして奇数個の を生成します#

区切り線を生成する場合は、カテゴリ コード 12 を含む必要なトークン リストを事前に作成する間接的な方法を使用する方がはるかに適切です。#例では、奇数であるため、3 つ使用しています。

\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ことを意味しますが、展開されるとパラメータとして扱われます。通常の割り当て ( LaTeX ではTeX プリミティブとして) では展開は行われないことを覚えておいてください。ここで、 はとまったく同じトークンの「保存」を実行します。これは、マクロの作成時に、それぞれに一致するパラメータが存在するか、トークンが 2 倍になっている必要があるという通常の TeX ルールがあることを意味します。#\newcommand\def\newenvironment\newcommand##

\newenvironmentは最終的に に解決されるため\def、 を使用して必要な操作を実行できます\edef

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

関連情報