Mantendo sublinhados nos parâmetros mesmo dentro de ambientes NewEnviron

Mantendo sublinhados nos parâmetros mesmo dentro de ambientes NewEnviron

eu seguiesta respostapara definir um comando tal que os sublinhados em seu parâmetro possam ser mantidos.

Entretanto, isso não funciona se o comando for chamado dentro de um ambiente que foi definido com 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}

Isso compila para

insira a descrição da imagem aqui

Digamos que não posso ficar sem environ(na verdade, estou lutando há cerca de uma hora para me livrar dele no meu documento real, sem sucesso), como posso corrigir isso?

Responder1

A solução depende do alfabeto usado para as variáveis. Se estes forem identificadores com letras maiúsculas e minúsculas, dígitos, sublinhado e alguns outros símbolos inofensivos (com código de categoria 12/outro, como caracteres de pontuação), então \detokenizepodem ser usados ​​para normalizar os códigos de categoria do identificador para token com código de categoria 12 ( o mesmo que dígitos):

\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}

Resultado

Responder2

Parece que esta também é uma situação em que \scantokenspoderia ser muito útil:

\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}

O problema com o seu original é que dentro de um \NewEnvironambiente de tipo, os tokens já foram lidos e seus códigos de gato já estão definidos antes de serem alimentados em sua macro. Ao usar \scantokens, os catcodes são essencialmente reatribuídos.

Para mais detalhes sobre o uso de \scantokens@egreg tem uma boa explicação em resposta à minha pergunta emAlguém poderia elucidar melhor a expansão, catcodes e scantokens…?

informação relacionada