2

I want to make it easier on myself to write large commands like this by "naming" the arguments.

I did this:

% Define the command for vector projection with named arguments \NewDocumentCommand{\VectorProjection}{O{\mathbf{u}} O{\mathbf{v}}} { { % Local command definitions \newcommand{\vecu}{#1} \newcommand{\vecv}{#2} \begin{align} \text{proj}_{\vecv} \vecu &= \frac{\vecu \cdot \vecv}{\|\vecv\|^2} \vecv \\ &= \left( \frac{\vecu \cdot \vecv}{\|\vecv\|^2} \right) \vecv \\ &= \frac{\vecu \cdot \vecv}{\vecv \cdot \vecv} \vecv \end{align} } } 

I'm assuming here, that the extra pair of { and } should create a "scope". Think I read that somewhere. Is that correct?

The following is fine:

\VectorProjection \VectorProjection[a][b] 

This one two:

\VectorProjection \VectorProjection[a][b] \newcommand{\vecu}{U} 

But this one here complains about redefining \vecu and \vecv, i.e. Command \vecu already defined. is the error message:

\newcommand{\vecu}{U} \VectorProjection \VectorProjection[a][b] 

This one also complains:

\VectorProjection \VectorProjection[a][b] \newcommand{\vecu}{U} \VectorProjection[a][b] 

Simply replacing the \newcommand with \renewcommand` doesn't solve it either because then

\VectorProjection 

fails with Command \vecu undefined.

My workaround, but not really related to the question

For now I'm using CTAN: Package namedef to do something like this:

\named\def\implVectorProjection#[vecu]#[vecv]% { % Vector Projection of vecu onto vecv \begin{align} \text{proj}_{#[vecv]} #[vecu] &= \frac{#[vecu] \cdot #[vecv]}{\|#[vecv]\|^2} #[vecv] \\ &= \left( \frac{#[vecu] \cdot #[vecv]}{\|#[vecv]\|^2} \right) #[vecv] \\ &= \frac{#[vecu] \cdot #[vecv]}{#[vecv] \cdot #[vecv]} #[vecv] \end{align} } \NewDocumentCommand{\XVectorProjection}{O{\mathbf{u}} O{\mathbf{v}}} { \implVectorProjection{#1}{#2} } \XVectorProjection \XVectorProjection[a][b] 

If anyone knows what solution people normally use to name macro arguments please let me know. Seems like such an essential feature.

4
  • 3
    You could use \def (which doesn't check) but the answer to your final question is that most people do not try to name aguments but use #1, #2` directly Note also that you should comment out the ends of lines you are adding a lot white space, which will not produce output as this is math mode, but is bad style (and wastes token memory) Commented May 30, 2024 at 15:17
  • 1
    Or use \renewcomand but also at the top level have \newcommand{\vecu}{unexpected vecu} so that the local redefinition works and any top level use produces warning text Commented May 30, 2024 at 15:22
  • Using \def\vecu{#1} instead of \newcommand{\vecu}{#1} indeed seems to do the trick. Even when I run this afterwards \def\vecu{X} \vecu \VectorProjection \vecu it will output "X" both times which is exactly what I would expect how scopes work. If I remove the additional { and } I get \mathbf allowed only in math mode. which is also as I'd expect. To me it looks like \newcommand though doesn't work well with scopes then? Commented May 30, 2024 at 15:42
  • 2
    \newcommand works as designed in groups but gives errors if the command is already defined, as you say. Perhaps you were expecting that the start of a group clears all definitions, that certainly does not happen (otherwise you would not be able to use \begin{align} however I would not recommend you have these groups, it is quite hard to ensure they do not affect the formatting. Commented May 30, 2024 at 15:47

1 Answer 1

1

It's rather unclear why using \vecu and \vecv in the body of the definition, when you can just use #1 and #2.

You possibly want

\NewDocumentCommand{\VectorProjection}{O{\mathbf{u}} O{\mathbf{v}}}{% \begin{align} \operatorname{proj}_{#2} #1 &= \frac{#1 \cdot #2}{\|#2\|^2} #2 \\ &= \left( \frac{#1 \cdot #2}{\|#2\|^2} \right) #2 \\ &= \frac{#1 \cdot #2}{#2 \cdot #2} #2 \end{align} } 

However, if you want that your vectors are always in \mathbf, calling

\VectorProjection[a][b] 

wouldn't ensure it.

Likely you want

\NewDocumentCommand{\VectorProjection}{O{u} O{v}}{% \begin{align} \operatorname{proj}_{\mathbf{#2}} \mathbf{#1} &= \frac{\mathbf{#1} \cdot \mathbf{#2}}{\|\mathbf{#2}\|^2} \mathbf{#2} \\ &= \left( \frac{\mathbf{#1} \cdot \mathbf{#2}}{\|\mathbf{#2}\|^2} \right) \mathbf{#2} \\ &= \frac{\mathbf{#1} \cdot \mathbf{#2}}{\mathbf{#2} \cdot \mathbf{#2}} \mathbf{#2} \end{align} } 

On the other hand, I'm asking myself how many times you will use such a three line display. Anyway…

\documentclass{article} \usepackage{amsmath} \usepackage{lipsum}% for mock text \NewDocumentCommand{\VectorProjection}{O{u} O{v}}{% \begin{align} \operatorname{proj}_{\mathbf{#2}} \mathbf{#1} &= \frac{\mathbf{#1} \cdot \mathbf{#2}}{\|\mathbf{#2}\|^2} \mathbf{#2} \\ &= \left( \frac{\mathbf{#1} \cdot \mathbf{#2}}{\|\mathbf{#2}\|^2} \right) \mathbf{#2} \\ &= \frac{\mathbf{#1} \cdot \mathbf{#2}}{\mathbf{#2} \cdot \mathbf{#2}} \mathbf{#2} \end{align} } \begin{document} \lipsum[20][1-4] \VectorProjection \lipsum[21][1-3] \VectorProjection[a][b] \lipsum[22][1-3] \end{document} 

enter image description here

However, I recommend not to use directly \mathbf, but choose a semantic name for your vectors and stick to it.

\documentclass{article} \usepackage{amsmath} \usepackage{lipsum}% for mock text \NewDocumentCommand{\vv}{m}{\mathbf{#1}} \NewDocumentCommand{\VectorProjection}{O{u} O{v}}{% \begin{align} \operatorname{proj}_{\vv{#2}} \vv{#1} &= \frac{\vv{#1} \cdot \vv{#2}}{\|\vv{#2}\|^2} \vv{#2} \\ &= \left( \frac{\vv{#1} \cdot \vv{#2}}{\|\vv{#2}\|^2} \right) \vv{#2} \\ &= \frac{\vv{#1} \cdot \vv{#2}}{\vv{#2} \cdot \vv{#2}} \vv{#2} \end{align} } \begin{document} \lipsum[20][1-4] \VectorProjection \lipsum[21][1-3] \VectorProjection[a][b] \lipsum[22][1-3] \end{document} 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.