3

I'm using the LaTeX3 technique shown by cfr here to prepend a \color command to some paragraphs. In the par_end_hook I added \color{black} to reset the color after the paragraph is done. It all works fine for normal text, but when used in a list, it colors the list index of the next item as well, although the text "EndOfParHook" before it appears black (as it should).

Why is that?

PS: I'm not looking to color the list indices as well. For me it would be fine if the 2., the 3. and the 6. were simply black.

This is the result

And this is the code to produce the image shown above:

\documentclass{article}
\usepackage{xcolor,l3galley,xparse}

\ExplSyntaxOn
\tl_gput_right:Nn \g_galley_par_begin_hook_tl
{
  \color{\NextPartColor}
  \gdef\NextPartColor{black}
}
\tl_gput_left:Nn \g_galley_par_end_hook_tl
{
  \color{black}EndOfParHook
}
\ExplSyntaxOff

\def\NextPartColor{black}
\def\todoPar{\gdef\NextPartColor{red!70!black}}
\def\donePar{\gdef\NextPartColor{green!70!black}}

\begin{document}

\todoPar This works fine for normal paragraphs.

Everything black here, as it should.

\begin{enumerate}
    \item\todoPar Some todo item
    \item\donePar This one is green, but why is the 2 red?
    \item Nothing to do here, but the 3 is green!
    \item Another black one
    \todoPar\item Doesn't matter if we place it before or after the \verb|\item|.
    \item Last one
\end{enumerate}
\end{document}
Fritz
  • 6,273
  • 31
  • 55

1 Answers1

1

So, the problem is that the contents of \g_galley_par_end_hook_tl are placed in a group. This can easily be checked by adding \the\currentgrouplevel into \g_galley_par_end_hook_tl and in a normal paragraph (or item). Sadly, making color changes global (as in breaking out of a group) is really messy and driver-dependent in LaTeX. See How can I change the text color in such a way that the effect transcends groups? for the gory details.


However, I managed to solve the problem by modifying the \item macro to explicitly set the color to \NextParColor. That way, we don't even need \g_galley_par_end_hook_tl, because the color for the next paragraph is already reset to black at the beginning of the current paragraph.

As a bonus, this also allows us to color the list number itself:

Looks better now

\documentclass{article}
\usepackage{xcolor,l3galley,xparse}

\ExplSyntaxOn
\tl_gput_right:Nn \g_galley_par_begin_hook_tl
{
  \color{\NextPartColor}
  \gdef\NextPartColor{black}
}
\ExplSyntaxOff

\def\NextPartColor{black}
\def\todoPar{\gdef\NextPartColor{red!70!black}}
\def\donePar{\gdef\NextPartColor{green!70!black}}

%% Hack: Fix wrong-color item labels
\let\OldItem=\item
\def\item{\color{\NextPartColor}\OldItem}

\begin{document}

\todoPar This works fine for normal paragraphs.

Everything black here, as it should.

\begin{enumerate}
    \item\todoPar Some todo item
    \item\donePar This one is green, but why is the 2 red?
    \item This whole line is black. Yay.
    \todoPar\item Before \verb|\item|, it also colors the number.
    \item Last one, also black.
\end{enumerate}
\end{document}
Fritz
  • 6,273
  • 31
  • 55