1

I'm looking for a shift instruction which will rotate the parameters passed to a LaTeX macro. The idea is that if optional parameters are omitted, then they should be dropped from the beginning of the parameter list instead of the end.

Here's my example usecase:

\NewDocumentCommand{\J}{o o}{
    \IfNoValueTF{#2}
    {
        \IfNoValueTF{#1}
        {\tensor{J}{}}
        {\tensor{J}{}({#1})}
    }
    {
        \tensor{J}{^{#1}}({#2})
    }
}

I can use this command like so:

\begin{equation}
    \J \quad \J[x] \quad \J[\mu][x]
\end{equation}

gives: enter image description here

The above command \J would be easier to read if I could define it like so, using an imaginary \shiftright{n} instruction:

\NewDocumentCommand{\J}{o o}{
  \IfNoValueTF{#2}{\shiftright}     % \J[x] --> \J[][x]
  \IfNoValueTF{#1}{\shiftright{2}}  % \J    --> \J[][]
  % \J[\mu][x] --> \tensor{J}{^{\mu}}(x)
  \tensor{J}{^{#1}}{#2}
}

Actually, I don't even know if it's possible to change the values of #n inside the macro. If someone could show me a way do that, and to check the number of parameters that the function has, that would be helpful too. Then I could probably define my own \shiftright macro.

Or, any other ideas to make the above idiom more expressive and easier to read than my first (working) definition?

3 Answers 3

2

As far as I'm aware it is not possible to shift arguments like this, not even in expl3 (I could be wrong about that). Also, if it was possible then in your example the printing of the parentheses (conditional on at least one argument being provided) would complicate the shifting procedure I think.

Maybe somewhat easier to read is to write an explicit enumeration of the three cases by defining helper macros \first and \second:

\documentclass{article}
\usepackage{tensor}
\usepackage{xparse}
\NewDocumentCommand{\J}{o o}{
  \IfNoValueTF{#1}{\def\first{}\def\second{}}{%          no arguments provided
  \IfNoValueTF{#2}{\def\first{}\def\second{(#1)}}{%      one argument provided
                   \def\first{#1}\def\second{(#2)}}}%  both arguments provided 
  \tensor{J}{^{\first}}{\second}
}
\begin{document}
\begin{equation}
    \J \quad \J[x] \quad \J[\mu][x]
\end{equation}
\end{document}

Output is the same as in the question.

1
  • Thanks. Maybe this is the only way to get it done, if it's not possible to redefine #n inside a function.
    – Myridium
    Feb 19, 2022 at 6:50
1

A easier solution is to change the input format to:

\J \quad \J[x] \quad \J^{\mu}[x]

enter image description here

Code:

\documentclass{article}
\usepackage{tensor}
\usepackage{xparse}

\NewDocumentCommand{\J}{e{^} o}{
  \tensor{J}
      {^{\IfValueT{#1}{#1}}}
      {\IfValueT{#2}{(#2)}}
}
\begin{document}
\begin{equation}
    \J \quad \J[x] \quad \J^{\mu}[x]
\end{equation}
\end{document}
1
  • This evades the question.
    – Myridium
    Feb 19, 2022 at 6:48
0

If I get it right, with a mechanism
"\J[x] --> \J[][x] and \J --> \J[][] and \J[\mu][x] --> \tensor{J}{^{\mu}}(x)"
almost the same branching/forking that currently is done depending on \IfNoValueTF must be done depending on the emptiness of [-preceded ]-delimited arguments:
If the 2nd optional argument is empty you don't want parentheses with nothing between them.
If the 1st optional argument is empty you don't want superscript-character ^.

So I don't know if you really gain readability of the code this way.

Btw: How about:

\documentclass{article}
\usepackage{tensor}

\NewDocumentCommand{\J}{o o}{%
  \IfNoValueTF{#2}{\tensor{J}{}\IfNoValueF{#1}{({#1})}}%
                  {\tensor{J}{^{#1}}({#2})}%
}%

\begin{document}

\begin{equation}
    \J \quad \J[x] \quad \J[\mu][x]
\end{equation}       

\end{document}

You could use expl3's f-type-expansion:

\documentclass{article}
\usepackage{tensor}

\ExplSyntaxOn
\NewDocumentCommand{\J}{o o}{%
  \exp_args:Nnf\use:nn
               {\tensor{J}}%
               {\IfNoValueTF{#2}{{}\IfNoValueF{#1}{({#1})}}{{^{#1}}({#2})}}%
}%
\ExplSyntaxOff

\begin{document}

\begin{equation}
    \J \quad \J[x] \quad \J[\mu][x]
\end{equation}       

\end{document}

You must log in to answer this question.

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