Сохранение подчеркиваний в параметрах даже внутри сред NewEnviron

Сохранение подчеркиваний в параметрах даже внутри сред NewEnviron

Я последовал заэтот ответдля определения команды таким образом, чтобы в ее параметрах можно было сохранить подчеркивания.

Однако это не сработает, если команда вызывается внутри среды, которая была определена с помощью NewEnvironfrom 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

Решение зависит от алфавита, используемого для переменных. Если это идентификаторы с заглавными и строчными буквами, цифрами, подчеркиванием и некоторыми другими безобидными символами (с кодом категории 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среде типа токены уже считаны и их catcodes уже установлены до того, как они будут переданы вашему макросу. При использовании \scantokenscatcodes по сути переназначаются.

Более подробную информацию об использовании \scantokens@egreg можно найти в ответе на мой вопрос по адресуМожет ли кто-нибудь подробнее объяснить расширение, каткоды и скантокены…?

Связанный контент