![TeX 中递归定义的宏](https://linux22.com/image/258668/TeX%20%E4%B8%AD%E9%80%92%E5%BD%92%E5%AE%9A%E4%B9%89%E7%9A%84%E5%AE%8F.png)
在收到对上一个问题,我兴奋不已,并试图创建一个宏\sum
,\sum<1+2+3>
将其扩展为 6。
我的想法是使用 的解析功能进行递归工作\def
。例如,以下代码输出“7+6+5”
\documentclass{article}
\def\sumtestX<#1+#2>{\ifx\empty#2{#1}\else{\sumtestX<#2>+#1 }\fi}
\def\sumtest<#1>{\sumtestX<#1+\empty>}
\begin{document}
\sumtest<5+6+7>
\end{document}
因此,人们会认为将“+”转换为真正的“和”会计算出实际的总和。然而,以下代码不是工作。
\documentclass{article}
\def\sum#1+#2{\the\numexpr#1+#2\relax}
\def\sumtestX<#1+#2>{\ifx\empty#2{#1}\else{\sum\sumtestX<#2>+#1 }\fi}
\def\sumtest<#1>{\sumtestX<#1+\empty>}
\begin{document}
\sumtest<5+6+7>
\end{document}
“缺失数字,视为零”!?怎么了?
答案1
实际上,有些花括号是错误的,有些参数周围的花括号缺失。对于分析/调试,此设置\tracingmacros=1
很有帮助。
\documentclass{article}
\def\sum#1+#2{%
\the\numexpr#1+#2\relax
}
\def\sumtestX<#1+#2>{%
\ifx\empty#2%
#1%
\else
\sum{\sumtestX<#2>}+{#1}% argument braces
\fi
}
\def\sumtest<#1>{\sumtestX<#1+\empty>}
\begin{document}
\sumtest<5+6+7>
\end{document}
当然,递归定义只是一个练习?
\sumtest
可以定义得更容易:
\def\sumtest<#1>{\the\numexpr(#1)\relax}
答案2
LuaTeX 是此类宏的理想选择。例如,在 ConTeXt 中,您可以定义:
\def\simplemath<#1>{\ctxlua{context(#1)}}
\starttext
\simplemath<1+2+3> \simplemath<2*4+5>
\stoptext
在 (Lua)LaTeX 中你可以定义:
\documentclass{minimal}
\def\simplemath<#1>{\directlua{tex.print(#1)}}
\begin{document}
\simplemath<1+2+3> \simplemath<2*4+5>
\end{document}
请注意,这适用于所有类型的数学表达式,而不仅仅是加法。