# Gobble every occurrence of \mypath../

Is there a neat way to remove all instances of the text \mypath../ from the input, using TeX's text processing capabilities? The ifthen approach below works, but seems to be a bit heavyweight. Also, I'm looking for a solution that would work before the \documentclass command:

\documentclass{scrartcl}
\usepackage{ifthen}

\newcommand{\mypath}[3]{%
\ifthenelse{\equal{#1#2#3}{../}}{}{#1#2#3}%
}

\begin{document}
Gobble: \mypath../

Don't gobble: \mypath.ab
\end{document}

-

Here's an expandable way:

\long\def\mypath#1#2#3{\mypathaux../#1#2#3../}
\long\def\mypathaux../#1../{%
\if\relax\detokenize{#1}\relax
\expandafter\mypathgobble
\else
#1
\fi}
\long\def\mypathgobble#1#2#3{}


The macro \mypath absorbes the next three tokens and calls \mypathaux in a curious way; let's see the two main cases:

1. \mypath../ becomes \mypathaux../../../

2. \mypath xyz becomes \mypathaux../xyz../

The macro \mypathaux has only one argument, all tokens that go from the first occurrence of ../ to the second occurrence. In case 1 there's nothing between the two occurrences, so #1 is empty. In case 2, #1 is xyz.

The macro now tests whether #1 is empty (it's a slick trick by H. Oberdiek); if it is, it calls \mypathgobble that swallows the ../ that remain on the main token list; otherwise it just returns #1.

A similar way that gets rid also of the \fi after #1, which might be needed in some situations is

\makeatletter
\newcommand\mypath[3]{\@mypath../#1#2#3../}
\long\def\@mypath../#1../{%
\if\relax\detokenize{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi\@gobblethree{#1}}
\providecommand\@gobblethree[3]{}
\makeatother


This uses features from the LaTeX kernel, while the former macros don't.

Let's see the two cases. With \mypath xyz we get

\@mypath../xyz../


and the test returns false, so we're left with

\expandafter\@secondoftwo\fi\@gobblethree{xyz}


where \expandafter acts on \fi (it simply disappears), leaving

\@secondoftwo\@gobblethree{xyz}


so \@secondoftwo finally produces xyz. In the case of \mypath../ we get

\@mypath../../../


and the test returns true; this leaves

\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi\@gobblethree{}../


(only the first two ../ disappear as part of the pattern matching). The first \expandafter acts on \else which causes everything up to the matching \fi to disappear:

\@firstoftwo\@gobblethree{}../


and now we get

\@gobblethree../


which leaves nothing.

-
Thank you for your edits. Still, I wonder what happens to the third ../ in \mypath../--> \@mypath../../../ after it has been matched to \@mypath../../ with #1 empty. –  krlmlr Sep 11 '12 at 4:49
@user946850 In the case you mention, the first pair of ../ disappears as part of the action of \@mypath and the third because \@gobblethree is called. I'll add something. –  egreg Sep 11 '12 at 7:37
That makes it perfectly clear. Here's the link to the question/answer that explains \expandafter: tex.stackexchange.com/q/451/8057 –  krlmlr Sep 11 '12 at 11:41