将包含“特殊” catcodes(尤其是“_”)的字符串传递给自定义 NewDocumentCommand 命令

将包含“特殊” catcodes(尤其是“_”)的字符串传递给自定义 NewDocumentCommand 命令

我如何才能正确地将下划线传递给 \newcommand?建议解决方案是使用零参数命令来改变 的 catcode _,然后再扩展为实际命令。

这与我想要使用的原因正好相反 \NewDocumentCommand,因为它有点尴尬,而且还会混淆参数类型。

有没有办法传递包含下划线的字符串(顺便说一下,是文件名),而不必离开我的 expl3/xparse/ \NewDocumentCommandbubble 的舒适区?

我不想使用v参数;它实际上应该像普通宏一样运行,\includechapter{foo_bar}而不是像\includechapter!foo_bar!


我当前的代码:

%%% Chapter Inclusion Macros
\RequirePackage{expl3}
\ExplSyntaxOn
% Command to include chapter files, if
% either the exclusive chapter list is empty,
% or said chapter is in there
\cs_set:Npn \cel_includechapter:n #1 {
  % Check whether list is empty
  \clist_if_empty:NTF
  \g_cel_enabled_clist % which list
  {\include{#1/#1}} % if empty, just include
  { % else
    % check whether argument in list of enabled chapters
    \clist_if_in:NnTF 
    \g_cel_enabled_clist % in which list
    {#1} % which element to look for
    {\include{#1/#1}} % if in there
    {\chapter{#1~(currently~disabled)}} %if not in there
  }
}
% user-facing command \includechapter
% includes chaptername/chaptername
% if enabled
\NewDocumentCommand{\includechapter}{m}{
  \cel_includechapter:n{#1}
}
\NewDocumentCommand{\enableChapter}{m}{
  \clist_put_right:Nn \g_cel_enabled_clist {#1}
}
\ExplSyntaxOff

到达时构建中断

\includechapter{foo_bar}

! Missing $ inserted.
<inserted text>
                $
l.147 \includechapter{foo_bar}

答案1

问题是你说

{\chapter{#1~(currently~disabled)}} %if not in there

因为文件名中的下划线会触发数学模式。

解决方案:改为

{\chapter{\tl_to_str:n {#1}~(currently~disabled)}} %if not in there

答案2

在这种情况下,解决方案是使用v-type 参数:

\NewDocumentCommand{\includechapter}{v}{
  \cel_includechapter:n{#1}
}
\NewDocumentCommand{\enableChapter}{v}{
  \clist_put_right:Nn \g_cel_enabled_clist {#1}
}

这仍然需要更多的修复,因为如果传递的参数包含下划线,则需要先进行处理才能排版。

幸运的是,我不想将这个宏用作另一个函数的参数(usrguide3.pdf):

v:以类似于 LATEX 2ε 命令 的参数的方式,在下一个字符和下一个出现字符之间逐字逐句地读取参数\verb。因此,v-type 参数在两个相同字符之间读取,这两个字符不能是%\#{或中的任何一个。逐字参数也可以括在括号中 ,} 并且{}之间。当带有逐字参数的命令出现在另一个函数的参数中时,它将产生错误。

相关内容