# “Mark” some part of a command as a prefix or postfix so it isn't affected by another command

I'm in a rather unique situation. I'd like to "mark" parts of a command output as prefix or postfix. For example:

\newcommand{\L}[1]{L\postfix{_i}}


And then be able to do something like this:

\newcommand{\est}[1]{\prefixof{#1}\hat{\mainbodyof{#1}}\postfixof{#1}}


Ideally, this should work on normal text, e.g. \est{\lambda} should expand to \hat{\lambda}. Also, \L should expand to L_i, and \est{\L} should expand to \hat{L}_i.

I know this is possible with TeX (it being Turing complete and all), but I have no idea where to even start, or what tags to put in the question exactly other than macros.

It seems @DavidCarlisle's answer doesn't work in this case:

\documentclass{article}

\usepackage{etoolbox}

\newcommand\zzfix[3]{#1#2#3}%pre-main-post

\def\prefixof#1{\expandafter\zzpre#1\relax{#1}}
\def\postfixof#1{\expandafter\zzpost#1\relax{#1}}
\def\mainbodyof#1{\expandafter\zzmain#1\relax{#1}}

\def\zzpre#1{\ifx\zzfix#1\expandafter\oneoffive\else\expandafter\gobblepastrelax\fi}
\def\zzpost#1{\ifx\zzfix#1\expandafter\threeoffive\else\expandafter\gobblepastrelax\fi}
\def\zzmain#1{\ifx\zzfix#1\expandafter\twooffive\else\expandafter\afterrelax\fi}

\def\oneoffive#1#2#3\relax#4{#1}
\def\twooffive#1#2#3\relax#4{#2}
\def\threeoffive#1#2#3\relax#4{#3}
\def\afterrelax#1\relax#2{#2}
\def\gobblepastrelax#1\relax#2{}

\newcommand{\queueState}[1][]{\zzfix{}{\ell}{\ifstrempty{#1}{}{_{#1}}}}

\newcommand{\baseQuantity}[1]{\prefixof{#1}\bar{\mainbodyof{#1}}\postfixof{#1}}

\begin{document}
But this does not work: $\baseQuantity{\queueState[1:N]}$
\end{document}


Maybe it's possible to make it work for this, too?

\show\queueState output:

> \queueState=macro:
->\@protected@testopt \queueState \\queueState {}.

• How deeply nested do you want this to be? E.g. do you want \est{\est{\L}} to give \hat{\hat{L}}_i? – Bruno Le Floch Feb 20 '18 at 14:43
• I guess I could do define est itself with a prefix and postfix if I wanted to do that. – Hameer Abbasi Feb 20 '18 at 14:46
• \zzfix has to be the first token in the expansion (so not nested), I don't see why you need the \ifstrempty test at all since you have defined it as an optional argument. latex is already testing for it being there/not being there, no need to test again. – David Carlisle Feb 21 '18 at 16:08
• I needed it because I needed to put a subscript on \ell depending on whether or not the optional command was there. However, I modified my example so \zzfix is the first token and it still doesn't work, unfortunately. See my edit. :-( – Hameer Abbasi Feb 22 '18 at 10:04

\documentclass{article}

\newcommand\zzfix[3]{#1#2#3}%pre-main-post

\renewcommand{\L}{\zzfix{}{L}{_i}}

\newcommand{\est}[1]{\prefixof{#1}\hat{\mainbodyof{#1}}\postfixof{#1}}

\def\prefixof#1{\expandafter\zzpre#1\relax{#1}}
\def\postfixof#1{\expandafter\zzpost#1\relax{#1}}
\def\mainbodyof#1{\expandafter\zzmain#1\relax{#1}}

\def\zzpre#1{\ifx\zzfix#1\expandafter\oneoffive\else\expandafter\gobblepastrelax\fi}
\def\zzpost#1{\ifx\zzfix#1\expandafter\threeoffive\else\expandafter\gobblepastrelax\fi}
\def\zzmain#1{\ifx\zzfix#1\expandafter\twooffive\else\expandafter\afterrelax\fi}

\def\oneoffive#1#2#3\relax#4{#1}
\def\twooffive#1#2#3\relax#4{#2}
\def\threeoffive#1#2#3\relax#4{#3}
\def\afterrelax#1\relax#2{#2}
\def\gobblepastrelax#1\relax#2{}

\begin{document}

Ideally, this should work on normal text, e.g. $\est{\lambda}$ should
expand to $\hat{\lambda}$. Also, $\L$ should expand to $L_i$, and $\est{\L}$
should expand to $\hat{L}_i$.
\end{document}

• Could you check out my edit? It seems your answer doesn't work in all cases. – Hameer Abbasi Feb 21 '18 at 14:52
• It might not be possible to make it general (I don't know) but I can say that the input will contain exactly one (possibly nested) zzfix, or it can fail-over to rendering it normally. – Hameer Abbasi Feb 21 '18 at 14:53
• @HameerAbbasi it needs to be the first token in the expansion (doing anything else while supporting the use like \lambda where it is not used at all would be much harder) as you have an optional argument the command \queueState expands to \protect\queueStatex and \queueStatex expands to \@ifnextchar[... so \zzfix is only seen after multiple expansions and multiple internal \def while testing if the next character is [. – David Carlisle Feb 22 '18 at 10:56
• @HameerAbbasi did you do as I suggest and test with \show\queueState what the definition of \queueState is after that command? – David Carlisle Feb 22 '18 at 11:21
• @HameerAbbasi yes as I explained above the optional argument means the expansion is different:-) not easily, although as I said initially testing with ifstrempty here makes little sense anyway – David Carlisle Feb 22 '18 at 12:33