# Feeding arguments to xstring macros

In Footnotes with automatic final period, the comment was made to provide the possibility to add a period . to a footnote conditionally, based on whether the footnote already has a period or not. I immediately thought xstring would solve this conditioning using \IfEndWith and attempted the following:

\documentclass{article}
\usepackage{xstring}% http://ctan.org/pkg/xstring
\makeatletter%
\long\def\@makefntext#1{%
\parindent 1em\noindent \hb@xt@ 1.8em{\hss\@makefnmark}#1\IfEndWith{#1}{.}{}{.}}
\makeatother
\begin{document}
Here is some text\footnote{This is a footnote}.
\end{document}


Here the footnote ends with the condition \IfEndWith{#1}{.}{}{.} to check whether #1 (the argument to \footnote) ends with .. If true, it does nothing, else it prints a .. This works without a hitch when you use \IfEndWith{xstring.}{.}{}{.}, but not here. TeX complains about an Undefined control sequence.

A related problem dealing with file extensions - How to make nonstopmode really not stop on a missing input file - was solved (or didn't complain like the above problem, yet it had a similar set up in terms of xstring) using:

\documentclass{article}
\usepackage{xstring}% http://ctan.org/pkg/xstring
\let\OldInputIfFileExists\InputIfFileExists
\renewcommand{\InputIfFileExists}[2]{%
\IfFileExists{#1}%
{\OldInputIfFileExists{#1}{#2}}%
{\IfEndWith{#1}{.tex}{\typeout{INPUT #1}}{\typeout{INPUT #1.tex}}}%
}
\begin{document}
This is dummy text.
\input{missing}% missing.tex is missing
\input{missing.tex}% missing.tex is missing
\end{document}


The idea in the above MWE (slightly modified from the original post) is to check whether a file to be \inputed exists or not, and write out some information to the .log file, appending the extension .tex as necessary. The selected output in the .log file after compiling the above should be

...
INPUT missing.tex
INPUT missing.tex
...


So, why does passing the argument #1 to \IfEndWith cause a problem in the former MWE, but not the latter?

Now, I do know that the xstring documentation clearly states:

[xstring] provides macros and tests operating on "strings of tokens" ... A "string of tokens" is a list of tokens of any nature, except that braces must be balanced and tokens catcode 6 and 14 (usualy % and #) are not allowed. Apart from this, any token is allowed, in any order in the list, whatever be the resulting code.

But why then does the second MWE compile without problem? I'm assuming a correction of my use would extend to all of the xstring macros.

-

As unbonpetit suggests, one problem is that \IfEndWith performs an \edef on its argument. However, the argument to \@makefntext is not the footnote text, but rather

\rule\z@\footnotesep\ignorespaces This is a footnote\@finalstrut\strutbox


so \IfEndWith will never succeed in finding a final dot. You have to do the check on the argument passed to \@footnotetext:

\documentclass{article}
\usepackage{xstring,etoolbox}
\makeatletter
\patchcmd{\@footnotetext}
{#1}
{#1\protect\IfEndWith{\detokenize{#1}}{.}{}{.}}
{}{}
\makeatother
\begin{document}
Here is some text\footnote{This is a footnote}.
Here is some text\footnote{This is a footnote.}.
\end{document}


However, this will fail if the footnote text ends with ! or ?.

The approach taken by AMS in amsthm is different and worthy of attention:

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
%%% taken from amsthm.sty
\relax\ifhmode
\ifnum\spacefactor>\@m \else#1\fi
\fi}
\def\nopunct{\spacefactor 1007 }
\def\frenchspacing{\sfcode\.1006\sfcode\?1005\sfcode\!1004%
\sfcode\:1003\sfcode\;1002\sfcode\,1001 }
%%% end of borrowed code
\patchcmd{\@footnotetext}
{#1}
{}{}
\makeatother

\begin{document}
Here is some text\footnote{This is a footnote}.
Here is some text\footnote{This is a footnote.}.
Here is some text\footnote{Is this a footnote?}.
Here is some text\footnote{This is a footnote without final period\nopunct}.
\end{document}


One can add \nopunct at the end of the footnote text in special cases when the final period is not desired (for instance, if the footnotes ends with \dots).

-

In your first MWE, xstring complians because it tries to expand #1 with an \edef and cannot because #1 is not "This is a footnote":

\documentclass{article}
\usepackage{xstring}% http://ctan.org/pkg/xstring
\makeatletter%
\long\def\@makefntext#1{%
\def\foo{#1}\show\foo}
\makeatother
\begin{document}
Here is some text\footnote{This is a footnote}.
\end{document}


As you see, #1 is "\rule \z@ \footnotesep \ignorespaces This is a footnote\@finalstrut \strutbox". Have a look at the \@footnotetext macro to see how it works.

For your second question, I am not sure that xstring is implied:

\documentclass{article}
\let\OldInputIfFileExists\InputIfFileExists
\renewcommand{\InputIfFileExists}[2]{%
\IfFileExists{#1}%
{\OldInputIfFileExists{#1}{#2}}%
{foobar}%
}
\begin{document}
This is dummy text.
\input{missing}% missing.tex is missing
\input{missing.tex}% missing.tex is missing
\end{document}


The behaviour is still the same. I'm sorry, I cannot search a solution, I have to go to work!

-
With e-TeX, it's usually easier to use \showtokens{#1} to see the argument, rather than do an assignment. – Joseph Wright Nov 4 '11 at 7:03