为了跟踪论文中的定义,我为一些宏编写了两个版本。一个只是宏,就像\mymacro
,另一个是宏的展开版本,我通常称之为\mymacro@unfold
。然后我编写了一个命令\unfold
,如果我写\unfold{\mymacro}
,输出就是\mymacro@unfold
。这至少是我打算让它工作的方式(在大多数情况下它确实如此),但在这个例子中它没有,我不知道为什么。
MWE 如下。它首先定义\unfold
宏,然后定义两个宏\cftalg
及其\extalg
展开版本。虽然 的输出\unfold{\cftalg{A}}
是\cftalg@unfold{A}
应该的, 的输出\unfold{\extalg{A}}
也是\cftalg@unfold{A}
。
\documentclass{article}
\makeatletter
%%%% To replace a token by another, use the following:
\newcommand{\@replace}[2]{#1}
%%%% Unfold replaces macros with their unfolded versions:
\newcommand{\unfold}[1]{%
\@ifnextchar\cftalg{\@replace{\cftalg@unfold}}{%
\@ifnextchar\extalg{\@replace{\extalg@unfold}}{%
}}
#1}
\newcommand{\algfont}{\mathbf}
\newcommand{\cftalg}{\algfont}
\newcommand{\cftalg@unfold}[1]{%
( \cftalgc{\cftalg{#1}},
\cftalgf{\cftalg{#1}},
\cftctxext{\cftalg{#1}},
\cftempc{\cftalg{#1}})
}
\newcommand{\extalg}{\algfont}
\newcommand{\extalg@unfold}[1]{%
(\cftalgc{\algfont{#1}},
\cftalgf{\algfont{#1}},
\cftctxext{\algfont{#1}})
}
%%%% The intended use of `\cftctx` is `\cftctx{\cftalg{#1}}`.
\newcommand{\cftalgc}[1]{%
{ \renewcommand{\cftalg}[1]{##1}
#1
}
}
%%%% The intended use of `\cftfam` is `\cftfam{\cftalg{#1}}`.
\newcommand{\cftalgf}[1]{\mathcal{F}_{#1}}
\newcommand{\cftctxext}[1]{\epsilon^{#1}}
\newcommand{\cftempc}[1]{\phi^{#1}}
\makeatother
\begin{document}
We analyze some kind of algebras $\cftalg{A}$.
\begin{itemize}
\item Algebras of this kind are quadruples: $\unfold{\cftalg{A}}$
\item Underlying it is a simpler kind of algebras which is only a triple, but LaTeX thinks differently about this:
$\unfold{\extalg{A}}$
\end{itemize}
\end{document}
答案1
中的比较\@ifnextchar
基于\ifx
。由于\cftalg
和具有相同的定义,因此即使宏为 ,也会使用 的\extalg
分支。\cftalg
\extalg
\cftalg
一个简单的解决方法是使和的定义\extalg
不同,例如:
\newcommand{\extalg}{\@empty\algfont}
或者
\newcommand*{\extalg}{\algfont}
完整示例:
\documentclass{article}
\makeatletter
%%%% To replace a token by another, use the following:
\newcommand{\@replace}[2]{#1}
%%%% Unfold replaces macros with their unfolded versions:
\newcommand{\unfold}[1]{%
\@ifnextchar\cftalg{\@replace{\cftalg@unfold}}{%
\@ifnextchar\extalg{\@replace{\extalg@unfold}}{%
}}
#1}
\newcommand{\algfont}{\mathbf}
\newcommand{\cftalg}{\algfont}
\newcommand{\cftalg@unfold}[1]{%
( \cftalgc{\cftalg{#1}},
\cftalgf{\cftalg{#1}},
\cftctxext{\cftalg{#1}},
\cftempc{\cftalg{#1}})
}
\newcommand{\extalg}{\@empty\algfont}
\newcommand{\extalg@unfold}[1]{%
(\cftalgc{\algfont{#1}},
\cftalgf{\algfont{#1}},
\cftctxext{\algfont{#1}})
}
%%%% The intended use of `\cftctx` is `\cftctx{\cftalg{#1}}`.
\newcommand{\cftalgc}[1]{%
{ \renewcommand{\cftalg}[1]{##1}
#1
}
}
%%%% The intended use of `\cftfam` is `\cftfam{\cftalg{#1}}`.
\newcommand{\cftalgf}[1]{\mathcal{F}_{#1}}
\newcommand{\cftctxext}[1]{\epsilon^{#1}}
\newcommand{\cftempc}[1]{\phi^{#1}}
\makeatother
\begin{document}
We analyze some kind of algebras $\cftalg{A}$.
\begin{itemize}
\item Algebras of this kind are quadruples: $\unfold{\cftalg{A}}$
\item Underlying it is a simpler kind of algebras which is only a triple:
$\unfold{\extalg{A}}$
\end{itemize}
\end{document}
根据宏名进行比较
根据宏名实现比较的方法有很多种。下面的实现将第一个标记放入#1
宏中\unfold@param
,并将其与\unfold@cftalg
和进行比较\unfold@extalg
,这两个宏分别包含\cftalg
或\extalg
。
\documentclass{article}
\makeatletter
%%%% To replace a token by another, use the following:
\newcommand{\@replace}[2]{#1}
%%%% Unfold replaces macros with their unfolded versions:
\newcommand{\unfold}[1]{%
\unfold@#1%
}
\newcommand*{\unfold@}[1]{%
\def\unfold@param{#1}%
\ifx\unfold@param\unfold@cftalg
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
\cftalg@unfold
{%
\ifx\unfold@param\unfold@extalg
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
\extalg@unfold
{#1}%
}%
}
\newcommand*{\unfold@cftalg}{\cftalg}
\newcommand*{\unfold@extalg}{\extalg}
\newcommand{\algfont}{\mathbf}
\newcommand{\cftalg}{\algfont}
\newcommand{\cftalg@unfold}[1]{%
( \cftalgc{\cftalg{#1}},
\cftalgf{\cftalg{#1}},
\cftctxext{\cftalg{#1}},
\cftempc{\cftalg{#1}})
}
\newcommand{\extalg}{\algfont}
\newcommand{\extalg@unfold}[1]{%
(\cftalgc{\algfont{#1}},
\cftalgf{\algfont{#1}},
\cftctxext{\algfont{#1}})
}
%%%% The intended use of `\cftctx` is `\cftctx{\cftalg{#1}}`.
\newcommand{\cftalgc}[1]{%
{ \renewcommand{\cftalg}[1]{##1}
#1
}
}
%%%% The intended use of `\cftfam` is `\cftfam{\cftalg{#1}}`.
\newcommand{\cftalgf}[1]{\mathcal{F}_{#1}}
\newcommand{\cftctxext}[1]{\epsilon^{#1}}
\newcommand{\cftempc}[1]{\phi^{#1}}
\makeatother
\begin{document}
We analyze some kind of algebras $\cftalg{A}$.
\begin{itemize}
\item Algebras of this kind are quadruples: $\unfold{\cftalg{A}}$
\item Underlying it is a simpler kind of algebras which is only a triple:
$\unfold{\extalg{A}}$
\end{itemize}
\end{document}
如果有两个以上的宏\cftalg
,则扩展性更好的变体\extalg
。实现假定\<macro>@unfold
每个都存在\<macro>
。此类宏声明为
\unfold@def\<macro>
完整示例:
\documentclass{article}
\makeatletter
%%%% To replace a token by another, use the following:
\newcommand{\@replace}[2]{#1}
%%%% Unfold replaces macros with their unfolded versions:
\newcommand{\unfold}[1]{%
\unfold@#1%
}
\newcommand*{\unfold@}[1]{%
\@ifundefined{unfold@@\detokenize{#1}}{#1}{%
\csname unfold@@\detokenize{#1}\endcsname
}%
}
\newcommand*{\unfold@def}[1]{%
\expandafter\def\csname unfold@@\detokenize{#1}\expandafter\endcsname
\expandafter{%
\csname\expandafter\@gobble\string#1@unfold\endcsname
}%
}
\unfold@def\cftalg
\unfold@def\extalg
\newcommand{\algfont}{\mathbf}
\newcommand{\cftalg}{\algfont}
\newcommand{\cftalg@unfold}[1]{%
( \cftalgc{\cftalg{#1}},
\cftalgf{\cftalg{#1}},
\cftctxext{\cftalg{#1}},
\cftempc{\cftalg{#1}})
}
\newcommand{\extalg}{\algfont}
\newcommand{\extalg@unfold}[1]{%
(\cftalgc{\algfont{#1}},
\cftalgf{\algfont{#1}},
\cftctxext{\algfont{#1}})
}
%%%% The intended use of `\cftctx` is `\cftctx{\cftalg{#1}}`.
\newcommand{\cftalgc}[1]{%
{ \renewcommand{\cftalg}[1]{##1}
#1
}
}
%%%% The intended use of `\cftfam` is `\cftfam{\cftalg{#1}}`.
\newcommand{\cftalgf}[1]{\mathcal{F}_{#1}}
\newcommand{\cftctxext}[1]{\epsilon^{#1}}
\newcommand{\cftempc}[1]{\phi^{#1}}
\makeatother
\begin{document}
We analyze some kind of algebras $\cftalg{A}$.
\begin{itemize}
\item Algebras of this kind are quadruples: $\unfold{\cftalg{A}}$
\item Underlying it is a simpler kind of algebras which is only a triple:
$\unfold{\extalg{A}}$
\end{itemize}
\end{document}
答案2
以下是解决给定问题的一种更简单的方法:
\documentclass{article}
\def\folddef#1#2{\expandafter\def \csname unfold@#1\string#2\endcsname}
\def\unfold#1#2{\csname unfold@#1\string#2\endcsname}
\folddef3\cftalg#1{(\mathbf{#1},\mathcal{F}_\mathbf{#1},\epsilon^\mathbf{#1})}
\folddef4\cftalg#1{(#1,\mathcal{F}_\mathbf{#1},\epsilon^\mathbf{#1},\phi^\mathbf{#1})}
\def\cftalg#1{\mathbf{#1}}
\begin{document}
We analyze some kind of algebras $\cftalg{A}$.
\begin{itemize}
\item Algebras of this kind are quadruples: $\unfold4\cftalg{A}$
\item Underlying it is a simpler kind of algebras which is only a triple:
$\unfold3\cftalg{A}$
\end{itemize}
\end{document}