![Передача строки, содержащей «специальные» коды (особенно `_`), в пользовательскую команду NewDocumentCommand](https://rvso.com/image/449643/%D0%9F%D0%B5%D1%80%D0%B5%D0%B4%D0%B0%D1%87%D0%B0%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8%2C%20%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%89%D0%B5%D0%B9%20%C2%AB%D1%81%D0%BF%D0%B5%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5%C2%BB%20%D0%BA%D0%BE%D0%B4%D1%8B%20(%D0%BE%D1%81%D0%BE%D0%B1%D0%B5%D0%BD%D0%BD%D0%BE%20%60_%60)%2C%20%D0%B2%20%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D1%83%D1%8E%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D1%83%20NewDocumentCommand.png)
Как правильно передать подчеркивание в \newcommand?предлагает решение использовать команду с нулевым аргументом, которая изменяет catcode _
, прежде чем расширяться до фактической команды.
Это как раз противоположно тому, почему я хотел бы использовать \NewDocumentCommand
, поскольку это довольно неудобно и также запутывает типы аргументов.
Есть ли способ передавать строки, содержащие подчеркивания (кстати, имена файлов), не покидая удобного \NewDocumentCommand
пузыря expl3/xparse/?
Я не хочу использовать 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 считывается между двумя идентичными символами, которые не могут быть ни одним из%
,\
,#
,{
,}
или␣
. Дословный аргумент также может быть заключен в фигурные скобки{
и}
.Команда с дословным аргументом вызовет ошибку, если она появится внутри аргумента другой функции.