我正在尝试创建一个宏,该宏会创建两个宏。第一个宏设置默认值,第二个宏创建一个宏来重新定义第一个宏。我试图概括我经常使用的常见模式。
\newcommand{\mkMac}[1]{%
\newcommand{\the#1}{The macro ##1}
\newcommand{\#1}[1]{\renewcommand{\the#1}{##1}}
}
用法:
\mkMac{affilation}
\affilation{University}
Welcome to \theaffilation
答案1
使用\newcommand
和,\renewcommand
您必须使用\csname...\endcsname
,以及一些在或生效\expandafter
之前构建控制序列:\newcommand
\renewcommand
\newcommand{\mkMac}[1]{%
\expandafter\newcommand\csname the#1\endcsname{%
Call the macro \texttt{\expandafter\string\csname #1\endcsname}!%
}%
\expandafter\newcommand\csname #1\endcsname[1]{%
\expandafter\renewcommand\csname the#1\endcsname{##1}%
}%
}
\mkMac{affiliation}
\show\theaffiliation
\show\affiliation
\affiliation{University}
\show\theaffiliation
\stop
这是运行示例时终端上的输出(\stop
只是结束运行):
This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013)
restricted \write18 enabled.
entering extended mode
(./mkmak.tex
LaTeX2e <2011/06/27>
Babel <3.9f> and hyphenation patterns for 78 languages loaded.
> \theaffiliation=\long macro:
->Call the macro \texttt {\expandafter \string \csname affiliation\endcsname }!.
l.11 \show\theaffiliation
?
> \affiliation=\long macro:
#1->\expandafter \renewcommand \csname theaffiliation\endcsname {#1}.
l.12 \show\affiliation
?
> \theaffiliation=\long macro:
->University.
l.14 \show\theaffiliation
?
)
No pages of output.
Transcript written on mkmak.log.
因此为和宏\mkMak{affiliation}
定义一个临时值;调用重新定义为。\theaffiliation
\affiliation
\affiliation{University}
\theaffiliation
University
答案2
您可以使用etoolbox
'\csdef
但在这种情况下,LaTeX 不会测试宏是否已经定义。
\usepackage{etoolbox}
\newcommand{\mkMac}[1]{%
\csdef{the#1}{The macro ##1}
\csdef{#1}##1{\csdef{the#1}{##1}}
}
请注意,\csdef
宏名两端的括号是必需的,并且必须省略前导反斜杠。
答案3
如果你不想考虑扩展,而想使用的功能\newcommand
,你可以使用宏\csnewcommand
并\recsnewcommand
定义为
\makeatletter
\newcommand*\csnewcommand{\@star@or@long\csnew@command}
\newcommand*\csnew@command[1]{\expandafter\new@command\csname#1\endcsname}
\newcommand*\recsnewcommand{\@star@or@long\recsnew@command}
\newcommand*\recsnew@command[1]{\expandafter\renew@command\csname#1\endcsname}
\makeatletter
这样,您就可以使用带星号和不带星号的版本\expandafter
。
代码
\documentclass{article}
\makeatletter
\newcommand*\csnewcommand{\@star@or@long\csnew@command}
\newcommand*\csnew@command[1]{\expandafter\new@command\csname#1\endcsname}
\newcommand*\recsnewcommand{\@star@or@long\recsnew@command}
\newcommand*\recsnew@command[1]{\expandafter\renew@command\csname#1\endcsname}
\makeatletter
\newcommand*{\mkMac}[1]{%
\csnewcommand*{the#1}{The macro #1}%
\csnewcommand*{#1}[1]{\recsnewcommand*{the#1}{##1}}}
\begin{document}
\mkMac{affilation}
Welcome to ``\theaffilation''.
\affilation{University}
Welcome to ``\theaffilation''.
\end{document}
输出
欢迎来到“宏联盟”。
欢迎来到“大学”。
答案4
LaTeX 定义了类似于以下提供的简短接口etoolbox
形式为\@namedef
(来自latex.ltx
):
\def\@namedef#1{\expandafter\def\csname #1\endcsname}
这是一个展示用法的简单示例:
\documentclass{article}
\makeatletter
\newcommand*{\mkMac}[1]{%
\@namedef{the#1}{The macro #1}%
\@namedef{#1}##1{\@namedef{the#1}{##1}}}
\makeatother
\begin{document}
\mkMac{affilation}
Welcome to ``\theaffilation''.
\affilation{University}
Welcome to ``\theaffilation''.
\end{document}