pgf icon indicating copy to clipboard operation
pgf copied to clipboard

xxcolor interfering with listings prebreak

Open EagleoutIce opened this issue 3 years ago • 1 comments

Brief outline of the bug

When using the xxcolor package, i can no longer use colors within listings prebreak (triggered by \lst@CalcLostSpaceAndOutput). Commenting out the line \usepackage{xxcolor} makes the MWE compile on my machine. With the package, i get the following error message (I've set \errorcontextlines9999):

Error Message
./example.tex:11: Missing number, treated as zero.
<to be read again> 
                   \kern 
<argument> \kern 
                 \lst@width 0
\XC@c@lcR #1.#2.#3:->\ifnum #1
                              0>0 1.00000\else 0.\ifnum #11<0 00000\else \XC...

\XC@calcR ...edef #2{\expandafter \XC@c@lcR #2.0.:
                                                  }
\@@cmd #1#2->\XC@calcR {#1}#2
                             \edef #2{\expandafter \XC@c@lcN #200000:}
\XC@calc@ ... \@@cmd {XC@calc#6}\@@cmd {#1}\@@tmp 
                                                  \ifx ,#2,\else \@@cmd {#2}...
<inserted text> ...ndafter \XC@calc@ \@@clr ,,,,:N
                                                  \let \@@clr \@@tmp 
\XC@ifxcase ...\XC@if@ #2#1{#3}\@nnil \the \toks@ 
                                                  
<argument> ...clr \fi \XC@coremodel \@@mod \@@clr 
                                                  \csname color@\@@mod \expa...

\@secondoftwo #1#2->#2
                      
\XC@definec@lor ...oks@ }{\@@mod }{\@@clr }}}\fi }
                                                  \expandafter \endgroup \@@...

\XC@col@rlet ...\fi \expandafter \endgroup \@@tmp 
                                                  \xglobal@stop 
\XC@mcolor ...nummixins >0\colorlet {XC@mixtmp}{.}
                                                  \applycolormixins {XC@mixt...

\XC@display ...lor '}\endgroup \fi \fi \XC@mcolor 
                                                  \set@color \XC@ecolor \ign...

\@textcolor ...\protect \leavevmode {\color #1{#2}
                                                  #3}
\lst@prebreak ->\hbox {\textcolor {blue}{X}
                                           }
\lst@@discretionary ...st@spacekern \lst@prebreak 
                                                  }{\llap {\lsthk@EveryLine ...

\lst@discretionary ...i \else \lst@@discretionary 
                                                  \fi 
\lst@OutputToken ... }\lst@CalcLostSpaceAndOutput 
                                                  }}\lst@ResetToken 
\lst@Output ...\fi \lsthk@Output \lst@OutputToken 
                                                  \fi \let \lst@lastother \r...

\lst@PrintToken ->\lst@ifletter \lst@Output 
                                            \lst@letterfalse \else \lst@Outp...

\lst@XPrintToken ->\lst@PrintToken 
                                   \lst@CheckMerge \ifnum \lst@length =\z@ \...

^^M->\lst@XPrintToken 
                      \lst@EOLUpdate \lsthk@InitVarsBOL \global \advance \ls...
l.11 Example         

Forcefully setting \XC@nummixins0 works, but i think this is only because it simply prevents the extension of \XC@mcolor within xxcolor. Hover, this breaks the effect of any active mixin-environment for the prebreak.

Minimal working example (MWE)

\documentclass{article}

\usepackage{pgf}
\usepackage{xxcolor}

\usepackage{listings}

\begin{document}
\begin{lstlisting}[breaklines, prebreak=\hbox{\textcolor{blue}{X}}]
Example
\end{lstlisting}
\end{document}

EagleoutIce avatar Sep 11 '22 15:09 EagleoutIce

Just a random attempt, not a serious fix: Restore normal \space definition inside xxcolor's patch to \XC@mcolor (one of xcolor's internal hooks).

I'm not familiar with xcolor's codebase, but a simple search shows that its implementation relies on \space's normal definition (\def\space{ }). But when prebreak is used, \space is let to \lst@spacekern, which is defined by \gdef\lst@spacekern{\kern\lst@width}.

\documentclass{article}

\usepackage{pgf}
\usepackage{xxcolor}
\usepackage{listings}

\usepackage{xpatch}
\makeatletter
\let\XC@space\space % backup normal \space

\xpatchcmd\XC@mcolor
  {%
    \colorlet{XC@mixtmp}{.}%
  }{%
    \let\XC@@space=\space % backup special \space (\lst@spacekern)
    \let\space=\XC@space
    \colorlet{XC@mixtmp}{.}%
    \let\space=\XC@@space
  }{}{\PatchFailed}
\makeatother

\begin{document}
\begin{lstlisting}[breaklines, prebreak=\hbox{\textcolor{blue}{X}}]
Example example example example example example example example example example
\end{lstlisting}
\end{document}

image

muzimuzhi avatar Sep 11 '22 17:09 muzimuzhi