9

What I am looking for is a single newcommand, let's call it \wedges, with a variable number of inputs that yields in a flexible way the following result:

enter image description here

I have already written the code for the variable input commands for the unbarred and barred parts isolated, they are respectively \cunei (italian for wedges) and \bcunei (b stands for barred). Thus \wedges = \cunei \wedge \bcunei. The code (inspired from here) is the following and outputs the above picture:

\documentclass[11pt,a4paper]{amsart}

% Just to shorten barring z
\newcommand{\bz}{\bar{z}}

% Wedge part (commands are \cunei, \checknextarg, \gobblenextarg)
\makeatletter
\newcommand{\cunei}[1]{%
    dz^{#1}\checknextarg}
\newcommand{\checknextarg}{\@ifnextchar\bgroup{\gobblenextarg}{}}
\newcommand{\gobblenextarg}[1]{\wedge dz^{#1}\@ifnextchar\bgroup{\gobblenextarg}{}}
\makeatother

% Wedge bar part (commands are \bcunei, \bchecknextarg, \bgobblenextarg, note the b in front)
\makeatletter
\newcommand{\bcunei}[1]{%
    d\bz^{#1}\bchecknextarg}
\newcommand{\bchecknextarg}{\@ifnextchar\bgroup{\bgobblenextarg}{}}
\newcommand{\bgobblenextarg}[1]{\wedge d\bz^{#1}\@ifnextchar\bgroup{\bgobblenextarg}{}}
\makeatother

\begin{document}
    \[
    \cunei{a}{b}{c}{d} \wedge \bcunei{e}{f}{g}
    \]
\end{document}

I am not satisfied with this since in case of only:

enter image description here

it is still quite verbose, the code is: \cunei{a} \wedge \bcunei{b}. Whereas ideally I would like something like \wedges{a}{\bar{b}} to produce it, where the command \wedges has flexible number of inputs and when it detects the \bar{} as input automatically writes d\bz^{}, instead of dz^{} (actually, since the exponents are usually always j,k,l,m, etc I again, as I did for z in the above code, will introduce newcommands as \bj, \bk, \bl, \bm, etc to shorten \bar{j},..., so I want the command to detect \bj, not \bar{j}, if that makes a difference). Is there a way to do this? If it may help note that unbarred and barred elements are always ordered, first the unbarred ones and then the barred ones. Thanks.

3

3 Answers 3

12

I would recommend not to go the “variable number of arguments” way. A comma separated list of exponents is clearer and easier to type.

Here the “conjugates” are prefixed by *.

\documentclass[11pt,a4paper]{amsart}

% Just to shorten barring z
\newcommand{\bz}{\bar{z}}

\ExplSyntaxOn

\NewDocumentCommand{\cunei}{m}
 {
  \freestyla_cunei:n {#1}
 }

\seq_new:N \l__freestyla_cunei_seq

\cs_new_protected:Nn \freestyla_cunei:n
 {
  \seq_clear:N \l__freestyla_cunei_seq
  \clist_map_inline:nn {#1}
   {
    \str_if_eq:eeTF {*} { \str_head:n {##1} }
     {% conjugate
      \seq_put_right:Nn \l__freestyla_cunei_seq { d\bar{z}^{\mspace{1mu}\str_tail:n {##1}} }
     }
     {
      \seq_put_right:Nn \l__freestyla_cunei_seq { dz^{##1} }
     }
   }
  \seq_use:Nn \l__freestyla_cunei_seq { \wedge }
 }

\ExplSyntaxOff

\begin{document}

\[
\cunei{a,b,c,d,*e,*f,*g}
\]

\end{document}

enter image description here

Each item in the list is checked; if it starts with *, d\bar{z}^{\mspace{1mu}<exponent>} is added to the sequence, otherwise dz^{<exponent>}. Finally, the items in the sequence are delivered with \wedge in between any two.

Note: \str_head:n selects the first character, \str_tail:n all except the first.

I added a small space in the “conjugate exponents”. Try without it to see the difference.

6
  • Scary, I was going to propose exactly the same syntax...
    – campa
    Commented May 24 at 17:39
  • @campa * is for conjugation, after all! 😉
    – egreg
    Commented May 24 at 17:42
  • @egreg just an off-topic curiosity: did you also had to \usepackage{expl3, xparse} to compile your code? Or I have an old Latex version?
    – Freestyla
    Commented May 24 at 20:06
  • 2
    @campa a pity you deleted your non-expl3 solution. It could be useful for people developing packages that should stay format-agnostic... 😉
    – Rmano
    Commented May 24 at 21:25
  • 2
    @Rmano It was a safety deletion. Playing with the macro seemed to fail in some cases, so I wanted to look into it. Undeleted.
    – campa
    Commented May 25 at 14:29
5

In case a LaTeX distribution is in use with expl3 not older than 2021-05-10 so that \clist_use:nn and \clist_map_tokens:nn are available you can probably use these:

\documentclass[11pt,a4paper]{amsart}

\ExplSyntaxOn
\NewDocumentCommand{\cunei}{m}{
  \exp_args:Ne \clist_use:nn {\clist_map_tokens:nn {#1} {\freestyle_cunei_chkstar:n}}{\wedge}
}
\cs_new:Nn \freestyle_cunei_chkstar:n {
  \use:c {
    use_
    \tl_if_head_is_group:nTF {#1} {i} {
      \tl_if_head_is_space:nTF {#1} {i} {
        \exp_args:Nne \use:nn {\if_meaning:w}{\tl_head:n {#1}}* \else: i\fi:
      }
    }
    i:nn
  }
  {\exp_not:n{d\bar{z}^{\mspace{1mu}\tl_tail:n {#1}}},}
  {\exp_not:n{dz^{#1}},}
}
\ExplSyntaxOff


\begin{document}

\[
\cunei{a,b,c,d,*e, *f,*g}
\]

\end{document}

enter image description here

1
  • If one loads xparse, my solution runs also with TL 2018 or 2019.
    – egreg
    Commented May 24 at 20:19
5

egreg has already answered, but just for fun a more low-level solution (but with the same input syntax)

\documentclass{article}

\makeatletter
\newcommand*{\foo}[1]{{\def\foo@i{\def\foo@i{\wedge}}\foo@ii#1,\relax,}}
\def\foo@ii#1,{\ifx\relax#1\else\foo@i\foo@iii#1**\relax\expandafter\foo@ii\fi}
\def\foo@iii#1*#2*#3\relax{d\if\relax\detokenize\expandafter{\@gobble#1?}\relax\bar{z}^{#2}\else z^{#1}\fi}
\makeatother

\begin{document}
\[
\foo{a,b,*c,*d,e,f, * g }
\]
\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 .