NewEnviron 環境内でもパラメータにアンダースコアを保持する

NewEnviron 環境内でもパラメータにアンダースコアを保持する

私はついていきますこの答えパラメータ内のアンダースコアを保持できるようなコマンドを定義します。

NewEnvironただし、 fromで定義された環境内でコマンドが呼び出された場合は、これは機能しませんenviron

\documentclass[a4paper]{scrreprt}
\newcommand{\cmd}{\begingroup
  \catcode`_=12 \cmdint}
\newcommand{\cmdint}[1]{%
  \texttt{#1}%
  \endgroup
}

\newenvironment{wrap}{}{}
\usepackage{environ}
\NewEnviron{wrap2}{\BODY}

\begin{document}
\cmd{some_test}

\begin{wrap}
  \cmd{some_test}
\end{wrap}

\begin{wrap2}
  \cmd{some_test}
\end{wrap2}
\end{document}

これは次のようにコンパイルされます

ここに画像の説明を入力してください

どうしても必要な場合environ(実際のドキュメントでこれを削除しようと 1 時間ほど苦労しましたが、成功しませんでした)、どうすればこれを修正できますか?

答え1

解決策は、変数に使用されるアルファベットによって異なります。これらが大文字と小文字、数字、アンダースコア、およびその他の無害な記号 (カテゴリ コード 12/その他、句読点文字) を含む識別子である場合は、次のコードを使用して、\detokenize識別子のカテゴリ コードをカテゴリ コード 12 (数字と同じ) のトークンに正規化できます。

\documentclass[a4paper]{scrreprt}

\newcommand*{\cmd}[1]{\texttt{\detokenize{#1}}}

\newenvironment{wrap}{}{}
\usepackage{environ}
\NewEnviron{wrap2}{\BODY}

\begin{document}
\cmd{some_test}

\begin{wrap}
  \cmd{some_test}
\end{wrap}

\begin{wrap2}
  \cmd{some_test}
\end{wrap2}
\end{document}

結果

答え2

\scantokensこれもうまく当てはまる状況のようです:

\documentclass[a4paper]{scrreprt}
\newcommand{\cmd}{\begingroup
  \catcode`_=12 \cmdint}
\newcommand{\cmdint}[1]{%
  \texttt{\scantokens{#1\noexpand}}%
  \endgroup
}

\newenvironment{wrap}{}{}
\usepackage{environ}
\NewEnviron{wrap2}{\BODY}

\begin{document}
\cmd{some_test}

\begin{wrap}
  \cmd{some_test}
\end{wrap}

\begin{wrap2}
  \cmd{some_test}
\end{wrap2}
\end{document}

オリジナルの問題は\NewEnviron、型環境内でトークンが既に読み込まれ、マクロに渡される前にその catcode が既に設定されていることです。 を使用すると\scantokens、catcode は基本的に再割り当てされます。

使用方法の詳細については、\scantokens@egregが私の質問に対する回答としてわかりやすく説明しています。誰か、拡張、キャットコード、スキャントークンについてさらに詳しく説明してくれませんか…?

関連情報