I'm trying to colorize diagnostic outputs to the console in order to make my stuff more visible in the endless stream of messages that LaTeX spits out.


However, all of my efforts like, for example

\typeout{^^1b[38;05;54m Indigo!} % Text line contains an invalid character.
\typeout{\char"001B[38;05;54m Indigo!} % \char "001B[38;05;54m Indigo!

seem to get subverted by TeX either not expanding certain commands within \typeout or claiming that there were illegal characters.


Is there a trick that would make this work?


There are two issues:

  • LaTeX has assigned catcode 15 for character ^^1b (decimal 27). The use of ^^1b triggers then the error message:

    ! Text line contains an invalid character.

    Thus the catcode for the character needs to be changed (see the example below).

  • TeX usually prints control characters with the ^^-notation. TeX compilers can have command line options to change this behavior:

    • TeX Live: -8bit or -translate-file=natural
    • MikTeX: --tcx=natural

The following example file defines \CSI as shortcut for ^^1b[.



\typeout{\CSI38;05;54mIndigo! \CSI1mBold\CSI22m \CSI4mUnderlined\CSI0m}
\typeout{\CSI37m\CSI41m\CSI1mBold white on red\CSI0m}



  • 1
    just tried it, using xelatex -8bit ... and it did work! that's great! i had tried some catcode mangling, as that is an obvious bit, but had missed out on the -8bit switch. i'm also not bold enough a TeX writer to try and have a \begingroup ... \endgroup overlap with a pair of braces... oh me oh my, is that even legal?—i'll immortalize this piece of code in a new module for github.com/loveencounterflow/cxltx-styles!
    – flow
    Mar 30 '14 at 12:28
  • @flow: \@firstofone just reads and outputs its argument unchanged. The idea is that the argument including ^^1b is read with the catcode setting that is active in the group. Then the catcode of the character token ^^1b will not change, after the group is closed by \endgroup. Mar 30 '14 at 12:33
  • 1
    this is truly ingenious. i'd never thought that this construct could be valid in any language. i mean, <div>x<span>y</div>z</span> isn't valid HTML and d[ ( x ] + 4 ) isn't valid JavaScript / Python / whatever, and for good reasons. it's baffling to see how much TeX works on a, as it were, "eat one token, chomp one token" base, how those braces are really more like implementation details of each individual macro rather than imposed by a global syntax (eg textpos: in \begin{textblock*}{10mm}[0,0.5](20mm,30mm) all the different arguments have different parens).
    – flow
    Mar 30 '14 at 13:11

one way i've found involves using \write18. i created a bash script:

#!/usr/bin/env bash
echo -e "\x1b$*\x1b[0m"

and then in my TeX i do

\immediate\write18{esc "[38;05;54mhelo Indigo"}

in other words, i 'outsourced' printing the problematic \x1b escape character. now i wonder whether there's a solution that does not include an external script.

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.