2

Why does this code output "False":

\documentclass{article}
\usepackage{stringstrings}
\usepackage{xifthen}

\begin{document}
\ifthenelse{\equal{\substring{ab}{1}{1}}{a}}{True}{False}
\end{document}

There are many alternative solutions to get the desired result: Test if the first character of a string is 'a', but I would like tho understand why the above code behaves this way and what would be the closest possible solution to get the desired behavior.

  • 1
    \equal tests the expansion of the two expressions are equal and the stringstrings functions are not expandable they make many internal assignments – David Carlisle Jul 28 '20 at 19:46
2

The macro \substring does not work by pure expansion: it produces a (long) series of commands to print the requested substring.

With [q] you can make it save the result in \thestring. Well, it always does, but [q] suppresses output at the calling spot.

\documentclass{article}
\usepackage{stringstrings}
\usepackage{xifthen}

\begin{document}
\substring[q]{ab}{1}{1}
\ifthenelse{\equal{\thestring}{a}}{True}{False}
\end{document}

This will print “True”.

I'd prefer the more powerful expl3 routine:

\documentclass{article}
\usepackage{xparse}
\usepackage{xifthen}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\substring}{mmm}
 {
  \tl_range:nnn { #1 } { #2 } { #3 }
 }
\ExplSyntaxOff

\begin{document}

\ifthenelse{\equal{\substring{ab}{1}{1}}{a}}{True}{False}

\ifthenelse{\equal{\substring{abcde}{-2}{-1}}{de}}{True}{False}

\end{document}

You see that you can also extract substrings from the end. See also https://tex.stackexchange.com/a/467527/4427 for a reimplementation of \ifthenelse with expl3.

0

If you're free to use LuaLaTeX, consider using Lua's powerful string functions, including string.sub (short for "string subset", I suppose).

For instance, the following program defines a LaTeX macro called \TestFirstChar. \TestFirstChar{ab}{a} typesets "True".

\documentclass{article}
\newcommand\TestFirstChar[2]{%
    \directlua{if (string.sub("#1",1,1)=="#2") then tex.sprint("True")
               else tex.sprint("False") 
               end}}

\begin{document}
\TestFirstChar{ab}{a}
\end{document}

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.