我想要创建一个\des{a}{b}
产生以下结果的函数:
\des{Q}{1} > Q_1
\des{Q_c}{1} > Q_{c,1}
我曾尝试改编代码这个答案但我不知道如何将第二个参数放在下标的逗号后面。
这是我生成的代码:
\NewDocumentCommand\des{mm}{\csname riccardo_des:nn\endcsname{#1}{_}{#2}}
\ExplSyntaxOn
\cs_new_protected:Npn \riccardo_des:nn #1 #2 #3
{
\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 { #3 } } }
\tl_use:N \l_tmpa_tl
}
\cs_new_protected:Npn \riccardo_dessb:n #1
{ \sb { #1 , des } }
\ExplSyntaxOff
我想用,des
传递给函数的第二个参数替换倒数第二行\des
。我该怎么做?
答案1
这里,我在第一个参数中搜索_
。如果没有找到,我使用#1_{#2}
。如果找到(分解#1
为#3_#4
),则使用#3_{#4,#2}
。
感谢 Mico 指出逗号被设置了\scriptscriptstyle
。已编辑并修复。
\documentclass{article}
\newcommand\des[2]{\desaux{#1}{#2}#1_\relax}
\def\desaux#1#2#3_#4\relax{%
\ifx\relax#4\relax
#1_{#2}
\else
#3_{\stripus#4,#2}
\fi
}
\def\stripus#1_{#1}
\begin{document}
$\des{Q}{1}$
$\des{Q_c}{1}$
$Q_{c,1}$ for comparison
$\des{Q_{ab}}{c}$
\end{document}
补充
根据 OP 的评论,他似乎希望\mathbf
在某些情况下(当#2
为空时)与 进行交互。以及\bar
按需与 进行交互。虽然我不确定这是否能满足所有需求,但这些事情可以直接在\des
宏中完成,而不是与第二个宏交互。
已编辑,还处理希腊字母的粗体(amsbsy
添加,使用\boldsymbol
)
例如,
\documentclass{article}
\usepackage{ifthen,amsbsy}
\newcommand\des[3][]{\desaux{#2}{#3}#2_\relax{#1}}
\def\desaux#1#2#3_#4\relax#5{%
\ifx\relax#4\relax
\ifx\relax#2\relax
\boldsymbol{\mathbf{#5#1}}
\else
#5#1_{#2}
\fi
\else
\ifx\relax#2\relax
\boldsymbol{\mathbf{#5#3_{\stripus#4}}}
\else
#5#3_{\stripus#4,#2}
\fi
\fi
}
\def\stripus#1_{#1}
\begin{document}
$\des{Q}{1}$\par
$\des{Q_c}{1}$\par
$\des{Q}{}$\par
$\des{Q_c}{}$\par
$\des[\bar]{Q}{1}$\par
$\des[\bar]{Q_c}{1}$\par
$\des[\bar]{Q}{}$\par
$\des[\bar]{Q_c}{}$
$\des{\psi}{}$\par
$\des{\psi_\alpha}{}$\par
$\des[\bar]{\psi_\alpha}{}$
\end{document}
答案2
为了多样化,下面是一个基于 LuaLaTeX 的解决方案。它设置了一个名为 的 LaTeX 宏\des
,该宏接受两个参数并调用一个名为 的 Lua 函数,而该函数又在两个 Lua 字符串函数(和)desfn
的帮助下完成大部分工作。string.find
string.sub
\documentclass{article}
\usepackage{luacode} % for "luacode" environment and "\luastring" macro
\begin{luacode}
function desfn ( u , v )
w = u:find ( "_" )
if w then -- found an underscore (_) char.
tex.sprint ( u:sub(1,w-1) .. "_{" .. u:sub(w+1) .. "," .. v .. "}" )
else
tex.sprint ( u .. "_{" .. v .. "}" )
end
end
\end{luacode}
%% LaTeX side code:
\newcommand\des[2]{\directlua{desfn(\luastring{#1},\luastring{#2})}}
\begin{document}
$\des{Q}{1}$ \quad $\des{Q_c}{1}$ \quad $\des{ABC_uvw}{123}$
\end{document}
答案3
另一个基于 LuaTeX 的解决方案,这里通过直接操作数学符号而不是使用字符串。例如,这允许嵌套调用或构造不需要第一个参数的\des
版本:\appendsub
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
local oldsub
function storesub()
local tail = tex.nest[tex.nest.ptr].tail
oldsub = tail and tail.sub
if oldsub then
tail.sub = nil
end
end
function recoversub(sep)
if oldsub then
local noad = node.new'noad'
noad.nucleus = oldsub
node.write(noad)
oldsub = nil
tex.sprint(sep)
end
end
\end{luacode}
\newcommand\appendsub[1]{\directlua{storesub()}_{\directlua{recoversub','}#1}}
\newcommand\des[2]{#1\appendsub{#2}}
\begin{document}
$\des{Q}{1}$ \quad $\des{Q_a}{1}$ \quad $\des{Q_{ab}}{123}$ \quad $\des{\des{Q}{abc}}{123}$
\end{document}
答案4
您可以利用正则表达式:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\des}{mm}
{
\simone_des:nn { #1 } { #2 }
}
\tl_new:N \l__simone_des_first_tl
\tl_new:N \l__simone_des_second_tl
\cs_new_protected:Nn \simone_des:nn
{
\regex_match:nnTF { \cD_ } { #1 }
{
\tl_set:Nn \l__simone_des_first_tl { #1 }
\tl_set:Nn \l__simone_des_second_tl { #2 }
\regex_replace_once:nnN
{ \cD_(.*)\Z } % whatever after _
{ \cD_\cB\{\1,\u{l__simone_des_second_tl}\cE\} }
\l__simone_des_first_tl
\tl_use:N \l__simone_des_first_tl
}
{#1\sb{#2}}
}
\ExplSyntaxOff
\begin{document}
$\des{Q}{1}$
$\des{Q_1}{c}$
\end{document}