3

I want to write a command.

This is the example the commands should achieve:

\begin{alignat}{1}
Hello \\
Hello two \\
Hello three
\end{alignat}{1}

This should the commands look like:

\mycommand {
\command{Hello}
\command{Hello two}
\command{Hello three}
}

\mycommand has one argument and this will include a list of commands. It will put a \begin{alignat}{1} before all commands and a \end{alignat}{1} after all commands. Between each of the commands it will insert a \\ (after the last command no \\ is inserted and this is the difficult part).

In this example the \command is

\newcommand{\command}[1]{#1}

The Question is how do i write \mycommmand

5
  • 1
    Where will you be using \mycommand? Inside a tabular?
    – Werner
    Jan 22, 2015 at 20:20
  • no it is like a macro for a table. and \command will insert a row Jan 23, 2015 at 0:34
  • 1
    Could you show a use-case? Sometimes working with macros inside tables could be tricky, so having a use-case could help with getting proper answers.
    – Werner
    Jan 23, 2015 at 0:38
  • That last case you say is too easy: \newcommand\mycommand[1]{\begin{alignat}{1}#1\end{alignat}} and \newcommand\command[1]{#1\\}.
    – Manuel
    Jan 23, 2015 at 2:37
  • yes thats the general idea but the problem is that this will insert a $\\$ after the last \command and this is what i want to omit Jan 23, 2015 at 11:35

3 Answers 3

4

Here is an implementation of \mycommand and \command that provides what you're after:

enter image description here

\documentclass{article}
\usepackage{amsmath}
\begin{document}

Some text before.
\begin{alignat}{1}
  \text{Hello} \\
  \text{Hello two} \\
  \text{Hello three}
\end{alignat}
Some text after.

\noindent
\hrulefill

\newcommand{\mycommand}[1]{%
  \begin{alignat}{1} #1 \end{alignat}%
}%

Some text before.
\mycommand{
  \text{Hello} \\
  \text{Hello two} \\
  \text{Hello three}
}%
Some text after.

\noindent
\hrulefill

\makeatletter
\renewcommand{\mycommand}[1]{%
  \begin{alignat}{1} #1\null \end{alignat}%
}%
\def\@afterfi#1\fi{\fi#1}%
\newcommand{\command}[1]{\text{#1} \@ifnextchar\null{}{\\}}%
\makeatother

Some text before.
\mycommand{
  \command{Hello}
  \command{Hello two}
  \command{Hello three}
}%
Some text after.

\end{document}

An additional \null token is inserted at the end of \mycommand's argument, and used as a check in \command using \@ifnextchar.

1
  • With xparse (which is in the title), it would be \NewDocumentCommand\command{mt\null}{\text{#1}\IfBooleanF{#2}{\\}}.
    – Manuel
    Jan 23, 2015 at 16:06
3

Doing it with just xparse facilities is complicated. Here's an implementation using some functions from expl3:

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

\ExplSyntaxOn

\seq_new:N \l_mycommand_lines_seq
\seq_new:N \l_mycommand_output_seq

\NewDocumentCommand{\mycommand}{m}
 {
  \seq_set_split:Nnn \l_mycommand_lines_seq { \command } { #1 }
  \seq_pop_left:NN \l_mycommand_lines_seq \l_tmpa_tl
  \seq_set_map:NNn \l_mycommand_output_seq \l_mycommand_lines_seq
   { \exp_not:n { \command { ##1 } } }
  \begin{align}
  \seq_use:Nn \l_mycommand_output_seq { \\ }
  \end{align}
 }

\cs_generate_variant:Nn \tl_if_blank:nT { x }
\ExplSyntaxOff

\newcommand{\command}[1]{#1}

\begin{document}

\mycommand{
\command{Hello}
\command{Hello &= two}
\command{Hello &= three}
}

\end{document}

The input is split at \command tokens; white space will be automatically trimmed. The first element in the sequence is popped off, as it will be empty. Then the sequence is mapped to reinsert \command before the items (but a different macro could be used. Then the resulting sequence is used with \\ in between any two items.

enter image description here

2
  • Is there a reason why you declared the variables \l_mycommand_lines_seq and \l_mycommand_output_seq outside \mycommand's definition? Do \l_-variables need to be declared outside the “environment” in which they are actually set?
    – Pier Paolo
    Jan 23, 2015 at 22:03
  • 2
    @PierPaolo Yes, they should, or you would redeclare them every time the macro/environment is called.
    – egreg
    Jan 23, 2015 at 22:06
0

This adds a \\ after each token in the argument.

\ExplSyntaxOn
\NewDocumentCommand\mycommand{m}
 {
  \tl_map_inline:nn {#1} {##1\\}
 }
\ExplSyntaxOff
2
  • this is not correct. it insert too many \\ Jan 23, 2015 at 1:41
  • Well, then your question might be not as clear as you think. What I understood (before your edit) that you wanted \mycommand{\commanda \commandb \commandc} to \commanda\\\commandb\\\commandc. Now, from your new edit I don't understand anything (at least before I understood something, altough it was wrong). Try making a better and exact example of what you want.
    – Manuel
    Jan 23, 2015 at 2:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.