如何停止宏处理参数?

如何停止宏处理参数?

Disclaimer:我不知道如何正确地措辞,所以标题可能会产生误导——非常欢迎编辑和评论建议或更正!

我使用该minted包将代码添加到我的文档中,并且由于minted提供了该功能,mintinline我倾向于经常使用该功能。我用来内联创建 Python 代码的命令之一是:

\NewDocumentCommand \imp { o m } {
    \IfNoValueTF{#1} {
        \mintinline{python}{#2}
    } {
        \mintinline[#1]{python}{#2}
    }
}

不幸的是,\imp似乎在将 #2 中的所有内容传递给 之前对其进行了处理\mintinline,这会产生如下不必要的结果:

\imp{'ONE   TWO'} => 'ONE TWO'
\mintinline{python}{'ONE   TWO'} => 'ONE   TWO'

当涉及反斜杠时甚至会出现错误:

\imp{\} => error
\mintinline{python}{\} => \

那么,当我使用这些定制的宏时,有没有办法抑制输入的处理?

我的 MWE 是:

\documentclass[10pt,openany]{book}
\usepackage{xparse,minted}

\NewDocumentCommand \imp { o m } {
    \IfNoValueTF{#1} {
        \mintinline{python}{#2}
    } {
        \mintinline[#1]{python}{#2}
    }
}

\begin{document}

\imp{'ONE   TWO'} % 'ONE TWO'
\mintinline{python}{'ONE   TWO'} % 'ONE   TWO'

\imp{\} % error
\mintinline{python}{\} % \

\end{document}

答案1

除非我误解了评论,否则你想要的是:

\documentclass{article}
\usepackage{minted}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand \imp { o }
  {
    \IfValueTF {#1}
      { \mintinline[#1]{python} }
      { \mintinline{python} }
  }

\ExplSyntaxOff

\begin{document}

\imp{'ONE   TWO'}
\mintinline{python}{'ONE   TWO'} % 'ONE   TWO'

\imp{\} % no error
\mintinline{python}{\} % \

\end{document}

截屏

我添加了\ExplSyntaxOn\ExplSyntaxOff,否则你的格式会添加不需要的空格。

请注意,以下定义同样适用;然而,我认为它有点难以理解,而且收获甚微:

\NewDocumentCommand \imp { o }
  {
    \IfValueTF {#1}
      { \mintinline[#1] }
      { \mintinline }
    {python}
  }

您的宏不起作用的原因是抓取逐字文本的命令(此处为\mintinline)使用特殊的类别代码设置来抓取它(例如,空格不像 TeX 通常那样处理)。但是当您的宏被调用并抓取它的 时#2,TeX 会根据当前类别代码设置,这不是设置\mintinline会做的事情;一旦分配,类别代码就会牢牢地附着在它们的角色标记上,除非你使用非常特殊命令,例如\detokenize

请注意,这里甚至\detokenize无法提供帮助:如果您a b在 TeX 的正常类别代码设置下阅读(例如,如果它被抓取作为宏参数),结果是一个包含三个字符标记的标记列表:

  • a类别代码为11(字母);
  • 一个空格标记(字符代码 32,类别代码 10);
  • b类别代码为 11。

输入中的四个空格已经合并为空格标记。从结果标记列表中,无法恢复原始空格数。不丢失此类信息的唯一方法是设置不同的类别代码输入文件中的字符被转换成标记(这就是\mintinline\verb类似命令的作用)。

当在正常类别代码机制下,输入中的字符作为宏参数1的一部分被抓取时,进行类似处理已经太晚了verbatim:输入中的字符已被标记化,即它们被转换成一个标记列表,每个标记要么是控制序列标记(例如\foobar),要么是字符标记(由字符代码和类别代码组成的对)。因此,这里的解决方案是不是抓住我们想要以verbatim类似方式处理的输入字符,并让它\mintinline自己用适合该任务的类别代码设置来完成。


脚注

  1. 这包括环境参数,因为环境是用宏实现的。

相关内容