Quebre a página apenas em pontos específicos de uma listagem

Quebre a página apenas em pontos específicos de uma listagem

Ao incluir o código-fonte dos arquivos (para mantê-lo atualizado automaticamente), não há como influenciar a formatação editando o código-fonte. Quando um parágrafo do documento é alterado, a listagem pode ficar difícil de ler.

Isso ocorre porque o código-fonte é frequentemente organizado em "parágrafos" (por exemplo, as assinaturas das funções e seus comentários abaixo) e eu preferiria não quebrá-los. Existe uma maneira de forçar o lstlisting a quebrar apenas a página, por exemplo, em linhas vazias? Abaixo está um exemplo simples com lstinputlisting:

\RequirePackage{filecontents}
\begin{filecontents*}{stack.mli}
(***********************************************************************)
(*                                                                     *)
(*                                 OCaml                               *)
(*                                                                     *)
(*             Xavier Leroy, projet Cristal, INRIA Rocquencourt        *)
(*                                                                     *)
(*   Copyright 1996 Institut National de Recherche en Informatique et  *)
(*     en Automatique.                                                 *)
(*                                                                     *)
(*   All rights reserved.  This file is distributed under the terms of *)
(*   the GNU Lesser General Public License version 2.1, with the       *)
(*   special exception on linking described in the file LICENSE.       *)
(*                                                                     *)
(***********************************************************************)

(** Last-in first-out stacks.
   This module implements stacks (LIFOs), with in-place modification.
*)

type 'a t
(** The type of stacks containing elements of type ['a]. *)

exception Empty
(** Raised when {!Stack.pop} or {!Stack.top} is applied to an empty stack. *)


val create : unit -> 'a t
(** Return a new stack, initially empty. *)

val push : 'a -> 'a t -> unit
(** [push x s] adds the element [x] at the top of stack [s]. *)

val pop : 'a t -> 'a
(** [pop s] removes and returns the topmost element in stack [s],
   or raises {!Empty} if the stack is empty. *)

val top : 'a t -> 'a
(** [top s] returns the topmost element in stack [s],
   or raises {!Empty} if the stack is empty. *)

val clear : 'a t -> unit
(** Discard all elements from a stack. *)

val copy : 'a t -> 'a t
(** Return a copy of the given stack. *)

val is_empty : 'a t -> bool
(** Return [true] if the given stack is empty, [false] otherwise. *)

val length : 'a t -> int
(** Return the number of elements in a stack. Time complexity O(1) *)

val iter : ('a -> unit) -> 'a t -> unit
(** [iter f s] applies [f] in turn to all elements of [s],
   from the element at the top of the stack to the element at the
   bottom of the stack. The stack itself is unchanged. *)

val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** [fold f accu s] is [(f (... (f (f accu x1) x2) ...) xn)]
    where [x1] is the top of the stack, [x2] the second element,
    and [xn] the bottom element. The stack is unchanged.
    @since 4.03 *)
\end{filecontents*}
\documentclass{article}
\usepackage{listings}
\begin{document}
\section{Stack}
\lstset{
  basicstyle={\ttfamily\lst@ifdisplaystyle\footnotesize\fi},
  language=[Objective]Caml
}
\lstinputlisting{stack.mli}
\end{document}

No exemplo acima, obtenho uma pausa entre copye seu comentário, embora bnreaking uma linha antes fosse muito melhor.

Responder1

De acordo comhttps://tex.stackexchange.com/a/73305/89417uma solução para evitar quebras de página nas listagens é usar um arquivo minipage. Colocar cada parágrafo de código em uma minipágina separada irá, portanto, quebrar entre os parágrafos. Você pode automatizar isso facilmente usando qualquer linguagem de script, por exemplo perl:

print "\\noindent\\begin{minipage}{\\linewidth}\\begin{lstlisting}\n";
while(<>){
    print $_ eq "\n" ? "\\end{lstlisting}\\end{minipage}\n\n\\noindent\\begin{minipage}{\\linewidth}\\begin{lstlisting}\n" : $_;
}
print "\\end{lstlisting}\\end{minipage}\n";

Este script converte linhas vazias no final e no início de uma minipágina e coloca um início e um fim extras para corresponder ao primeiro e ao último parágrafo.

Então, no LaTeX, você pode chamar este script (assumindo Linux, execute com --shell-escape):

\documentclass{article}
\usepackage{listings}
\usepackage[margin=1.5in]{geometry} % make OCaml comment block fit on a line
\begin{document}
\section{Stack}
\lstset{
  basicstyle={\ttfamily\lst@ifdisplaystyle\footnotesize\fi},
  language=[Objective]Caml
}
\input{|"perl format_listing.pl < stack.mli"}
\end{document}

Resultado:

insira a descrição da imagem aqui

Responder2

Se houver apenas uma quebra de página, uma maneira fácil é usar \enlargethispage.

Isso move a val copylinha para a próxima página.

\documentclass{article}
\usepackage{listings}
\begin{document}
\section{Stack}
\lstset{
  basicstyle={\ttfamily\lst@ifdisplaystyle\footnotesize\fi},
  language=[Objective]Caml
}
\enlargethispage{-\baselineskip}
\lstinputlisting{stack.mli}
\end{document}

insira a descrição da imagem aqui

informação relacionada