latex3/xcolor

Missing character messages with TikZ

Closed this issue · 11 comments

When mixing the current color . in TikZ environment produces messages such as these

Missing character: There is no ! in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 0 in font nullfont!

in the log. When warnings are treated as errors, e.g., using latexmk -Werror, the above output will prevent the document to successfully compile.

I previously submitted the issue to the pgf bug tracker. However, it was quickly closed claiming the bug is caused by xcolor.

Minimal working example (MWE)

\documentclass[tikz]{standalone}

\begin{document}
\begin{tikzpicture}
  \draw[.!50] (0,0) -- (1,0);
\end{tikzpicture}
\end{document}

then inspect the log.

The pgf people are right, the following code typesets !50 incorrectly.

\documentclass{article}
\usepackage{xcolor}
\begin{document}
\colorlet{foo}{.!50}
\end{document}

@blefloch I just sent exactly the same example in the pgf issue ;-).

The \if-test is \XC@info is clearly faulty, as it compares \if..!50, but I'm not quite sure yet what the test is actually supposed to do.

I was almost ready to say this is not supported syntax because it is not documented anywhere. However, "Figure 7: Current color" of xcolor.pdf includes \textcolor{.!50}{50\%} as an example.

I agree the \XC@info test is faulty. It is meant to detect the type of color and produce a number (0 for ., 1 for names like red, 2 or 3 for certain expressions). However it seems the number is almost not used: only the case where it is 1 is used in the code that calls \XC@info. Of course we cannot rely on that because other packages might use \XC@info. I think the least invasive change is to replace the test by a corrected one, presumably tested after filtering out the cases of complicated expressions:

\def\XC@info#1#2%
 {\XC@edef#2{#1}%
  \expandafter\in@\expandafter>\expandafter{#2}%
  \ifin@\def#2{4}\else\expandafter\in@\expandafter:\expandafter{#2}%
  \ifin@\def#2{3}\else\expandafter\in@\expandafter!\expandafter{#2}%
  \ifin@\def#2{2}\else % now there's no >,:,!
  \if-\expandafter\@car#2\@nil\def#2{2}\else % catches -red
  \edef#2{\noexpand\in@{/./}{/#2/}}#2%
  \edef#2{\ifin@0\else1\fi}\fi\fi\fi\fi}

where I used \@car rather than the previous method to determine if the expression starts with -, and I applied that previous method to test for an argument being exactly .. Hopefully I got the number of closing \fi right. Can we please use expl3 when rewriting such pieces of LaTeX2e code?

Can we please use expl3 when rewriting such pieces of LaTeX2e code?

we can, but we have inherited this package a few weeks ago, it wasn't written by any of us.

@blefloch I just tried your code on a complicated plot and all the null font messages are gone ;-)

Can we please use expl3 when rewriting such pieces of LaTeX2e code?

I would have not problems with

\ExplSyntaxOn
\cs_new_protected:Npn \XC@info ....

\ExplSyntaxOff

@blefloch no objection to your code but are there cases other than the test for . that required the other re-arrangements?
a smaller change just fixing the \if. test might be

\def\XC@info#1#2%
 {\XC@edef#2{#1}%
  \if.\expandafter\@car#2\relax\@nil\def#2{0}\else\expandafter\in@\expandafter>\expandafter{#2}%
  \ifin@\def#2{4}\else\expandafter\in@\expandafter:\expandafter{#2}%
  \ifin@\def#2{3}\else\expandafter\in@\expandafter!\expandafter{#2}%
  \ifin@\def#2{2}\else\edef#2{\noexpand\in@{/-}{/#2}}#2%
  \edef#2{\ifin@2\else1\fi}\fi\fi\fi\fi}

down the line we probably want bigger changes (and in color) to interface better with l3color but keeping changes small (and in 2e style) until we are ready for that seem desirable to me at least.

The reason was that your code yields 0 for an expression such as .!50!red contrarily to the intent of that command, which seems to be to give larger numbers for more complicated expressions. On the other hand \XC@info is only used in one place where the only value that is singled out is 1, so it doesn't actually matter. I'll let you pick whichever code you like best.

@blefloch oh of course yes I had that in mind at the start and then completely forgot:-) I wasn't sure what you meant by "presumably tested after filtering out the cases of complicated expressions:" do you mean that the code as posted needs a filter adding or were you describing the code as written?

Yes, sorry, I wrote "presumably tested after filtering out the cases of complicated expressions:" then I figured it wasn't so trivial to write the code and I ended up writing the code. So yest, it's just a description of the code I wrote.

This has been resolved in xcolor 2021/10/31 v2.13 and uploaded to ctan.