2

I am trying to write some macros to easy my life while writing mathematics in LaTeX. For this, I would like to have some macros to write wedge products in a more concise manner. I have a command which typesets general wedge products based on a comma separated list:

\DeclareListParser*{\forcommalist}{,}
\NewDocumentCommand{\wedgeproduct}{s m}{%
    \IfValueTF{#1}{\forcommalist{\listadd\wedgelist}{#2}}{\forlistloop{\listadd\wedgelist}{#2}}
    \newcounter{wedgelength}
    \forlistloop{\ifnumequal{\value{wedgelength}}{0}{}{\wedge}\stepcounter{wedgelength}}{\wedgelist}
}

(using xparse and etoolbox). I am trying to define a macro \diffform as follows

\NewDocumentCommand{\diffform}{m}{%
    \forcommalist{\listadd\formlist{}d}{#1}
    \wedgeproduct*{{\formlist}}
}

But when using it as (in mathmode)

\diffform{x,y}

It gives the following error

! Undefined control sequence.
<argument> ...}{\wedge }\stepcounter {wedgelength}{\formlist 
                                                  }
l.21    \diffform{x,y}

I do not really understand what is going wrong (because it should not be looking for \formlist but for \wedgelist). How can I solve this problem? Any references to general explanations about programming macros like this in (Lua)TeX are also appreciated.

Full source code:

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}
\usepackage{etoolbox}

\DeclareListParser*{\forcommalist}{,}
\NewDocumentCommand{\wedgeproduct}{s m}{%
        \IfValueTF{#1}{\forcommalist{\listadd\wedgelist}{#2}}{\forlistloop{\listadd\wedgelist}{#2}}
        \newcounter{wedgelength}
        \forlistloop{\ifnumequal{\value{wedgelength}}{0}{}{\wedge}\stepcounter{wedgelength}}{\wedgelist}
}

\NewDocumentCommand{\diffform}{m}{%
        \forcommalist{\listadd\formlist{}d}{#1}
        \wedgeproduct*{{\formlist}}
}

\begin{document}
\begin{equation*}
        \diffform{x,y}
\end{equation*}
\end{document}
3

Rather than etoolbox, I'd go with the more powerful and less clumsy expl3.

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}

\newcommand{\diff}{\mathop{}\!d}

\ExplSyntaxOn
\NewDocumentCommand{\diffform}{m}
 {
  \hoekstra_diffform:n { #1 }
 }

\seq_new:N \l__hoekstra_diffform_in_seq
\seq_new:N \l__hoekstra_diffform_out_seq

\cs_new_protected:Nn \hoekstra_diffform:n
 {
  \seq_set_from_clist:Nn \l__hoekstra_diffform_in_seq { #1 }
  \seq_set_map:NNn \l__hoekstra_diffform_out_seq \l__hoekstra_diffform_in_seq { \diff ##1 }
  \seq_use:Nn \l__hoekstra_diffform_out_seq { \wedge }
 }
\ExplSyntaxOff

\begin{document}

\begin{equation*}
\diffform{x} \qquad \diffform{x,y,z,t}
\end{equation*}

\end{document}

The working is as follows:

  1. The input is split at commas and populates a sequence.
  2. A new sequence is built from it by adding the “differential d” in front of each item.
  3. The new sequence is delivered, with \wedge in between items.

enter image description here

2
  • 1
    Thank you! It works like a charm.
    – D Hoekstra
    Jun 5 at 10:15
  • +1: But I fear that this will soon cause your reputation to exceed the Porsche number :) (911k). Jun 6 at 1:39

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.