Jonathan Kew - 2021-05-17

I think this is a problem at the macro level rather than in the xetex engine itself. As far as I can see, each \color{...} command here expands into a \special{color push ...} in the output, so that the output driver pushes a new color onto its stack; but the colors are never popped from the stack, and eventually it reaches its maximum size (looks like 128 entries).

If you put each usage of \color{....} <text> inside a group, by surrounding it with { ... } braces, the problem goes away because the color stack gets popped at the end of the group.

According to the color package documentation the expected behavior of \color is that it "will stay in effect until the end of the current TeX group". It seems the implementation of this relies on a color stack in the output driver, and that stack has a limited depth. These are implementation details that could perhaps be improved (as far as I can see, at the macro level, there's no point in pushing all the colors onto the stack; only the color in effect at the beginning of the group needs to be saved so that it can be restored at the end; and the output driver's color stack could be made dynamic rather than fixed-depth).

These issues would be best reported somewhere like the TeX Live mailing list, I think, as they're not bugs in the xetex engine itself. As for the original problem, probably the easiest workaround is to ensure that each colored fragment of output is appropriately grouped, to avoid continually pushing new stack entries.