Xstring package bug?

Why is resultin equal to $\frac{1}{2}$ (tokenized)? Shouldn't result and resultin be equal?

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xstring}

\def\halo{%

\verbtocs{\resultin} | \frac{1}{2} |
( result in function : \resultin )\\
}

\begin{document}

\halo
\verbtocs{\result} | \frac{1}{2} |
( result : \result )\\

\end{document}


• A character becomes a token the moment TeX sees it for the first time, and that doesn't (usually) change. When you made the definition of \halo, \verb{1}{2} got tokenized as \verb { 1 } { 2 }, and that was "frozen", so \resultin contains 7 tokens (\verb, {...) and \result contains 11 tokens (\, v, e...). That's the classical verb-command-in-argument issue :-) – Phelype Oleinik Aug 22 '19 at 18:15
• @PhelypeOleinik It's actually its less famous verb-command-in-macro-definition cousin :-P – siracusa Aug 22 '19 at 18:26
• @CarolLypher Certainly there are, but they all depend on what you are actually trying to do. For this simple case, one easy way out is to load the cprotect package and then do \cprotect{\def\halo}{\verbtocs|blablabla|}. – Phelype Oleinik Aug 22 '19 at 19:23
• No “verbatim” command can go in the argument to another command; there are workarounds, such as cprotect, but you should explain what's your aim. – egreg Aug 22 '19 at 19:43
• apart from the verb issue, never use \\  at the end of a paragraph (latex does warn about that) – David Carlisle Aug 22 '19 at 20:31

Another simple way, beside the suggestions in the comments, is to use the e-TeX primitive \scantokens around the verbatim code in your macro defintion:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xstring}

\def\halo{%
\scantokens{%
\verbtocs{\resultin} | \frac{1}{2} |
( result in function : \resultin )
}%
}

\begin{document}

\halo

\verbtocs{\result} | \frac{1}{2} |
( result : \result )

\end{document}


outputs

\scantokens{...} will process the code of its argument as if it was written to an external file and immediately read back from that file via \input. All catcodes, even the ones fixed after the macro body of \halo had been read, will be reassigned under the catcode regime active at the time \scantokens is executed.

EDIT: As pointed out in the comments, this method has some limitations on the text that can be used as verbatim material. You must be aware that TeX first scans the whole macro definition under the normal catcode regime and later reconsiders everything it had successfully parsed ealier. This for example explains the extra space in the output after \frac, because TeX had already tokenized it as macro name, which then got an extra space added after it in the \scantokens process.

• Note, however, that the output isn't identical: the one with \scantokens contains a space-after-csname after \frac. The \scantokens version also can't have a % character, all # must be doubled, and all { and } must be balanced, and multiple sequential space (catcode 10) tokens are tokenized as a single space token. It's not prohibitive, but are the downside of using a verbatim command in an argument. There's not much to be done, really. This is not a criticism to the answer, just things to have in mind when using a verbatim macro in an argument. – Phelype Oleinik Aug 24 '19 at 23:36
• @PhelypeOleinik Good point, I didn't even notice the extra space. – siracusa Aug 25 '19 at 0:41