7

I want code in parentheses and in brackets to appear in different colors. In the following document, the words brackets again appear in green as intended, and outside again is black as intended, but stretches into the margin of the page.

If I uncomment the line ,breaklines=true, the line is broken between brackets and again, however, these words and the following are red, i.e. as if a (-)-delimited section was detected but then the closing ) was ignored.

What is going on here?

Addition: The problem occurs also if there is no line break present, e.g. if I shorten all words in the text to their first letter. The problem goes away in any case if I pick any other kind of delimiter instead of (), e.g. {}.

\documentclass{article}
\usepackage{color}
\usepackage{listings}

\lstdefinelanguage{new}{
    moredelim=*[s][\color{red}]{(}{)},
    moredelim=*[s][\color{green}]{[}{]},
  }
\lstset{
  language=new
  %,breaklines=true
  }

\begin{document}

\begin{figure}
\begin{lstlisting}
outside(in paren) [in brackets (paren+brackets) brackets again] outside again
\end{lstlisting}
\end{figure}

\end{document}
5

You might have come across a bug arising from the special treatment of the right parenthesis by the line-breaking algorithm of the listings package. In fact, when the SelectCharTable hook used by the listings package is executed and line breaking is enabled ) is defined as a macro, namely by

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

where

\lst@Def=macro:
#1->\lccode `\~=#1\lowercase {\def ~}.

Unfortunately, this means that ) is not recognized as a delimiter any more, which eventually leads to your observation.

I’ve put some effort in finding a fix for this bug, but haven’t succeeded so far. (My TeX programming skills are still limited.) So, the only thing I can provide right now is a workaround in the form of a patch that simply cancels the special treatment of ) by the line-breaking algorithm:

\documentclass{article}

\usepackage{color}

\usepackage{listings}

\lstdefinelanguage{new}{
  moredelim=*[s][\color{red}]{(}{)},
  moredelim=*[s][\color{green}]{[}{]},
}

\lstset{
  language=new,
  breaklines=true
}

\usepackage{etoolbox}

\makeatletter

\patchcmd{\lsthk@SelectCharTable}{%
  \lst@ifbreaklines\lst@Def{`)}{\lst@breakProcessOther)}\fi
}{%
}{
}{
}

\makeatother

\begin{document}

\begin{lstlisting}
outside (in paren) [in brackets (paren+brackets) brackets again] outside again
\end{lstlisting}

\end{document}

The resulting output is:

5
  • I don't fully understand the logic of that \lst@Def. Is there any reason why you use those \expandafter's and not \patchcmd{\lsthk@SelectCharTable}{...}{}{}{}?
    – egreg
    Oct 1 '12 at 11:01
  • @egreg: You’re right, \patchcmd{\lsthk@SelectCharTable} would be possible as well. I’ve used the alternative formulation since this is the way the control sequence name of the SelectCharTable hook is constructed by \lst@AddToHook.
    – mhp
    Oct 1 '12 at 11:21
  • @egreg: \lst@Def is completely mysterious to me.
    – mhp
    Oct 1 '12 at 11:26
  • There's no need to use such a complicated procedure once the control sequence has been built.
    – egreg
    Oct 1 '12 at 12:05
  • @egreg: You’ve convinced me; I’ve edited my answer.
    – mhp
    Oct 1 '12 at 12:16
2

A simple workaround would be, instead of using closing parenthesis ')', one can use another character e.g ']' and replace it with closing parenthesis ')'.

\begin{lstlisting[literate={(}{{\textbf{(}}}1                          
                           {]}{{\textbf{)}}}1]
(In text I'm closing using]
\end{lstlisting}
1
  • This was the most simple way! I had ] in my code so I put `) instead of ) and did: literate={`)}{{\textbf{)}}}{1} Apr 10 '19 at 23:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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