Salte de página solo en puntos específicos de un listado

Salte de página solo en puntos específicos de un listado

Al incluir el código fuente de los archivos (para mantenerlo actualizado automáticamente), no hay forma de influir en el formato editando el código fuente. Cuando cambia un párrafo del documento, la lista puede resultar difícil de leer.

Esto se debe a que el código fuente a menudo está organizado en "párrafos" (por ejemplo, las firmas de funciones y sus comentarios a continuación) y preferiría no dividirlos. ¿Hay alguna manera de forzar que lstlisting solo haga saltos de página, por ejemplo, en líneas vacías? A continuación se muestra un ejemplo sencillo con 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}

En el ejemplo anterior, obtengo una pausa entre copyy su comentario, aunque sería mucho mejor separar una línea antes.

Respuesta1

De acuerdo ahttps://tex.stackexchange.com/a/73305/89417Una solución para evitar saltos de página en los listados es utilizar un archivo minipage. Por lo tanto, colocar cada párrafo de código en una minipágina separada dividirá los párrafos. Puede automatizar esto fácilmente utilizando cualquier lenguaje de secuencias de comandos, por ejemplo 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 convierte líneas vacías en el final y el inicio de una minipágina, y coloca un inicio y un final adicionales para que coincidan con el primer y el último párrafo.

Luego, en LaTeX, puedes llamar a este script (asumiendo Linux, ejecútalo con --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:

ingrese la descripción de la imagen aquí

Respuesta2

Si solo hay un salto de página, una forma sencilla es utilizar \enlargethispage.

Esto mueve la val copylínea a la página siguiente.

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

ingrese la descripción de la imagen aquí

información relacionada