![即使在 NewEnviron 环境中,参数中也要保留下划线](https://linux22.com/image/310008/%E5%8D%B3%E4%BD%BF%E5%9C%A8%20NewEnviron%20%E7%8E%AF%E5%A2%83%E4%B8%AD%EF%BC%8C%E5%8F%82%E6%95%B0%E4%B8%AD%E4%B9%9F%E8%A6%81%E4%BF%9D%E7%95%99%E4%B8%8B%E5%88%92%E7%BA%BF.png)
我跟着这个答案定义一个命令,使得其参数中的下划线可以保留。
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
解决方案取决于变量使用的字母表。如果这些标识符包含大写和小写字母、数字、下划线和其他一些无害符号(类别代码为 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的更多详细信息,在回答我的提问时有一个很好的解释有人可以进一步阐明扩展、catcodes 和 scantokens……吗?