I had some expl3 code which relied on \tl_upper_case:n to do some expandable case changing. However today I updated my TeX distribution and the code now throws an error:

! LaTeX3 Error: '\tl_upper_case:n' deprecated on 2022-01-01. Use
(LaTeX3)        '\text_uppercase:n '.

Type <return> to continue.

l.6 \tl_upper_case:n
                     { oh~no! }

In fact, all of:

\tl_<some>_case:n(n)    % <some> = (upper|lower|mixed)
\str_<some>_case:n      % <some> = (upper|lower|fold)
\char_<some>_case:N     % <some> = (upper|lower|mixed|fold)
\char_str_<some>_case:N % <some> = (upper|lower|mixed|fold)

raise similar errors. What happened?

  • “deprecated on 2022-01-01” Is your computer a time machine? ;-) – Speravir Jan 16 at 0:09
  • @Speravir It seems so. I was asked a similar question just a couple days ago ;-) – Phelype Oleinik Jan 16 at 0:14

As the error message says, the function \tl_upper_case:n are now deprecated and should be replaced by \text_uppercase:n. The full list is:

  • \tl_<some>_case:n(n)\text_<some>case:n, for lower, upper, and mixed case;
  • \str_<some>_case:n\str_<some>case:n, for lower, upper, and fold case;
  • \char_<some>_case:N\char_<some>case:N, for lower, upper, mixed, and fold case;
  • \char_str_<some>_case:N\char_str_<some>case:N, for lower, upper, mixed, and fold case.

In particular, <some>_case was replaced by <some>case, as a single word, mixed case was renamed to title case and, more importantly, the functions for dealing with general text input were removed from l3tl (token lists) to a more specific l3text module for general text manipulation tools.

You can read more about the text and string manipulation functions in the “The l3text package” part of the expl3 interfaces documentation or in this blog post, which contains a brief discussion of the main features of these functions, including language-dependent changes, with usage examples.

Until the mentioned update, the functions were (for four years or so) in the l3tl module as experimental features (thus subject to change), but they (the \tl_<some>_case:n ones) were not really suited for l3tl and there was the increasing need of a module for text manipulation. Now in the l3text module they are marked as stable, so there should be no further interface changes.

This move was the first step in a larger update to add other text manipulation tools to the LaTeX3 kernel. The base of these functions is the newly added \text_expand:n, which does as it advertises: it expands input text. This function is more or less equivalent to LaTeX2ε's \protected@edef, but it's powered by \expanded, so it's expandable!

More functions will be added to the new l3text module, for example \text_purify:n, which will be an expandable equivalent to hyperref's \pdfstringdef to generate valid PDF strings from user input.

| improve this answer | |
  • 2
    I'd say \text_expand:n is a bit like a combination of \expanded with \protected@edef ... – Joseph Wright Jan 15 at 11:45

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.