I'm trying to get to grips with how to do basic string manipulation using expl3. Here's what I have so far:



    \str_set_eq:NN \l_tmpa_str \str_uppercase:n{hello}




I don't get an error when I compile with latexmk -jobname=test -lualatex .\uppercasing_strings.tex, but the content of the resulting pdf is not what I expect:

enter image description here

Furthermore, if I try str_show:N \l_tmpa_str I get an error:

LaTeX3 Error: Variable '\l_tmpa_str' is not a valid str.

What am I doing wrong? How can I output the value of \l_tmpa_str to both the terminal and my pdf?



MWE bracing argument as per comments



    \str_set:Nx {\l_tmpa_str} {\str_uppercase:n {hello}}

    \str_show:N \l_tmpa_str



Error message

Running 'lualatex  -recorder --jobname="test"  "./uppercasing_strings.tex"'
This is LuaHBTeX, Version 1.15.0 (TeX Live 2022)
 restricted system commands enabled.
LaTeX2e <2021-11-15> patch level 1
 L3 programming layer <2022-04-10>
Document Class: article 2021/10/04 v1.4n Standard LaTeX document class
(./test.aux) (c:/texlive/2022/texmf-dist/tex/latex/base/ts1cmr.fd)
> \l_tmpa_str=HELLO.
<recently read> }

l.9     \str_show:N \l_tmpa_str


2 Answers 2


Function names in expl3 follow quite a strict pattern. They should start with either \<module> or with \__<module> (for public and private functions, respectively), where <module> is a string of letters that “emulate” a namespace in order to reduce the possibility of name conflicts between different packages.

After the first part, something that describes the working of the function follows. In \str_set_eq:NN the module is str (string manipulations) and the descriptive part is _set_eq.

After the “proper name”, a colon and the signature follow. This signature specifies the number of arguments the function operates on and possibly some preprocessing done to them. Exception: if the signature ends with w, the number of arguments is not specified and one has to look at the documentation to see what's the expected syntax for the function.

The argument types N and n are the most common. The former means that the argument must be an unbraced single token, the latter means that the argument must be a braced list of tokens.

In the case of \str_set_eq:NN, the signature tells you that the function expects two arguments, which should be single tokens. Therefore in

\str_set_eq:NN \l_tmpa_str \str_uppercase:n { hello }

one can immediately spot a syntax error even without knowing what \str_set_eq:NN is about, because this function will operate on \l_tmpa_str and on \str_uppercase:n.

What does \str_set_eq:NN do? It sets the first token, which should be a str variable, to have the same current value of the second token, which should be a str variable as well.

There are similar functions for all other types of variables.

In your case you don't want to set \l_tmpa_str to the value of another str variable, but to a value you are stating at that point. So what you need is


or a variant thereof. If you do

\str_set:Nn \l_tmpa_str { hello }

you're setting the variable to have the specified value. But in your case you want to “preprocess” the string given as argument, in order to pass it uppercased. OK, we can use the variant

\str_set:Nx \l_tmpa_str { \str_uppercase:n { hello } }

where the argument type x means that the argument should again be a braced list of tokens, but it will be full expanded before being passed to the main function. Thus this call will be the same as

\str_set:Nn \l_tmpa_str { HELLO }

In interface3.pdf you see \str_set:Nx listed in the predefined variants of \str_set:Nn

enter image description here

but if you need some variant you can generate it yourself by

\cs_generate_variant:Nn \str_set:Nn { Nx }

(adapt this to the needed case).

Let's see what the manual says about \str_set_eq:NN

enter image description here

This underlines that the arguments should both be str variables.

There's another caveat. Does \str_uppercase:n work in an x argument? Yes, because in the documentation we see

enter image description here

and the ⋆ means that the function will work in full expansion contexts.

Note that, contrary to some given advice, the first argument to \str_set:Nn should not be braced. To be honest, the braces do no harm, as far as TeX is concerned, but they make the coding inconsistent. Arguments of type N or V should never be braced; all others should.

  • Thanks for a very informative response. This answer is clearly superior and I would upvote it more if I could. I don't like to switch accepted answers though, so I hope you don't mind me keeping the initial accepted answer.
    – user32882
    Commented Apr 23, 2022 at 9:31
  • @user32882 I would recommend that you go ahead and switch the accepted answer, if you believe it would be helpful for others to see it first.
    – Davislor
    Commented Apr 23, 2022 at 14:00
  • @user32882 You can, in fact, upvote an answer more than once, by awarding a bounty.
    – Davislor
    Commented Apr 23, 2022 at 14:00

In the initial example the code that will be executed is...

\str_set_eq:NN \l_tmpa_str \str_uppercase:n

which is wrong, because \str_uppercase:n is not a ⟨str var⟩.

Instead, you want

\str_set:Nx \l_tmpa_str {\str_uppercase:n {hello}}

to set \l_tmpa_str to the expanded value of \str_uppercase:n {hello}.

Regarding the edit, note that the show commands will pause the compilation, you can e.g. press enter to continue. See Using \show in nonstopmode causes TeXmaker to raise false alarms. Any fix? for more details.

  • 1
    It's not a full answer. Please include a detailed explanation of why \str_show freezes the output.
    – user32882
    Commented Apr 23, 2022 at 5:39
  • @user32882 It wasn't in the original question though (only in the edit) but okay
    – user202729
    Commented Apr 23, 2022 at 5:40
  • \str_show was part of my original code, and as a question poster if I implement this solution I would still be kept wondering why my code isn't compiling all the way.
    – user32882
    Commented Apr 23, 2022 at 5:41
  • Actually, you're right that \str_show wasn't in my original question. But anyway, it's nice to have it in the answer for future reference. Thanks!
    – user32882
    Commented Apr 23, 2022 at 5:46
  • 2
    a minor nitpick: N arguments should not be braced. \str_set:Nx \l_tmpa_str {...}
    – cgnieder
    Commented Apr 23, 2022 at 8:06

You must log in to answer this question.

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