9

ConTeXt has a .mkvi file extension for modules (roughly similar to LaTeX packages) which allows to use named arguments like:

\def\foo[#parameters]#content{ #parameters ... #content ...}

instead of

\def\foo[#1]#2{#1 ... #2 ...}

Not really a difference, but it has an advantage that macros tend to be more readable. Are there any packages or functionalities which allow the same for LaTeX?

7
  • 1
    \def\foo[#1]#2{#1 ... #2 ...} %where #1=parameters, %2=content seems to be enough clear. Commented Jun 14, 2020 at 20:01
  • 1
    The context extension requires imho luatex. As latex wants to support more engines (pdftex, xetex, ptex, uptex) this can not be implemented. Commented Jun 14, 2020 at 20:03
  • 1
    ConTeXt preprocesses the file before even running LuaTeX on it, so I don't think this can work with just LuaTeX. Commented Jun 14, 2020 at 21:43
  • 1
    I wrote something like that some time ago to assist on another project of mine. Some internal macros started to have too many arguments and I was changing their order too often, so keeping track of the argument numbers was becoming a nuisance (and often lead to errors). The code is here, if you're interested: github.com/PhelypeOleinik/namedef. To build the docs just run pdflatex namedef.ins, and a .sty file should be generated. Commented Jun 14, 2020 at 23:36
  • @PhelypeOleinik I've had to install a dozen packages to compile docs (I work with a minimal LaTeX installation). However, I'm pleased to see catcode trickery. It looks ConTeXt enough to my taste. I'll accept your comment if you make it an answer.
    – user193767
    Commented Jun 14, 2020 at 23:52

1 Answer 1

14

I wrote something like that some time ago to assist in another project of mine. Some internal macros started to have too many arguments and I was changing their order too often, so keeping track of the argument numbers was becoming a nuisance (and often lead to errors).

To solve that, I wrote the namedef package, that allows you to change from (an admittedly boring example):

\def\Say#1 to #2%
  {#1, #2!}

to

\named\def\Say#[greeting] to #[whom]%
  {#[greeting], #[whom]!}

The advantage I saw in this syntax is that if you decide to swap the order of #[greeting] and #[whom] in the parameter text, you don't have to change them in the replacement text—the advantage of semantics over syntax :-)

The code works by scanning the definition for #6[⟨name⟩], replacing them by numbers, and then handing the translated tokens for TeX to perform the definition.

The code is hosted at https://github.com/PhelypeOleinik/namedef. To build the .sty file, run tex namedef.ins, and to build the documentation, run pdflatex namedef.ins. The generated .sty file can be used in LaTeX with \usepackage{namedef}, or in other formats with \input namedef.sty.

2
  • 2
    Nice. Did you think to #<name># instead of the brackets?
    – egreg
    Commented Jun 15, 2020 at 8:26
  • 1
    @egreg Hm... I didn't think of that. It would be a bit tricky in case you have single parameter tokens in the replacement text, like \edef\foo#name#{\string#then#name#} (not sure it is possible to distinguish the right case reliably). Also according to this bloke, I can't have a macro delimited by a #, so it makes the implementation a bit more complicated :-) That said, since it's possible to change the delimiter when necessary, it should be possible to use that syntax... Commented Jun 15, 2020 at 16:54

You must log in to answer this question.