Fechando parênteses como delimitador não correspondido quando breaklines=true

Fechando parênteses como delimitador não correspondido quando breaklines=true

Quero que o código entre parênteses e colchetes apareça em cores diferentes. No documento a seguir, as palavrascolchetes novamenteaparecem em verde conforme pretendido elá fora novamenteé preto conforme pretendido, mas se estende até a margem da página.

Se eu descomentar a linha ,breaklines=true, a linha será quebrada entrecolchetesede novo, no entanto, essas palavras e as seguintes são vermelhas, ou seja, como se uma seção delimitada por (- )tivesse sido detectada, mas o fechamento )fosse ignorado.

O que está acontecendo aqui?

Adição:O problema também ocorre se não houver nenhuma quebra de linha, por exemplo, se eu encurtar todas as palavras do texto para a primeira letra. De qualquer forma, o problema desaparece se eu escolher qualquer outro tipo de delimitador em vez de (), por exemplo {}.

\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}

Responder1

Você pode ter se deparado com um bug decorrente do tratamento especial do parêntese direito pelo algoritmo de quebra de linha dolistingspacote. Na verdade, quando o SelectCharTablegancho usado pelo listingspacote é executado e a quebra de linha está habilitada )é definido como uma macro, ou seja, por

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

onde

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

Infelizmente, isso significa que )não é mais reconhecido como delimitador, o que eventualmente leva à sua observação.

Eu me esforcei para encontrar uma solução para esse bug, mas não consegui até agora. (Minhas habilidades de programação em TeX ainda são limitadas.) Então, a única coisa que posso fornecer agora é uma solução alternativa na forma de um patch que simplesmente cancela o tratamento especial )pelo algoritmo de quebra de linha:

\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}

A saída resultante é:

Responder2

Uma solução simples seria, em vez de usar parênteses de fechamento ')', pode-se usar outro caractere, por exemplo, ']' e substituí-lo por parênteses de fechamento ')'.

\begin{lstlisting[literate={(}{{\textbf{(}}}1                          
                           {]}{{\textbf{)}}}1]
(In text I'm closing using]
\end{lstlisting}

informação relacionada