Beim Einbinden von Quelltext aus Dateien (um diesen automatisch aktuell zu halten) gibt es keine Möglichkeit, die Formatierung durch Bearbeiten des Quelltextes zu beeinflussen. Ändert sich ein Absatz im Dokument, kann die Auflistung schwer lesbar werden.
Dies liegt daran, dass Quellcode häufig in „Absätzen“ organisiert ist (z. B. die Funktionssignaturen und ihre Kommentare darunter) und ich möchte diese lieber nicht umbrechen. Gibt es eine Möglichkeit, Listenlisten so zu zwingen, dass Seitenumbrüche nur bei leeren Zeilen erfolgen? Unten finden Sie ein einfaches Beispiel mit 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}
Im obigen Beispiel erhalte ich einen Umbruch zwischen copy
und seinem Kommentar, obwohl es viel besser wäre, eine Zeile früher zu lesen.
Antwort1
Entsprechendhttps://tex.stackexchange.com/a/73305/89417Eine Lösung, um Seitenumbrüche in Auflistungen zu vermeiden, ist die Verwendung eines minipage
. Wenn Sie jeden Code-Absatz in eine separate Miniseite setzen, wird daher zwischen den Absätzen ein Umbruch erfolgen. Sie können dies problemlos mit einer beliebigen Skriptsprache automatisieren, z. B. 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";
Dieses Skript wandelt leere Zeilen in das Ende und den Anfang einer Miniseite um und fügt einen zusätzlichen Anfang und ein zusätzliches Ende ein, um sie an den ersten und letzten Absatz anzupassen.
Anschließend können Sie in LaTeX dieses Skript aufrufen (unter Linux ausgeführt mit --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}
Ergebnis:
Antwort2
Wenn nur ein Seitenumbruch vorhanden ist, besteht eine einfache Möglichkeit darin, zu verwenden \enlargethispage
.
Dadurch wird die val copy
Zeile auf die nächste Seite verschoben.
\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}