3

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?

youthdoo
  • 861

3 Answers3

4

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

enter image description here

\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}

David Carlisle
  • 757,742
4

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}

enter image description here

egreg
  • 1,121,712
  • What is \exp_args:Ne for? (I know its meaning, but why use such a function here?) – youthdoo Dec 26 '22 at 04:25
  • @youthdoo You want to fully expand the second argument to \str_if_eq:nnTF before this function does its job. – egreg Dec 26 '22 at 08:53
3

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.

enter image description here

% !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}

Mico
  • 506,678