
Я хотел бы определить макрос \des
, который имеет один аргумент и добавляет к нему нижний индекс, т.е. \des{a}
должен соответствовать a_{des}
. Пока решение очевидно, однако макрос должен также принимать аргументы, которые уже содержат нижние/верхние индексы, и объединять нижние индексы, если необходимо, с помощью запятой. На практике я хотел бы \des{a_{foo1}^{foo2}}
получить тот же результат, что и a_{foo1, des}^{foo2}
.
Я знаю оэтотответ иэтот, однако я не могу адаптировать их к своему случаю. Более того, команда \des
может также появляться, например, в подписях к рисункам, и это, похоже, создает проблемы, возможно, связанные с гиперссылкой и/или расширением аргумента.
Большое спасибо за Вашу помощь.
решение1
С expl3
- Проверяем, есть ли
_
внутри аргумента\des
; - если внутри ничего нет
_
, мы просто добавляем_{\textnormal{des}}
к аргументу\des
; и - если действительно есть хотя бы один
_
, мы заменяем его макросом (\riccardo_dessb:n
), который, в свою очередь, при раскрытии принимает один аргумент (исходный индекс) и преобразуется в_{<original subscript>,\textnormal{des}}
(по сути,_{<whatever>}
преобразуется в_{<whatever>,\textnormal{des}}
).
Вот правильный код
\documentclass{scrartcl}
\usepackage{xparse,mathtools}
\NewDocumentCommand\des{m}{\csname riccardo_des:nn\endcsname{#1}{_}}
\ExplSyntaxOn
\cs_new_protected:Npn \riccardo_des:nn #1 #2
{
\tl_set:Nn \l_tmpa_tl { #1 }
\tl_if_in:NnTF \l_tmpa_tl { #2 }
{ \tl_replace_all:Nnn \l_tmpa_tl { #2 } { \riccardo_dessb:n } }
{ \tl_put_right:Nn \l_tmpa_tl { \sb { \textnormal{des} } } }
\tl_use:N \l_tmpa_tl
}
\cs_new_protected:Npn \riccardo_dessb:n #1
{ \sb { #1 , \textnormal{des} } }
\ExplSyntaxOff
\begin{document}
$\des{a}$ and $\des{a_{b}^{c}}$
\end{document}
Добавление
Если вы предпочитаете понятный синтаксис, \des{a}_{b}^{c}
а не \des{a_{b}^{c}}
, вот решение с использованиемкакой-то кодЯ опубликовал несколько недель назад. Это может показаться громоздким, но фактическое определение гораздо короче.
\documentclass{scrartcl}
\usepackage{xparse,mathtools}
% begin addition for new arguments
\ExplSyntaxOn
\cs_new_protected:Npn \__xparse_count_type_k:w #1
{
\__xparse_single_token_check:n { #1 }
\quark_if_recursion_tail_stop_do:Nn #1 { \__xparse_bad_arg_spec:wn }
\__xparse_count_mandatory:N
}
\cs_new_protected:Npn \__xparse_count_type_K:w #1 #2
{
\__xparse_single_token_check:n { #1 }
\quark_if_recursion_tail_stop_do:nn { #2 } { \__xparse_bad_arg_spec:wn }
\__xparse_count_mandatory:N
}
\cs_new_protected:Npn \__xparse_add_type_k:w #1
{ \exp_args:NNo \__xparse_add_type_K:w #1 { \c__xparse_no_value_tl } }
\cs_new_protected:Npn \__xparse_add_type_K:w #1 #2
{
\__xparse_flush_m_args:
\__xparse_add_grabber_optional:N K
\tl_put_right:Nn \l__xparse_signature_tl { #1 { #2 } }
\__xparse_prepare_signature:N
}
\cs_new_protected:Npn \__xparse_add_expandable_type_k:w #1
{
\exp_args:NNo \__xparse_add_expandable_type_K:w #1 { \c__xparse_no_value_tl }
}
\cs_new_protected_nopar:Npn \__xparse_add_expandable_type_K:w #1 #2
{
\__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type } { K }
\__xparse_add_expandable_type_m:w % May be create this?
}
\cs_new_protected:Npn \__xparse_grab_K:w #1 #2 #3 \l__xparse_args_tl
{
\__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected_nopar:Npn
{ _ignore_spaces }
}
\cs_new_protected:Npn \__xparse_grab_K_long:w #1 #2 #3 \l__xparse_args_tl
{
\__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected:Npn
{ _ignore_spaces }
}
\cs_new_protected:Npn \__xparse_grab_K_trailing:w #1 #2 #3 \l__xparse_args_tl
{
\__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected_nopar:Npn
{ _ignore_spaces }
}
\cs_new_protected:Npn \__xparse_grab_K_long_trailing:w #1 #2 #3 \l__xparse_args_tl
{
\__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected:Npn
{ _ignore_spaces }
}
\cs_new_protected:Npn \__xparse_grab_K_aux:NnnNn #1 #2 #3 #4 #5
{
\exp_after:wN #4 \l__xparse_fn_tl ##1
{
\__xparse_add_arg:n { ##1 }
#3 \l__xparse_args_tl
}
\use:c { peek_meaning_remove #5 :NTF } #1
{ \l__xparse_fn_tl }
{
\__xparse_add_arg:n { #2 }
#3 \l__xparse_args_tl
}
}
\prop_put:Nnn \c__xparse_shorthands_prop { a } { k \sb }
\prop_put:Nnn \c__xparse_shorthands_prop { b } { k \sp }
\prop_put:Nnn \c__xparse_shorthands_prop { A } { K \sb }
\prop_put:Nnn \c__xparse_shorthands_prop { B } { K \sp }
\ExplSyntaxOff
% end
\NewDocumentCommand\des{ma}
{#1\IfValueTF{#2}{_{#2,\textnormal{des}}}{_{\textnormal{des}}}}
\begin{document}
$\des{a}$ and $\des{a}_{b}^{c}$
\end{document}
решение2
Чтобы справиться со всеми возможностями, вы можете использовать регулярные выражения. Единственное предположение, которое я делаю, это то, что после этого не должно быть пробелов _
, но это тоже можно учесть.
Названия функций должны быть понятными. Синтаксис регулярных выражений см. в texdoc l3regex
.
\documentclass{article}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\des}{m}
{
\riccardo_des:n { #1 }
}
\tl_new:N \l_riccardo_des_arg_tl
\cs_new_protected:Nn \riccardo_des:n
{
\regex_match:nnTF { \_ } { #1 }
{
\riccardo_des_sub:n { #1 }
}
{
\riccardo_des_nosub:n { #1 }
}
}
% syntactic sugar
\cs_new_protected:Nn \riccardo_des_replace:nnn
{
\tl_set:Nn \l_riccardo_des_arg_tl { #3 }
\regex_replace_once:nnN { #1 } { #2 } \l_riccardo_des_arg_tl
\tl_use:N \l_riccardo_des_arg_tl
}
\cs_new_protected:Nn \riccardo_des_nosub:n
{
\riccardo_des_replace:nnn { ([^\^]*) } { \1\cD\_\cB\{\c{destext}\cE\} } { #1 }
}
\cs_new_protected:Nn \riccardo_des_sub:n
{
\regex_match:nnTF { \_\{ } { #1 }
{
\riccardo_des_sub_braced:n { #1 }
}
{
\riccardo_des_sub_unbraced:n { #1 }
}
}
\cs_new_protected:Nn \riccardo_des_sub_unbraced:n
{
\riccardo_des_replace:nnn { \_(.) } { \cD\_\cB\{\1,\c{destext}\cE\} } { #1 }
}
\cs_new_protected:Nn \riccardo_des_sub_braced:n
{
\riccardo_des_replace:nnn { \_\{(.*?)\} } { \cD\_\cB\{\1,\c{destext}\cE\} } { #1 }
}
\ExplSyntaxOff
\newcommand{\destext}{\mathrm{des}}
\begin{document}
$\des{a}+\des{a^{}}+\des{a^2}$
$\des{a_1}+\des{a_1^2}+\des{a^2_1}$
$\des{a_{1}}+\des{a_{1}^2}+\des{a^2_{1}}$
$\des{a_{1}}+\des{a_{1}^{2}}+\des{a^{2}_{1}}$
\end{document}