15

I have some latex code that goes a bit like this:

% 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}}

The work I'm doing is in linear algebra, where I need to use these vectors a lot. So, defining shorter commands seems pretty natural. But when papers start getting longer, I end up with either half the alphabet being defined as different commands -- one for each letter.

So I tried to define a command that just defines another command so that I could just put it in a loop...

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

and several variations thereupon... But the closest I came to a working model was when the error that the compiler gave me changed to missing \begin{document}.

Can someone explain or give a source to learn more about what I should be doing (or if there's a better way after all) to define dynamic commands? Note that this specific instance is just one example. I'm interested in doing LaTeX metaprogramming, not rendering vectors nicely specifically.

2 Answers 2

15

Using \# simply defines \#. You need something that, given a name, becomes the command with that name. Such a thing exists as a TeX primitive command: \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}

If you have to define that many vectors, you might consider representing them by bold letters rather than \vec. Formulas look less cluttered that way.

1
  • Perfect! Thanks. Yes, I agree, I have \renewcommand{\vec}[1]{\textbf{#1}} defined above this section for just that reason -- Not sure if that's the best way but it seemed logical at the time. Much obliged. Lot to learn about latex. Nov 17, 2013 at 8:08
8

To add to Dan's answer, you may do the following to avoid the repeating \MkVec{..}'s.

\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     }

Now, with this implementation, you can maintain/modify your list of related macros in a single action. Should you decide \x should mean something else, simply take it off \lst. (For me, \x is \times.) whereas adding new entries only requires the typing of single leeters. In a different scenario, say you decide later that the macro should really be called \xvec, \yvec, etc. instead. Do this

\def\str{vec}

Then, in the definition of \MkVec, add \str immediately after #1.

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

The for loop remains the same.


The string can be added before #1 as well. So by extension, you can generate lists of micro that replace pages of definitions like

\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)}

where each entry has to be maintained individually.

However, I haven't had any luck with Greek letters with this approach.

Oh, you might be interested in getting this package which enables you to add numbers after the string name of a macro. The package includes a good introduction as to how to use it and it offers us insights of meta-programming with lateX.


EDIT: Commands such as \ddix and \dix do interfere with each other under the \MkVec structure. You would need to do the for loop immediately after each instance of \MkVec like functions. For example

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

may NOT work. But the following will.

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

One last thing. I think I need to include this for others who may come across this discussion. To use @ in document, one would need to include \makeatletter before using it and \makeatother when finished. In packages, for example, .sty files, the declaration is optional and should be avoided.

1
  • Thanks, Joseph! I couldn't figure out how to put blocks of codes together. And now I know!
    – Argyll
    Jan 10, 2014 at 9:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .