Formatação alternada dentro do mesmo ambiente lstlisting

Formatação alternada dentro do mesmo ambiente lstlisting

Estou escrevendo um documento que contém partes de uma sessão do interpretador do compilador (GHCi neste caso, mas isso não é relevante). Eu tenho um estilo cuidadosamente configurado para o código Haskell que gostaria de usar lá. Mas o prompt e principalmente a saída não são código Haskell e devem ser impressos de forma diferente.

Aqui está um exemplo:

\begin{lstlisting}
Prelude> let fibs = 0:1:zipWith (+) fibs (tail fibs) in fibs !! 10
55
\end{lstlisting}

Qual é a maneira mais elegante de aplicar um estilo diferente ao que vem a seguir Prelude >e ao resto?

Responder1

Uma abordagem seria usar a moredelimopção de aplicar uma formatação diferente (e eliminar o destaque da sintaxe) em certas partes:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\usepackage{listings}

\newcommand{\notCode}{\color[rgb]{0.0,0.35,0.6}}

\lstset{
  language=Haskell,
  basicstyle=\ttfamily,
  showstringspaces=false,
  breaklines=true,
  keywordstyle={\textit},
  moredelim=[is][\notCode]{@}{@},
}

\begin{document}

\begin{lstlisting}
@Prelude>@ let fibs = 0:1:zipWith (+) fibs (tail fibs) in fibs !! 10
@55@
\end{lstlisting}

\end{document}

insira a descrição da imagem aqui

Uma possível desvantagem é que você precisa fazer isso “manualmente”. Para a Prelude>peça você pode usar a morekeywordsopção de aplicar automaticamente seu estilo, mas para as linhas que não começam com Prelude>isso será mais difícil.

Responder2

Aqui está uma resposta parcial que é suficiente para o meu caso de uso, por exemplo, formatar apenas os comandos e deixar o resto literalmente:

\documentclass{article}

\usepackage{listings}
\usepackage{framed}

\lstset{language=Haskell,basicstyle=\small\sffamily,stringstyle=\itshape}

\begingroup
\catcode`\>=\active%
\catcode`\^^M=\active%
\gdef\foo{%
\catcode`\>=\active%
\catcode`^^M=\active%
\def > ##1^^M{\char`\>{} \lstinline!##1!\par}%
\def ^^M{\par}%
}%
\endgroup

\newenvironment{ghci}{%
\begin{framed}%
\begingroup%
\small\ttfamily%
\foo%
}{%
\endgroup%
\end{framed}%
}

\begin{document}
\pagestyle{empty}
\begin{ghci}
*Count> let s = "hello stackexchange"
*Count> let x = count 0 [0..100000000]
*Count> x
Just *** Exception: stack overflow
\end{ghci}
\end{document}

Isso produz a seguinte saída

insira a descrição da imagem aqui

Ainda não é totalmente satisfatório, pois não consigo usar as opções de frame do lstlistings, que tive que imitar usando o adjustboxpacote nice. Além disso, ele quebra se houver um >na saída em algum lugar, mas isso é algo com o qual posso conviver.

informação relacionada