软件包通常会接受一个或两个参数的宏作为某些元素的转换,至少对我来说,这些宏是一次性的,不值得永久命名 - 或者至少不值得在用户命名空间中命名。我该如何实现这一点?
\documentclass{article}
\usepackage{xcolor,empheq}
\begin{document}
\begin{empheq}[box=\colorbox{blue!20}{\hspace{1em}#1\hspace{1em}}]{align*}
a & = b \\
a^2 &= b^2
\end{empheq}
\end{document}
考虑以下尝试,它深受以下因素的影响:使用 xparse 语法通过宏定义新宏:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new:Npn \lambda_generate_new_csname: {
\tl_set:Nn \l_tmpa_tl { random } % I'll figure this out later
\prg_while:nn { ! \undefined_p \l_tmpa_tl } {
\tl_set:Nn \l_tmpa_tl { another random }
}
\tl_use:N \l_tmpa_tl
}
\cs_new:Npn \lambda_generate_new_cs: {
\use:c { \lambda_generate_new_csname: }
}
% number of arguments and then transformation
\NewDocumentCommand \LambdaFunction { m m } {
\lambda_insert_lambda:nn { #1 } { #2 }
}
\cs_new_protected:Npn \lambda_insert_lambda:nn #1 #2 {
\use:x {
% expansion unsure
\exp_not:n { \NewDocumentCommand } \lambda_generate_new_cs: {
\prg_replicate:nn { #1 } { m }
}
} {
#2
}
}
\ExplSyntaxOff
\begin{document}
\LambdaFunction{1}{hello, #1!}
{world}
% > hello, world!
\end{document}
编辑
根据评论,非常有趣的是创建一个可扩展 LambdaFunction
— 更适合函数式编程风格。我认为 TeX 毕竟在很大程度上是一种函数式语言 — 但这是否延伸到了它的核心?我认为这个问题的答案将在很大程度上说明 TeX 的编程范式。
答案1
从数字到 m 列表(内部)再到列表的转换#1#2...
似乎没有必要那么冗长,我只想这样做
\documentclass{article}
\newcommand\LambdaFunction[2][0]{%
\let\tmp\relax
\newcommand\tmp[#1]{#2}\tmp}
\begin{document}
\LambdaFunction[1]{hello, #1!}
{world}
% > hello, world!
\LambdaFunction[2]{Good #1, Mr.~#2}
{morning}{Sun}
\end{document}
答案2
作为解决方案的替代方案xparse
,这是一个\newcommand
版本。
\documentclass{scrartcl}
\makeatletter
\providecommand\use@command{}
\newcommand\usecommand[2][1]{\renewcommand\use@command[#1]{#2}\use@command}
\makeatother
\begin{document}
\usecommand{hello, #1!}
{world}
\usecommand[2]{Good #1, Mr.~#2}
{morning}{Sun}
\end{document}
这更“容易”,因为xparse
它不接受数字(虽然我更希望\NewDocumentCommand\definedcommand[3]{definition with #1, #2 and #3}
被接受:P)。
答案3
如果您不尝试在每次运行时创建随机 csname,那么任务就会简单得多。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \LambdaFunction { O{1} m } {
\lambda_insert_lambda:nn { #1 } { #2 }
}
% #1: Number of arguments
% #2: Transformation
\cs_new_protected:Npn \lambda_insert_lambda:nn #1 #2 {
\use:x {
% Put off expanding the declaration until its argument list has
% been expanded
\exp_not:n { \DeclareDocumentCommand \__lambda_expression } {
% Create the argument list
\prg_replicate:nn { #1 } { m }
}
} {
% Insert the definition
#2
}
% Leave the new function in the input stream
\__lambda_expression
}
\ExplSyntaxOff
\usepackage{empheq,xcolor}
\begin{document}
\LambdaFunction{hello, #1!}
{world}
% > hello, world!
\LambdaFunction[2]{Good #1, Mr.~#2}
{morning}{Sun}
% > Good morning, Mr.~Sun
\begin{empheq}[
box={\LambdaFunction[1]{%
\colorbox
{blue!20}%
{\hspace{1em}##1\hspace{1em}}%
}%
}
]{align*}
a &= b \\
a^2 &= b^2
\end{empheq}
\end{document}
答案4
Lambda ala JavaScript 匿名函数和 python,选择您的风格并留在 LaTeX/TeX 范式内会更好。
\documentclass{article}
\usepackage{lipsum}
\usepackage{fp}
% function (callback, args) {
% return
%}
\def\func (#1,#2){%
\ifcsname#1\endcsname%
\csname#1\endcsname{#2}%
\else%
#1,#2
\fi%
}
\begin{document}
\func (textbf, Heading)
\func (textit, \lipsum[2])
\func (hello, world)
%python
%g = lambda x: x**2
\def\g#1{\FPpow\result{#1}{2}\result}
\g{18}
\end{document}