3

I defined a macro with variadic arguments as below, and it works fine.
$\un{N}$ => [N]
$\un{J}{s}$ => [J/s]

\makeatletter
\newcommand\un[1]{\@ifnextchar\bgroup{\un@double{#1}}{\un@single{#1}}}
\newcommand\un@single[1]{{\ \boldsymbol{ \left[ \mathrm{#1} \right]} \ }}
\newcommand\un@double[2]{{\ \boldsymbol{ \left[ \mathrm{\dfrac{\mathrm{#1}}{\mathrm{#2}}} \right] } \ }}
\makeatother

In the same way, I defined another macro to denote partial differentiation. But it doesn't work. The desired result is as follows:
\pfrac{x}{y} => ∂x/∂y
\pfrac{x}{y}{z} => ∂/∂z (∂x/∂y)

\makeatletter
\newcommand\pfrac[1]{ \@ifnextchar\bgroup{\pfrac@three{#1}}{\pfrac@two{#1}}}
\newcommand\pfrac@two[2]{{ \frac{\partial #1}{\partial #2} }}
\newcommand\pfrac@three[3]{{ \frac{\partial }{\partial #3} \left( \frac{\partial #1}{\partial #2} \right) }}
\makeatother

How can I fix the latter newcommand?

2
  • 1
    This is possible (the xparse package even still supports the deprecated g option for defining optional {} arguments) but you should not define commands this way as they break all latex syntax conventions. Optional arguments should be in [] not {} . Syntax that wouldn't break latex conventions would be \un{J}[s], \un{j/s} \un{j,s}, ... Commented May 25 at 10:55
  • 1
    So you want the result of \pfrac ABC to differ from the result of \pfrac AB{C}? And what about \pfrac ABC versus \pfrac AB C? (\@ifnextchar consumes space tokens...) Commented May 25 at 11:44

3 Answers 3

5

Let's expand it by hand to see what happens. Starting from:

\pfrac{x}{y}

after substituting x into #1, we get:

\@ifnextchar\bgroup{\pfrac@three{x}}{\pfrac@two{x}}{y}

Since the content right after \@ifnextchar\bgroup{\pfrac@three{x}}{\pfrac@two{x}} is {y}, in particular it starts with {, so the first branch is selected, and after a while it becomes:

\pfrac@three{x}{y}

Oops. Unfortunately it's very difficult to observe this process directly (unravel package?) and documentation (to run the program by hand) are hard to find.

How to fix:

\makeatletter
\newcommand\pfrac[2]{\@ifnextchar\bgroup{\pfrac@three{#1}{#2}}{\pfrac@two{#1}{#2}}}
\newcommand\pfrac@two[2]{\frac{\partial #1}{\partial #2}}
\newcommand\pfrac@three[3]{\frac{\partial }{\partial #3} \left( \frac{\partial #1}{\partial #2} \right)}
\makeatother

I remove the redundant braces and spaces (although they seems mostly harmless in this case).

0
3

You need only two macros

\newcommand\pfrac[2]{%
  \@ifnextchar\bgroup%
  {\pfrac@three{#1}{#2}}%
  {\frac{\partial #1}{\partial #2}}%
}

\newcommand\pfrac@three[3]{%
  \frac{\partial }{\partial #3} \left( \pfrac{#1}{#2} \right)%
}

but it would be probably preferable to stay with optional arguments

\NewDocumentCommand{\xpfrac}{ omm }
  {%
    \IfValueTF{#1}
    {\frac{\partial }{\partial #1} \left( \xpfrac{#2}{#3} \right)}
    {\frac{\partial #2}{\partial #3}}
  }

Note that you can put the optional argument at the end with mmo if you prefer \xpfrac{x}{y}[z] instead of \xpfrac[z]{x}{y}.

Example:

\documentclass{article}

\makeatletter
\newcommand\pfrac[2]{%
  \@ifnextchar\bgroup%
  {\pfrac@three{#1}{#2}}%
  {\frac{\partial #1}{\partial #2}}%
}

\newcommand\pfrac@three[3]{%
  \frac{\partial }{\partial #3} \left( \pfrac{#1}{#2} \right)%
}
\makeatother

\NewDocumentCommand{\xpfrac}{ omm }
  {%
    \IfValueTF{#1}
    {\frac{\partial }{\partial #1} \left( \xpfrac{#2}{#3} \right)}
    {\frac{\partial #2}{\partial #3}}
  }


\begin{document}

$\pfrac{x}{y}$

$\pfrac{x}{y}{z}$

$\xpfrac{x}{y}$

$\xpfrac[z]{x}{y}$

\end{document}

Example

0
0

My proposal is to not pursue the path of “variadic macro”. In your use case the syntax should be

\pfrac{x}{y}
\pfrac[z]{x}{y}

because z will appear first in the output. Alternatively, \pfrac{x}{y}[z], but this is less appealing.

\documentclass{article}
\usepackage{amsmath}

\NewDocumentCommand{\pfrac}{omm}{%
  \IfValueT{#1}{\frac{\partial}{\partial#1}\!\left(}%
  \frac{\partial#2}{\partial#3}%
  \IfValueT{#1}{\right)}%
}

\begin{document}

\[
\pfrac{x}{y}\qquad \pfrac[z]{x}{y}
\]

\begin{center}% for testing text style
$\pfrac{x}{y}\qquad \pfrac[z]{x}{y}$
\end{center}

\end{document}

enter image description here

With the alternative syntax (same output):

\documentclass{article}
\usepackage{amsmath}

\NewDocumentCommand{\pfrac}{mmo}{%
  \IfValueT{#3}{\frac{\partial}{\partial#3}\!\left(}%
  \frac{\partial#1}{\partial#2}%
  \IfValueT{#3}{\right)}%
}

\begin{document}

\[
\pfrac{x}{y}\qquad \pfrac{x}{y}[z]
\]

\begin{center}% for testing text style
$\pfrac{x}{y}\qquad \pfrac{x}{y}[z]$
\end{center}

\end{document}

The first proposal is better also because in the second case you would need some care in case a bracket follows the construction without the optional argument.

You must log in to answer this question.

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