2

I'm working on applying the answer to my question about color and ligatures and have run into a problem when the color change is supposed to happen inside a discretionary. Boiled down to a MWE and it looks like this:

\documentclass[12pt]{article} % use larger type; default would be 10pt

\usepackage{xcolor}
\usepackage{luacolor}
\definecolor{grebackgroundcolor}{RGB}{255,200,0}
\listfiles

\def\foobar#1#2{%
    \hbox to 0pt{%
        {\color{grebackgroundcolor}#2}%
    }%
    #1%
    \relax %
}%


\begin{document}

\noindent\foobar{test}{\rule[-2pt]{36pt}{12pt}}

\noindent\discretionary{}{}{\foobar{test}{\rule[-2pt]{36pt}{12pt}}}

\end{document}

If you compile the MWE, you'll see that the first instance of \foobar works fine, but in the second, the rule ends up being black instead of orange. Remove the loading of luacolor and both instances work fine. How do I change color such that the color change will happen inside a \discretionary when luacolor loaded?

  • This doesn't answer the question, but {\color{grebackgroundcolor}#2\hss} would probably be better inside \foobar to avoid an overfull \hbox (you don't even need the outer braces since \hbox defines a group). – frougon May 28 '19 at 22:17
  • The original context does have a \hss. It got stripped out during the reduction to MWE. – rpspringuel May 28 '19 at 22:26
  • 1
    @frougon better to have the group (or use \textcolor) otherwise the colour restore will be outside the box. – David Carlisle May 31 '19 at 11:37
  • @DavidCarlisle Thanks for the info... this sounds nasty. Can this color restoring do anything bad if #2 is the last remaining thing in the \hbox, once we have removed the extra group? – frougon May 31 '19 at 11:42
  • 1
    yes:-) it can trash the color stack – David Carlisle May 31 '19 at 11:44
  • @DavidCarlisle Arrrrrrgh, thanks so much for the warning, then! :-) – frougon May 31 '19 at 11:52
  • @DavidCarlisle Sorry to dredge this up, but I'm trying to determine if my code here does the right thing with respect to color handling when reading the pseudo mandatory argument of the choices environment (not an actual argument, because I want catcode-sensitive stuff to work there; color handling is in commands \ryanjform@startchoices@insidebox@hook and \ryanjform@startchoices@aftergroup@hook). It works with colored material even if I remove the extra \bgroup and \egroup I added because of your above comments. – frougon Jun 30 '19 at 09:52
  • @DavidCarlisle So, I fear I'm missing something. From these comments, I thought that the following MWE would cause problems, but I can't make it fail (I tried with pdfTeX, LuaTeX with and without luacolor). Can turn this into a new question if this is worthy. Many thanks! MWE: `\documentclass{article} \usepackage{xcolor}

    \begin{document}

    \color{red!50!black} This is a \hbox{\color{blue}foo} test.

    \end{document}`.

    – frougon Jun 30 '19 at 09:52
  • @frougon \hbox is OK, the color restore comes outside the box (via aftergroup) but that is OK, change \hbox{..} to \sbox0\hbox{...}\box0 and now you get the colour restore before the colour push and things go arbitrarily bad depending on where it is – David Carlisle Jun 30 '19 at 10:28
  • @DavidCarlisle I believe you meant \setbox instead of \sbox. With \setbox, I have the example I was looking for. :-) That's weird stuff indeed, thanks for pointing it out! If I understand correctly, inside \box0, there is a “push blue” instruction (\special) but no corresponding pop (unless additional braces are put inside the box), and this push lasts after the box when \box0 is used in the document. – frougon Jun 30 '19 at 10:41
  • 1
    @frougon yes sorry, it was me that put the extra group in sbox so I ought to know the difference:-) – David Carlisle Jun 30 '19 at 11:00

1 Answers1

2

The luacolor package hooks the macro \luacolorProcessBox to the shipout box in order to apply the lua color formatting. Apparently the \discretionary processing formats the content in a way that \luacolorProcessBox cannot handle from the shipout box. A possible solution is to apply the macro directly to the content inside of the \discretionary.

To do this the content must be stored in a box. The box can be processed by the macro and subsequently inserted into the document.

MWE:

\documentclass[12pt]{article} % use larger type; default would be 10pt

\usepackage{xcolor}
\usepackage{luacolor}
\definecolor{grebackgroundcolor}{RGB}{255,200,0}

\newsavebox{\temp}
\def\foobar#1#2{%
    \sbox{\temp}{\hbox to 0pt{%
        {\color{grebackgroundcolor}#2}%
    }%
    #1%
    \relax}%
    \luacolorProcessBox\temp%
    \usebox{\temp}%
}%

\begin{document}

\noindent\foobar{test}{\rule[-2pt]{36pt}{12pt}}

\noindent\discretionary{}{}{\foobar{test}{\rule[-2pt]{36pt}{12pt}}}

\end{document}

Result:

enter image description here

Note: there may be side effects to the box manipulation, check the results carefully for any undesired issues.

Marijn
  • 37,699
  • I found one side effect. If the colored text is the last thing in the box, then the color will leak out of the box and adding extra groups inside the box or around the \usebox doesn't help. Ending the box with \relax also doesn't help. The only thing I found that works was to end the box with \rule{0pt}{0pt} (outside the color group). – rpspringuel May 30 '19 at 13:30
  • @rpspringuel maybe save the previous color at the start and restore it at the end of the box, as in https://tex.stackexchange.com/questions/218090/how-to-save-the-current-colour? – Marijn May 30 '19 at 13:40
  • First off it seems that \colorlet doesn't like being inside a \discretionary. Even when I manage to work around that problem (which I can do in the MWE, not sure if it'll be possible in context), however, a tailing \color{saved} command doesn't appear to have any effect. It appears to need something which at least nominally prints to act upon inside the box. In which case, it's no better than the \rule trick I'm already using. – rpspringuel May 30 '19 at 13:54