0

In trying to learn more about the details of what is possible with LaTeX, I wanted to see if I could create an API around creating functions. This is what the output function would be, for example:

\NewDocumentCommand{\foo}{mmmO{}}{
  % #1 == foo, tl
  % #2 == baz, clist
  % #3 == bac, seq
  % #4 == asdf, prop list
  \typeout{#1}
  \typeout{#2}
  \typeout{#3}
  \typeout{#4}
}

Roughly that would be generated from this sort of API:

\mycommand{examplea}{
  \myarg{foo}{tl}
  \myarg{baz}{clist}
  \myarg{bac}{seq}
  \myarg{asdf}{prop}[optional]
  \mycommandbody{
    \typeout{\foo}
    \typeout{\baz}
    \typeout{\bac}
    \typeout{\asdf}
  }
}

Essentially what I am trying to accomplish is to dynamically generate the argument signature. That is, make this:

mmmO{}

from the following:

\myarg{foo}{tl}
\myarg{baz}{clist}
\myarg{bac}{seq}
\myarg{asdf}{prop}[optional]

The following is the MWE:

\documentclass[a4paper]{article}

\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

% not sure where to define this.
\seq_new \l_example_options_seq
\tl_new \l_example_name_tl
\tl_new \l_example_datatype_tl
\prop_new \l_example_options_prop

\NewDocumentCommand{\myarg}{mmO{}}{
  \tl_gset \l_example_name_tl {#1}
  \tl_gset \l_example_datatype_tl {#2}
  \prop_gset \l_example_options_prop {#3}

  % store these values in a sequence
  % of property lists
  \seq_push_right {name=\l_example_name_tl,datatype=\l_example_datatype_tl,options=\l_example_options_prop}
}

% don't know how to make it into a block
\NewDocumentCommand{\mycommandbody}{m}{
  \tl_gset \l_example_name_tl {#1}
}

\NewDocumentEnvironment{mycommand}{m}{

}{
  % loop through \l_example_options_seq and generate
  % mmmO{} (in this case) dynamically from the items.
  \NewDocumentCommand{#1}{\dynamicallygeneratedargs}{\mycommandbody}
}

\begin{document}

Hello world.

\mycommand{examplea}{
  \myarg{foo}{tl}
  \myarg{baz}{clist}
  \myarg{bac}{seq}
  \myarg{asdf}{prop}[optional]
  \mycommandbody{
    \typeout{\foo}
    \typeout{\baz}
    \typeout{\bac}
    \typeout{\asdf}
  }
}

\end{document}

The reason for this question is to learn more about complex ways of dynamically generating stuff in LaTeX3. This example requires what seems like a complex usage of seq in order to capture the arguments and then later on generate the signature. Wondering if these certain things are possible in LaTeX and how they might work.

  • That seems not feasible. The macro definition would not contain the names of the arguments (as long as you don't define a key=value syntax), neither does it care for the nature of the arguments, so there is no point in doing \myarg{foo}{<type-of-foo>}. TeX doesn't enforce any type of argument on the input, it just tokenizes the next token or group as the next argument. – Skillmon Mar 26 '18 at 18:25
  • 2
    Sorry, I have to say this, but you're flooding the site with a lot of questions, like in a rush about learning L3 in a couple of hours. – user31729 Mar 26 '18 at 18:26
  • 2
    perhaps starting LaTeX with expl3 might not be the best way however ... – user31729 Mar 26 '18 at 18:29
  • 3
    it is possible to do this (tex is turing complete language so you can do all sorts of things) but you should think really hard whether it is a good idea to do so (it almost certainly is not) xparse is explicitly not intended as a programming layer it is intended as a high level declarative declaration of the document level syntax. One of the main advantages of having it set up as a declarative system is that editors, syntax checkers and highlighters etc can get the signature of document markup without having to interpret tex code. If you generate the signature in tex, you destroy that. – David Carlisle Mar 26 '18 at 18:42
  • 4
    There should be a reason why you’re asking this question, but I can’t see it, sorry. – egreg Mar 26 '18 at 19:38

Your Answer

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

Browse other questions tagged or ask your own question.