在 LaTeX 中,有没有可能定义一个命令模板?
如下代码中,我定义了一个关于“名言”的 counter 及其配套命令。
当有多个类似的 counter 需要处理时,如果能够定个一个模板,然后通过模板来创建多个 counter ,则更符合思维习惯,代码也能简洁不少。
我尝试了一下,如下的 createlabel
, 但编译不通过。
\documentclass{ctexart}
\usepackage{hyperref}
\hypersetup{colorlinks=true, linkcolor=red}
\newcommand{\createlabel}[2][]{
\newcounter{#1}
\renewcommand\the#1{#2 \arabic{#1}}
\newcommand*{\#1}[1][]{\refstepcounter{#1}{\the#1 ##1} }
}
\begin{document}
\newcounter{mingyan} % 定义“名言”的计数器
\renewcommand\themingyan{名言\arabic{mingyan}}
\newcommand*\mingyan[1][]{\refstepcounter{mingyan}{\themingyan #1} }
% \createlabel{minyan}{名言} % 仅定义前缀
% \createlabel{minyan}{名言\arabic{mingyan}} % 直接定义输出格式,这样最好
\mingyan{敏而好学,不耻下问。——孔子}\label{mingyan:kongzi} % 记录一个名言,为其增加标签
\ref{mingyan:kongzi} % 引用标签
\end{document}
不知道你想干什么,但是你的 \newcommand\createlabel
代码有几处错误,将其修改如下:
\newcommand{\createlabel}[2]{
\newcounter{#1}
\expandafter\renewcommand\csname the#1\endcsname{#2} % 应该使用 \csname ...\endcsname
\expandafter\newcommand\expandafter*\csname #1\endcsname[1]{ % 同上
\refstepcounter{#1}\csname the#1\endcsname ##1} % 同上
} % 如果不想写这么多 \expandafter,可用 LaTeX3 的 \exp_args:Nc, \exp_args:NNc
看起来 \createlabel
是要接收两个必须参数,应该使用 \newcommand{}[]{}
的形式,而不是 \newcommand{}[][]{}
的形式。
这样就能正常编译了:
\documentclass{ctexart}
\usepackage{hyperref}
\hypersetup{colorlinks=true, linkcolor=red}
%% 错误的代码
%\newcommand{\createlabel}[2][]{
% \newcounter{#1}
% \renewcommand\the#1{#2 \arabic{#1}}
% \newcommand*{\#1}[1][]{\refstepcounter{#1}{\the#1 ##1} }
%}
\newcommand{\createlabel}[2]{
\newcounter{#1}
\expandafter\renewcommand\csname the#1\endcsname{#2}
\expandafter\newcommand\expandafter*\csname #1\endcsname[1]{
\refstepcounter{#1}\csname the#1\endcsname ##1}
}
\begin{document}
%\newcounter{mingyan} % 定义“名言”的计数器
%\renewcommand\themingyan{名言\arabic{mingyan}}
%\newcommand*\mingyan[1][]{\refstepcounter{mingyan}{\themingyan #1} }
%% 使用第二个命令
% \createlabel{minyan}{名言} % 仅定义前缀
\createlabel{mingyan}{名言\arabic{mingyan}} % 直接定义输出格式,这样最好
\mingyan{敏而好学,不耻下问。——孔子}\label{mingyan:kongzi} % 记录一个名言,为其增加标签
\ref{mingyan:kongzi} % 引用标签
\end{document}