The function \str_count_spaces:n{} should count the number of spaces in its parameter.

For me it outputted unexpected results.

\str_count_spaces:n{he llo} %->0

However these were okay,

\str_count_spaces:n{he\ llo} %->1
\str_count_spaces:n{he~llo} %->1
\str_count_spaces:n{he\char{32}llo} %->1

Did I misunderstand the definition of this function?

  • 1
    In expl3 syntax a usual space is not a space token but ignored. So usual spaces are only counted, if the argument is not read in expl3 catcode context. See also tex.stackexchange.com/q/132030/277964
    – cabohah
    Dec 23, 2022 at 12:48

2 Answers 2


Yes, you misunderstood the concept of strings in expl3.

A TeX string (and thus an expl3 string) is a series of characters which have category code 12 (“other”) with the exception of space characters which have category code 10 (“space”). Thus at a technical level, a TeX string is a token list with the appropriate category codes. In this documentation, these are simply referred to as strings.

There's a problem: to understand what this means you need to understand what "token" in TeX means, which ultimately boils down to reading TeXbook etc.... (resources)

Anyway, so \char or \ are not character tokens, but all the str function converts its arguments to string. You can view what the string will be with \str_show:n:


\str_show:n{he\ llo}



he\ llo
he llo
he\char {32}llo

Because of how \detokenize primitive works in eTeX (the behavior is inherited from whatever function used to implement converting token list to string in TeX source code, in expl3 documentation it's mentioned that the conversion is done with \tl_to_str:n where the description of \detokenize is copied there) a space is added after \char, which has nothing to do with the fact that the number is 32 and it typesets a space when run normally.

  • In retrospect, as a formal language description expl3 documentation abstracts away the TeX details reasonably well, but it doesn't do a good job at teaching the language and leave the readers in the dark on why some commands' behavior (e.g. f-type expansion) are highly counterintuitive (answer: they're inherited from the corresponding TeX primitives which there's no (or no efficient) way to abstract it out) (not to complain, it's difficult.)
    – user202729
    Dec 23, 2022 at 16:36
  • interface3 is intended as a reference, we don't yet have 'Programming in expl3' (and would be very happy to have a volunteer to write it!)
    – Joseph Wright
    Dec 23, 2022 at 16:40

Within \ExplSyntaxOn and \ExplSyntaxOff all spaces are ignored.

To insert an explicit space use ~ (which as you note works).

You can create a LaTeX command that wraps the expl3 macro to count spaces in a non-strange way outside of of the Expl3 programming environment:

\NewDocumentCommand \CountSpaces { m }
    \str_count_spaces:n { #1 }
\CountSpaces{he llo} % -> 1
  • So would \str_if_eq:nnTF{~}{#1}{yes}{no} be correct in a function judging whether its parameter is a space? I'm going to use it after \ExplSyntaxOff.
    – youthdoo
    Dec 23, 2022 at 13:58
  • @youthdoo If the "function" that uses \str_if_eq:nnTF and ~ is defined with ExplSyntax On, ~ is a space and is equal to a literal space on the user-level. (Outside ExplSyntax ~ is an unbreakable space which is not the same as a space.) Dec 23, 2022 at 16:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .