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 moredelim
opçã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}
Uma possível desvantagem é que você precisa fazer isso “manualmente”. Para a Prelude>
peça você pode usar a morekeywords
opçã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
Ainda não é totalmente satisfatório, pois não consigo usar as opções de frame do lstlistings, que tive que imitar usando o adjustbox
pacote nice. Além disso, ele quebra se houver um >
na saída em algum lugar, mas isso é algo com o qual posso conviver.