# How to change color inside \discretionary with luacolor?

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 at 22:17
• The original context does have a \hss. It got stripped out during the reduction to MWE. – rpspringuel May 28 at 22:26
• @frougon better to have the group (or use \textcolor) otherwise the colour restore will be outside the box. – David Carlisle May 31 at 11:37
• yes:-) it can trash the color stack – David Carlisle May 31 at 11:44
• @frougon yes sorry, it was me that put the extra group in sbox so I ought to know the difference:-) – David Carlisle Jun 30 at 11:00

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:

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

• 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 at 13:30
• @rpspringuel maybe save the previous color at the start and restore it at the end of the box, as in tex.stackexchange.com/questions/218090/…? – Marijn May 30 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 at 13:54