5

I am trying to make a macro that defines a one-parameter macro for me (the reason is a veeeery long story). Here's my implementation.

\def\foo#1#2{%
\expandafter\def\csname bar#1\endcsname##1{#2}%
}

\foo{qix}{:: #1 ::}

\barqix{hi world}

Now the question. Using the #1 notation is possible but unaesthetic in my application. I would like use instead an unused macro, e.g. \PARAM . I guess for this I should be \leting \PARAM to #1, but something goes wrong if I do.

Any idea to get around this?

  • 2
    So you'd like \foo{qix}{:: \PARAM ::}? I find this much less aesthetic, besides giving a wealth of problems with space clobbering. – egreg Feb 24 '17 at 18:18
3

You can do that by storing the captured argument in \PARAM. Note that parameterless macros gobble spaces after them, so you'll have to be careful in what you pass to the resulting macro:

enter image description here

\documentclass{article}

\begin{document}

\def\foo#1#2{%
  \expandafter\def\csname bar#1\endcsname##1{\def\PARAM{##1}#2}%
}

\foo{baz}{:: \PARAM ::}

\barbaz{hi world}

\foo{bat}{:: {\PARAM} ::}

\barbat{hi world}

\end{document}
  • 1
    Well, if a call is nested… – egreg Feb 24 '17 at 18:28
  • 1
    @egreg: As in \barbat{hi \barbat{world}}? – Werner Feb 24 '17 at 18:29
  • 1
    For instance. If \PARAM is used twice, I foresee disaster. – egreg Feb 24 '17 at 18:31
  • This solution works, but as @egreg comments it might get very tricky if nested, which is precisely what I intended to do... – Jaeya Feb 24 '17 at 18:31
  • @Jaeya: It would be great if you can show examples of your use cases (which includes nesting). – Werner Feb 24 '17 at 18:33
4

Usually people have the opposite problem. ;-)

\def\PARAM{##1}
\def\foo#1#2{%
  \expandafter\edef\csname bar#1\endcsname##1{#2}%
}

\foo{qix}{:: \PARAM\space ::}

\barqix{hi world}

\bye

You have to use \edef, with all the connected problems, because TeX does no interpretation of the replacement text in a \def.

Otherwise, you'd have to do a lengthy scanning of the replacement text, substituting \PARAM with ##1; if it appears in a group…

Besides, I find

\foo{qix}{:: #1 ::}

much less clumsy.

Just for fun, with expl3 and l3regex:

\input expl3-generic

\ExplSyntaxOn
\cs_new_protected:Npn \foo #1 #2
 {
  \tl_set:Nn \l_tmpa_tl { #2 }
  \regex_replace_all:nnN { PARAM } { \cP\#1 } \l_tmpa_tl
  \cs_set:NV \temp:n \l_tmpa_tl
  \cs_set_eq:cN {bar#1} \temp:n
 }
\cs_generate_variant:Nn \cs_set:Nn { NV }
\ExplSyntaxOff

\foo{qix}{:: PARAM ::}

\barqix{hi world}

\bye

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.