I have a command defined as
\newcommand{\testspace}[1]{\str_if_eq:nnTF{~}{#1}{yes}{no}}
Now \testspace{ } is yes and \testspace{s} is no. However,
\testspace{\str_item:nn{s }{2}} %->no
How to explain this? How to make it output yes?
You provided no example code but in
\testspace{\str_item:nn{s }{2}} %->no
If you are in an expl3 region space is ignored so that is
\testspace{\str_item:nn{s}{2}} %->no
If you are in the document
\testspace{\str_item:nn{s }{2}} %->no
will give an error that \str is not defined followed by missing $ error as _ must be in math mode
\documentclass{article}
\ExplSyntaxOn
\cs_generate_variant:Nn\str_if_eq:nnTF{neTF}
\newcommand{\testspace}[1]{\str_if_eq:neTF{~}{#1}{yes}{no}}
\ExplSyntaxOff
\begin{document}
Now \testspace{ } is yes and \testspace{s} is no. However,
\ExplSyntaxOn
\testspace{\str_item:nn{s ~ }{2}} %->no
\ExplSyntaxOff
\end{document}
It depends on where you are.
If \ExplSyntaxOn is in effect, then \str_item:nn{s }{2} returns nothing, because spaces are ignored. On the other hand, \str_item:nn{s~}{2} would return a space token.
If you want to have the test usable in “user space”, define as follows:
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\testspaceTF}{ommm}
{
\IfNoValueTF{#1}
{% no optional argument, test the whole string
\str_if_eq:nnTF { #2 } { ~ } { #3 } { #4 }
}
{% optional argument to test a single item in the string
\exp_args:Ne \str_if_eq:nnTF { \str_item:nn { #2 } { #1 } } { ~ } { #3 } { #4 }
}
}
\ExplSyntaxOff
\begin{document}
\testspaceTF{s}{yes}{no} (should print no)
\testspaceTF{ }{yes}{no} (should print yes)
\testspaceTF[2]{s }{yes}{no} (should print yes)
\testspaceTF[1]{s }{yes}{no} (should print no)
% check expandability
\edef\test{\testspaceTF[2]{s }{yes}{no}}
\texttt{\meaning\test}
\end{document}
If you're willing and able to compile your document with LuaLaTeX, you could employ Lua's string.find function to test for the presence of whitespace in a string.
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for \luaexec and \luastring macros
\newcommand\testspace[1]{\luaexec{%
if string.find ( \luastring{#1} , "\%s" ) then tex.sprint ( "yes" )
else tex.sprint ( "no" ) end }}
\newcommand\foo{s }
\begin{document}
\testspace{ } \testspace{s} \testspace{s } \testspace{\foo}
\end{document}
\exp_args:Nefor? (I know its meaning, but why use such a function here?) – youthdoo Dec 26 '22 at 04:25\str_if_eq:nnTFbefore this function does its job. – egreg Dec 26 '22 at 08:53