I have the following MWE which prints the catcode of every character in the list.

The input method is:


but I want to simplify as follows:


Here the MWE:


\cs_new:Npn \catcode_print:n #1 
  The~catcode~of~\tl_to_str:n {#1}~is~\char_value_catcode:n {#1} \par
\NewDocumentCommand { \MyList }
 { > { \SplitList { , } } m }
 { \ProcessList {#1} { \catcode_print:n } }
% \MyList{+,{,},\%,a}

EDIT and PS: I want to inverse the number to get the corresponding character: For example: \tex_number:D A prints 65. But I want to insert 65 and with the result A

  • 3
    Use \char_value_catcode:n { `#1 } instead of \char_value_catcode:n { #1 }. Feb 9, 2012 at 18:36
  • @BrunoLeFloch: This was to simple ;-). Do you know a way how to inverse \tex_number:D A. This will print 65. But I want to insert 65` and want to get A. (LaTeX3 solution isn't deprecated ;-) ). Please provide an answer. Feb 9, 2012 at 18:40

1 Answer 1


Not expandably, of course:



will give


But of course


does the same. The \achar technique can be useful if you want to define a macro to expand to the character given by number (with category code 12):


\show\firstA \show\secondA \show\thirdA

What does \achar do? It starts a group where the lowercase correspondent of the exclamation character is set to character #2 (which is supposed to be a number, in any of the formats TeX allows for specifying an integer constant). This correspondance is maintained by an array (a 256 component vector, in 8 bit TeX, the whole 0x110000 of Unicode for XeTeX and LuaTeX, from 0x0000 to 0x10FFFF): the n-th entry specifies the lowercase correspondent for character number n.

When we say \lowercase{<tokens>}, TeX performs the substitution of each character token with its lowercase correspondent and then inserts back in the input stream the token list so obtained, to be read again. In our case \endgroup, \def and the first argument to \achar are not touched, as they are not character tokens, so only ! is converted, exactly to the character having the number we specified in the second argument. Notice that TeX still hasn't executed \endgroup: it does only when the token list is put back. So the group is closed, the \lccode assignment is forgotten and the \def is executed.

With \achar\firstA{65}, for example, the replacement text for \firstA is A with category code 12, because ! has category code 12 and \lowercase doesn't change this attribute.

The LaTeX3 code is just the same:

\NewDocumentCommand { \achar } { m m }
    \char_set_lccode:nn { `! } { #2 }
    \tl_to_lowercase:n { \group_end: \cs_new:Npn #1 { ! } }
  • GREAT! (as always ;-) ) Do you know the LaTeX3 source too? Feb 9, 2012 at 19:03
  • Incidentally, the experimental module l3str introduces for internal purposes 256 constant token lists holding each of the bytes: for character codes less than 256, you can access the corresponding character expandably. Feb 9, 2012 at 22:20
  • Will you add also the missing 1113856 for Unicode? :)
    – egreg
    Feb 9, 2012 at 22:25
  • @egreg better a late reply than none: no, I won't add ones for Unicode. The 256 bytes are useful for all engines when converting from an encoding to another (e.g., UTF-16 for some pdf strings). Dec 30, 2012 at 0:31

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.