Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

As the title says, the option breaklines=true seems to have an undesired interaction when using literate; in the following example the closing parenthesis doesn't get colorized

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}

\lstset{
  literate=
    {)}{{\textcolor{red}{)}}}{1}
    {(}{{\textcolor{red}{(}}}{1},
  breaklines=true,
}

\begin{document}

\begin{lstlisting}
()
\end{lstlisting}

\end{document}

enter image description here

Commenting out the breaklines=true option produces the desired result. What is producing this odd behaviour and how can it be prevented?

share|improve this question
    
related: tex.stackexchange.com/questions/110641/… –  Jubobs Mar 11 at 21:18
add comment

2 Answers

up vote 10 down vote accepted

When the breaklines=true option is given, a code that's executed after doing \lst@literate (which assigns the special meaning to the defined characters) is

\lst@ifbreaklines \lst@Def {`)}{\lst@breakProcessOther )}\fi

and this expands to

\lccode `\~=#1\lowercase {\def ~}{\lst@breakProcessOther )}

which makes the active ) expand to

\lst@breakProcessOther )

where ) is not active. All this happens when \lsthk@SelectCharTable is executed.

If, just for trying, I apply a patch with etoolbox

\makeatletter
\patchcmd{\lsthk@SelectCharTable}{`)}{`]}{}{}
\makeatother

then the right parenthesis will be printed red, but a similar problem will appear with the ] in case, say,

literate=
  {[}{{\textcolor{red}{[}}}{1}
  {]}{{\textcolor{red}{]}}}{1},

is specified (the right bracket will become a black right parenthesis, which I expected).

I believe this has to do with precautions listings makes in order to correctly treat parenthesized expressions. And I suspect that not much can be done about this.

If I try to patch the definition of \lsthk@SelectCharTable removing that conditional part, then the right parenthesis comes out red. But I don't know if other problems will arise.

share|improve this answer
    
Surely, the fact that breaklines breaks literate replacements is not the intended behaviour. Should this be reported as a bug? –  Jubobs Dec 9 '13 at 14:22
    
@Jubobs I believe so. –  egreg Dec 9 '13 at 14:46
    
There is an explanation underneath the line \lst@ifbreaklines \lst@Def {`)}{\lst@breakProcessOther )}\fi in listings.dtx: A bug [...] has been removed by using \lst@ProcessOther instead of \lst@AppendOther. I guess fixing that original bug introduced another, which is the object of Gonzalo's question... –  Jubobs Mar 9 at 13:54
add comment

I looked at the file listings.sty of the package listings trying to find inconsistencies and inaccuracies, but to no avail. If you are on the same boat, no pun intended, look elsewhere.

The line 1350 of code in the file lstmisc.sty however, specifies that if the options breaklines are set true, the `) ends its process. This is precisely the reason that lies behind the inoperability of this character, when the instructed options to break those lines as specified in the preamble of the document, are continously disregarded.

Whether this issue is considered a bug by the TeX community, I won't argue in favor or against it, for it is only fair for the experts to reach a conclusion about this problem.

Is a patch needed as suggested by egreg? Only if you are unwilling to make a small change in the file lstmisc.sty. (Hopefully by the next update of the listings package, the issue at hand is resolved. It's beyond me though, why it's been over a year, since this question first appeared, and the problem has not been fixed).

Thus the solution is to replace, or better yet, to omit the closing parenthesis in the line 1350 of said file, so the offending character, functions as it should, regardless if \lstset is set to break the lines as intended. That is, even if breaklines=true is specified earlier in the document.

So

 {\lst@ifbreaklines \lst@Def{`)}{\lst@breakProcessOther)}\fi}

ought to be replaced by:

 {\lst@ifbreaklines \lst@Def{``}{\lst@breakProcessOther)}\fi}

if parentheses and brackets are enclosed within the document, even without a patch.

An example goes like this:



\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{etoolbox}


\lstset{
    breaklines=true,
  literate=
    {[}{{\textcolor{red}{\Huge [}}}{1}
    {]}{{\textcolor{red}{\Huge ]}}}{1}
    {(}{{\textcolor{red}{\Huge (}}}{1}
    {)}{{\textcolor{red}{\Huge )}}}{1}
}


\begin{document} 
\noindent Output obtained: 

\begin{lstlisting}        
[a test a test a test a test a test a [test a test a test a test a test a test a test a test a test a test a test a test[ a test a test a test a test a test a test) a test a test a test a test a test a test a test a test a test a test a test a   test a test a test a test a test a te]st a] test a test a test a test a test a test a test a test ([a test a test( a t )est a test a test a test a)]    
\end{lstlisting}               
\end{document}

And if you are not changing the lstmisc.sty line 1350 until the next update of the package listings, which hopefully it will be fixed, then the implementation of the patch by using the etoolbox package, as it was suggested earlier by egreg, is as follows:



\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{etoolbox}


\lstset{
    breaklines=true,
  literate=
    {[}{{\textcolor{red}{\Huge [}}}{1}
    {]}{{\textcolor{red}{\Huge ]}}}{1}
    {(}{{\textcolor{red}{\Huge (}}}{1}
    {)}{{\textcolor{red}{\Huge )}}}{1}
}


% egreg's workaround
\makeatletter
\patchcmd{\lsthk@SelectCharTable}{)}{`}{}{} 
\makeatother 

\begin{document} 
\noindent Output obtained: 

\begin{lstlisting}        
[a test a test a test a test a test a [test a test a test a test a test a test a test a test a test a test a test a test[ a test a test a test a test a test a test) a test a test a test a test a test a test a test a test a test a test a test a   test a test a test a test a test a te]st a] test a test a test a test a test a test a test a test ([a test a test( a t )est a test a test a test a)]    
\end{lstlisting}               
\end{document}

Edit: the following patch,

\patchcmd{\lsthk@SelectCharTable}{`)}{``}{}{}

although equivalent to the one discussed above, is actually wiser, because it can be undone more easily; the inverse patch is

\patchcmd{\lsthk@SelectCharTable}{``}{`)}{}{}

enter image description here

share|improve this answer
    
That approach is not viable, because the color declaration is applied to any text that follows the ). Moreover, the problem is broader than just colour. –  Jubobs Dec 9 '13 at 19:03
    
@Jubobs no problem, I'll update the answer –  doed Dec 9 '13 at 19:10
    
@Jubobs isn't the package listings intended for brief lines of code anyway? In other words, how important is to have lipsum sized paragraphs when the package's purpose is completely different? –  doed Dec 9 '13 at 21:58
    
Do you have a source supporting that claim? As far as I know, listings is not intended for just brief lines of code. People (incl. me) use it to typeset sizeable pieces of code. –  Jubobs Dec 9 '13 at 22:03
2  
I'm not sure what you mean, but manually breaking the lines is not a viable option. Imagine inputting listings that reside in external source files. You'd have to introduce linebreaks in those files simply to be able to typeset them nicely in LaTeX. And then imagine that you decide to change the text width and/or the font size. Your line breaks wouldn't be where they're needed anymore. You'd have to reformat your listings all over again. This example shows that the automatic line-breaking functionality offered by listings is very valuable. It's too bad it breaks other valuable things. –  Jubobs Dec 9 '13 at 22:32
show 5 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.