动态定义命令

动态定义命令

我有一些乳胶代码,有点像这样:

% Sp defines a generic command for an arbitrary space, 
% and all of the others just delegate the bulk of their
% work to it so that when I decide to change the formatting,
% I can in one place.
\newcommand{\Sp}[2]{\textrm{#1}\left(#2\right)}
\newcommand{\Nul}[1]{\Sp{Nul}{#1}}
\newcommand{\Col}[1]{\Sp{Col}{#1}}
\newcommand{\Row}[1]{\Sp{Row}{#1}}

% Some common vectors, so I don't have to repeatedly type
% \vec{x}_1:
\newcommand{\u}{\vec{u}}
\newcommand{\v}{\vec{v}}
\newcommand{\w}{\vec{w}}
\newcommand{\x}{\vec{x}}
\newcommand{\y}{\vec{y}}

我所做的工作是线性代数,我需要使用这些向量很多。因此,定义较短的命令似乎很自然。但是当论文开始变长时,我最终要么将字母表的一半定义为不同的命令——每个字母一个命令。

所以我尝试定义一个命令,该命令仅定义另一个命令,以便我可以将它放入循环中......

\newcommand{\MkVec}[1]{\expandafter\def\#1{\vec{#1}}}

以及由此产生的几种变化...但是我最接近工作模型的是当编译器给我的错误变为 时missing \begin{document}

有人能解释一下或提供资料来进一步了解我应该做什么(或者是否有更好的方法)来定义动态命令吗?请注意,这个特定实例只是一个例子。我对做 LaTeX 元编程感兴趣,而不是专门渲染矢量。

答案1

使用\#简单的定义\#。您需要一个东西,给定一个名称,它将成为具有该名称的命令。这样的东西作为 TeX 原始命令存在:\csname ... \endcsname

\documentclass{article}
\newcommand{\MkVec}[1]{\expandafter\def\csname#1\endcsname{\vec{#1}}}
\MkVec{x}\MkVec{y}
\begin{document}
  Some vectors: $\x$, $\y$.
\end{document}

如果必须定义那么多向量,您可以考虑用粗体字母而不是 来表示它们\vec。这样公式看起来就不会那么混乱。

答案2

为了补充 Dan 的回答,您可以执行以下操作\MkVec{..}避免重复

\newcommand{\MkVec}[1]{\expandafter\def\csname#1\endcsname{\vec{#1}}}
  \def\lst{x,y,z,u,v,w,a,b,c}
  \@for\i:=\lst\do{%
    \expandafter\MkVec \i     }

现在,通过此实现,您可以通过一个操作维护/修改相关宏的列表。如果您决定\x应该表示其他含义,只需将其删除即可\lst。(对我来说,\x\times。)而添加新条目只需输入单个 leeters。在另一个场景中,假设您稍后决定宏应该真正称为\xvec\yvec等。请这样做

\def\str{vec}

然后,在 的定义中,立即在 后\MkVec添加。\str#1

\newcommand{\MkVec}[1]{\expandafter\def\csname#1\str\endcsname{\vec{#1}}}

for 循环保持不变。


字符串#1也可以添加在前面。因此,通过扩展,您可以生成微列表来替换定义页面,例如

\def\dx{\partial x}
\def\dy{\partial y}
\def\dz{\partial z}
\num\def\limx0{lim_(x->0)}
\num\def\limy0{lim_(y->0)}
\num\def\limz0{lim_(z->0)}

每个条目都必须单独维护。

但是,我用这种方法对希腊字母没有任何效果。

哦,你可能有兴趣这个包它使您可以在宏的字符串名称后添加数字。该包包含有关如何使用它的良好介绍,并为我们提供了使用 lateX 进行元编程的见解。


编辑:\ddix 和 \dix 等命令在 \MkVec 结构下确实会互相干扰。您需要在每个 \MkVec 类函数实例之后立即执行 for 循环。例如

\newcommand{\MKa}...
\newcommand{\Mkb}...
 \@for...  
        \expandafter \MKa \i
        \expandafter \MKb \i    }  

可能不起作用。但下面的方法可以。

\newcommand{\MKa}...
  \@for...  
        \expandafter \MKa \i    }
\newcommand{\Mkb}...
  \@for...
        \expandafter \MKb \i    }  

最后一件事。我觉得我需要为可能看到这个讨论的其他人添加这一点。要使用@ 在文件中,需要\makeatletter在使用前和\makeatother使用完毕后包含。在包中,例如 .sty 文件,声明是可选的,应避免使用。

相关内容