4

I would like to have a macro, call it \magicreplace which gets some arbitrary parameter (= sequence of tokens) and replaces every occurrence of some token (say, a or x or ,) with some fixed sequence of tokens (say hello, or \text{hello}).

So, \magicreplace{a}{abc{abc}} expands to hellobc{abc}.

Is there something available in some package for doing that? If not, how would I go about implementing this thing?

Notes:

  • Can be LaTeX rather than plain TeX
  • pdftex and/or xetex please
3
  • since you use \rm I'm assuming you need this for plain tex not latex? Also do you need it for pdftex or would luatex or xetex solutions be OK? – David Carlisle Jun 30 '17 at 20:54
  • if you are replacing a by hello what do you want abc{abc} to produce? (hellobc{abc} is perhaps easier than {hellbc{hellobc}) – David Carlisle Jun 30 '17 at 20:57
  • @DavidCarlisle: See edits. – einpoklum Jun 30 '17 at 21:08
4

This is already available out of the box in expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\magicreplace}{mmm}
 {
  \tl_set:Nn \l_einpoklum_magicreplace_tl { #3 }
  \tl_replace_all:Nnn \l_einpoklum_magicreplace_tl { #1 } { #2 }
  \tl_use:N \l_einpoklum_magicreplace_tl
 }
\tl_new:N \l_einpoklum_magicreplace_tl
\ExplSyntaxOff

\begin{document}

\magicreplace{a}{hello}{abc{abc}}

\magicreplace{a}{hello}{a b c{a b c}a}

\end{document}

enter image description here

A different version where the replacement string is fixed (but changeable).

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\magicreplace}{mm}
 {
  \tl_set:Nn \l_einpoklum_magicreplace_tl { #2 }
  \tl_replace_all:NnV \l_einpoklum_magicreplace_tl { #1 } \l_einpoklum_magicreplace_rep_tl
  \tl_use:N \l_einpoklum_magicreplace_tl
 }
\NewDocumentCommand{\setreplacement}{m}
 {
  \tl_set:Nn \l_einpoklum_magicreplace_rep_tl { #1 }
 }

\tl_new:N \l_einpoklum_magicreplace_tl
\tl_new:N \l_einpoklum_magicreplace_rep_tl
\cs_generate_variant:Nn \tl_replace_all:Nnn { NnV }
\ExplSyntaxOff

\begin{document}

\setreplacement{hello}

\magicreplace{a}{hello}{abc{abc}}

\setreplacement{world}
\magicreplace{a}{a b c{a b c}a}

\end{document}

enter image description here

3
  • where's the fun in stealing from boxes? – David Carlisle Jun 30 '17 at 22:12
  • @DavidCarlisle That Bruno does the work. – egreg Jun 30 '17 at 22:17
  • I suspected there was something like this deep under the hood. – einpoklum Jul 1 '17 at 9:38
3

It's possible to take more care over white space but a simple version is

enter image description here

\documentclass{article}

\def\zz#1#2#3{\def\zzz##1#1{##1#2\zzz}{\zzz#3\zzzz#1\relax}}
\def\zzzz#1\relax{}
\begin{document}

\zz{a}{hello}{abc{abc}abc}
\end{document}
2
  • What would the issue with whitespace be? – einpoklum Jun 30 '17 at 21:51
  • @einpoklume actually with that form space is probably Ok but if the list of tokens before the a is just a brace group, th ebraces would be dropped – David Carlisle Jun 30 '17 at 22:15

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.