7

Within an align* environment I have lines of the form

\Rightarrow &<\texttt{Program Code}, [a \mapsto 1, b \mapsto 2]> &\text{Rule Name}\\
\Rightarrow &<\texttt{Program Code 2}, [a \mapsto 2, b \mapsto 3]> &\text{Rule Name 2} \\

Giving

LaTeX render of the above code

I thought of making a macro to make this much easier, of the form

\pline{Program Code}{a \mapsto 2,b \mapsto 2}{Rule name}

I want the third argument, the rule name, to be optional. If so, it shouldn't show up on the line, on the right.

I was trying to use the native ifx/else combo but I switched to the xparse package. Right now, I have this:

\NewDocumentCommand{\pline}{+m +m o}{
    \Rightarrow &<\texttt{#1}, \ensuremath{[#2]}>
    \IfValueTF{#3}
        {&\text{#3}}
}

However, the rule names do not align right. See the below demonstration:

\begin{align*}
    % Explicit Code
    \Rightarrow &<\texttt{Program Code}, [a \mapsto 1, b \mapsto 2]> &\text{Rule Name} \\
    \Rightarrow &<\texttt{Program Code 2}, [a \mapsto 2, b \mapsto 3]> &\text{Rule Name 2} \\\\
    % Commands
    \pline{Program Code}{a \mapsto 1,b \mapsto 2}{Rule Name} \\
    \pline{Program Code 2}{a \mapsto 2,b \mapsto 3}{Rule Name 2}
\end{align*}

Alignment fixed, but font wrong.

To fix this, I put the & infront of \IfValueTF and removed it from before the \text{#3}. However, though this fixes the alignment issue, the font is still wrong and seems to stay in math mode, in spite of the \text.

How can I fix both these issues?

Minimal working example:

\documentclass[notitlepage]{report}

\usepackage{mathpazo}
\usepackage{amsmath,amssymb}
\usepackage{xparse}

\begin{document}

\NewDocumentCommand{\pline}{+m +m o}{
    \Rightarrow &<\texttt{#1}, \ensuremath{[#2]}>
    \IfValueTF{#3}
        {\&text{#3}}
}

\NewDocumentCommand{\plinealigned}{+m +m o}{
    \Rightarrow &<\texttt{#1}, \ensuremath{[#2]}>
    &\IfValueTF{#3}
        {\text{#3}}
}

\begin{align*}
    % Explicit Code
    \Rightarrow &<\texttt{Program Code}, [a \mapsto 1, b \mapsto 2]> &\text{Rule Name} \\
    \Rightarrow &<\texttt{Program Code 2}, [a \mapsto 2, b \mapsto 3]> &\text{Rule Name 2} \\\\
    % Commands
    \pline{Program Code}{a \mapsto 1,b \mapsto 2}{Rule Name} \\
    \pline{Program Code 2}{a \mapsto 2,b \mapsto 3}{Rule Name 2}\\\\
    % Commands with alignment fixed
    \plinealigned{Program Code}{a \mapsto 1,b \mapsto 2}{Rule Name} \\
    \plinealigned{Program Code 2}{a \mapsto 2,b \mapsto 3}{Rule Name 2}
\end{align*}

\end{document}

Image showing all three cases of the issue.

1
  • 1
    You should change \IfValueTF to \IfValueT or add a pair of curly braces. \IfValueTF takes three arguments: one for the thing to be tested, one for the true branch and one for the false branch. But in your defintion, you miss the latter. Actually, with O{} instead of o, you can omit the test altogether. Commented May 4, 2023 at 0:16

2 Answers 2

8

You need \IfValueT not \IfValueTF. You misplaced &, {&\text{#3}} not {\&text{#3}} in \pline. The o is optional argument, you need [] not {}.

\documentclass[notitlepage]{report}

\usepackage{mathpazo}
\usepackage{amsmath,amssymb}
\usepackage{xparse}

\begin{document}

\NewDocumentCommand{\pline}{+m +m o}{
    \Rightarrow &<\texttt{#1}, \ensuremath{[#2]}>
    \IfValueT{#3}
        {&\text{#3}}
}

\NewDocumentCommand{\plinealigned}{+m +m o}{
    \Rightarrow &<\texttt{#1}, \ensuremath{[#2]}>
    &\IfValueT{#3}
        {\text{#3}}
}

\begin{align*}
    % Explicit Code
    \Rightarrow &<\texttt{Program Code}, [a \mapsto 1, b \mapsto 2]> &\text{Rule Name} \\
    \Rightarrow &<\texttt{Program Code 2}, [a \mapsto 2, b \mapsto 3]> &\text{Rule Name 2} \\\\
    % Commands
    \pline{Program Code}{a \mapsto 1,b \mapsto 2}[Rule Name] \\
    \pline{Program Code 2}{a \mapsto 2,b \mapsto 3}[Rule Name 2]\\
    % Commands with alignment fixed
    \plinealigned{Program Code}{a \mapsto 1,b \mapsto 2}[Rule Name] \\
    \plinealigned{Program Code 2}{a \mapsto 2,b \mapsto 3}[Rule Name 2]
\end{align*}

\end{document}

enter image description here

2
  • Oh, I believe the \&text was just a mistake by me in copying the command over, but the answer does work, thank you.
    – Harith
    Commented May 4, 2023 at 1:43
  • @Harith note you only need xparse in old latex releases. \NewDocumentCommand is defined in current formats with no package needed. Commented May 4, 2023 at 8:05
5

There are a few errors in your code:

  1. \&text should be &\text
  2. \ensuremath does nothing useful
  3. the argument type should be m, not +m
  4. < and > aren't to be used as brackets
  5. an optional argument is inside square brackets, not braces

I add some space after the \Rightarrow and use \langle and \rangle for the angle brackets. Note the different spacing. Also &&\text{} for better alignment.

\documentclass{article}
\usepackage{amsmath,amssymb}

\begin{document}

\NewDocumentCommand{\pline}{m m o}{%
  \Rightarrow{} & \langle\texttt{#1}, [#2]\rangle
  \IfValueT{#3}{&&\text{#3}}%
}

\begin{align*}
\pline{Program Code}{a \mapsto 1,b \mapsto 2}[Rule Name] \\
\pline{Program Code 2}{a \mapsto 2,b \mapsto 3}[Rule Name 2]
\end{align*}

\end{document}

enter image description here

Why is \ensuremath doing nothing useful? The command \pline (as written) must be used in math mode, because of \Rightarrow.

If you really want < and >, make them into the proper kind of math atoms.

\documentclass{article}
\usepackage{amsmath,amssymb}

\begin{document}

\NewDocumentCommand{\pline}{m m o}{%
  \Rightarrow{} & \mathopen<\texttt{#1}, [#2]\mathclose>
  \IfValueT{#3}{&&\text{#3}}%
}

\begin{align*}
\pline{Program Code}{a \mapsto 1,b \mapsto 2}[Rule Name] \\
\pline{Program Code 2}{a \mapsto 2,b \mapsto 3}[Rule Name 2]
\end{align*}

\end{document}

enter image description here

You must log in to answer this question.

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