lstlisting
当与或multicols
内部结合时, 的垂直间距会发生变化。可以使用 固定顶部间距(请参阅此内容)minipage
tcolorbox
lstlisting
\topskip = 0pt
回答(还有一个关于底部间距的问题),但底部的间距大多不正确。对于belowskip = 0pt
和偶数行,可以获得最佳近似值。belowskip > 0pt
对于每行数,设置都会给出相同的错误间距(这取决于字体大小)。
有没有针对此问题的通用解决方案?如果没有,那么获得一致间距的最佳做法是什么?
例子
平均能量损失
\documentclass{article}
\usepackage{listings}
\usepackage{multicol}
% Simplified tcolorbox
\newenvironment{mybox}{
\addvspace{\bigskipamount}
\hrule
\begin{minipage}{\textwidth}
}{
\end{minipage}
\hrule
\addvspace{\bigskipamount}
}
\parindent = 0pt
\begin{document}
Normal
\verb|belowskip = 0pt|
\begin{mybox}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
\end{lstlisting}
\end{mybox}
\begingroup
\huge
\begin{mybox}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
\end{lstlisting}
\end{mybox}
\endgroup
Multicols
\verb|belowskip = 0pt|
\topskip = 0pt
\begin{mybox}
\begin{multicols}{2}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
Ag
\end{lstlisting}
\end{multicols}
\end{mybox}
\begin{mybox}
\begin{multicols}{2}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
Ag
Ag
\end{lstlisting}
\end{multicols}
\end{mybox}
Multicols with default settings of listings
\verb|belowskip = \medskipamount > 0pt|
\begin{mybox}
\begin{multicols}{2}
\begin{lstlisting}
Ag
Ag
\end{lstlisting}
\end{multicols}
\end{mybox}
\begin{mybox}
\begin{multicols}{2}
\begin{lstlisting}
Ag
Ag
Ag
\end{lstlisting}
\end{multicols}
\end{mybox}
\begingroup
\huge
\begin{mybox}
\begin{multicols}{2}
\begin{lstlisting}
Ag
Ag
\end{lstlisting}
\end{multicols}
\end{mybox}
\endgroup
\end{document}
更新
的正常间距listings
由 (hook EveryLine) 引入\lsthk@EveryLine
。这可以用 和 来模仿\par
。\strut
添加\vspace
类似于belowskip
。因此间距行为可以简化为multicol
。
\documentclass{article}
\usepackage{listings}
\usepackage{multicol}
% Simplified tcolorbox
\newenvironment{mybox}{
\addvspace{\bigskipamount}
\hrule
\begin{minipage}{\textwidth}
}{
\end{minipage}
\hrule
\addvspace{\bigskipamount}
}
\parindent = 0pt
\begin{document}
Normal
\begin{mybox}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
\end{lstlisting}
\end{mybox}
\begin{mybox}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
Ag
\end{lstlisting}
\end{mybox}
Imitation of lstlisting
\begin{mybox}
\par\strut Ag
\end{mybox}
\begin{mybox}
\par\strut Ag
\par\strut Ag
\end{mybox}
Multicols with imitation of lstlisting
\topskip = 0pt
\begin{mybox}
\begin{multicols}{2}
\par\strut Ag
\par\strut Ag
%\vspace{0pt}% no belowskip
\end{multicols}
\end{mybox}
\begin{mybox}
\begin{multicols}{2}
\par\strut Ag
\par\strut Ag
\vspace{0pt}% belowskip --> reduces the deviation to a small value, but the spacing remains incorrect
\end{multicols}
\end{mybox}
\begin{mybox}
\begin{multicols}{2}
\par\strut Ag
\par\strut Ag
\par\strut Ag
\vspace{0pt}% belowskip
\end{multicols}
\end{mybox}
\end{document}
答案1
当行数为奇数时,第一列的底部将与基线齐平。belowskip 是什么并不重要,因为它不会位于列的底部。多列本身可能会正常地添加一些空间,但 minipage 会占用这些空间。(\@minipagefalse
更糟。)
不清楚应在基线以下添加多少间隙。 \dp\strutbox
太小,又\medskipamount
太大。
\documentclass{article}
\usepackage{listings}
\usepackage{multicol}
\parindent = 0pt
\begin{document}
Normal
\verb|belowskip = 0pt|\bigskip
\hrule
\begin{minipage}{\textwidth}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
\end{lstlisting}
\end{minipage}
\hrule
\bigskip
Multicols
\verb|belowskip = 0pt|\bigskip
\topskip = 0pt
\hrule
\begin{minipage}{\textwidth}
\begin{multicols}{2}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
Ag
\end{lstlisting}
\end{multicols}
\end{minipage}
\hrule
\bigskip
\hrule
\begin{minipage}{\textwidth}
\begin{multicols}{2}
\begin{lstlisting}[aboveskip = 0pt, belowskip = 0pt]
Ag
Ag
Ag
\end{lstlisting}
\end{multicols}
\vskip 1ex
\hrule height0pt
\end{minipage}
\hrule
\end{document}
答案2
此修复基于回答@John Kormylo 的另一个问题。每行后面的空格可以通过\hrule height0pt
在末尾添加来保护。
\begin{mybox}
\begin{multicols}{2}
\par\strut Ag\hrule height0pt
\par\strut Ag\hrule height0pt
\par\strut Ag\hrule height0pt
\vspace{0pt}% belowskip
\end{multicols}
\end{mybox}
幸运的是,包含执行此任务的listings
钩子(参见\lst@AddToHook{EOL}
listings-devel.pdf)。请注意,每次调用后都必须清除此钩子,因为每次调用lstlisting
时都会添加相同的代码。它还可以防止对其他列表产生不必要的影响(例如)。lstlisting
\lstinline{code}
\documentclass{article}
\usepackage{listings}
\usepackage{multicol}
% Simplified tcolorbox
\newenvironment{mybox}{
\addvspace{\bigskipamount}
\hrule
\begin{minipage}{\textwidth}
}{
\end{minipage}
\hrule
\addvspace{\bigskipamount}
}
\makeatletter
% Simplified tcolorbox with multicols
\newenvironment{multibox}[1][2]{
\topskip = 0pt% remove spacing on top
\begin{mybox}
\begin{multicols}{#1}
\lst@AddToHook{EOL}{\hrule height0pt}% add hrule after each input line
}{
\end{multicols}
\end{mybox}
}
% Clear the hook
\AfterEndEnvironment{multibox}{\gdef\lsthk@EOL{}}
\makeatother
% Set the skips of lstlisting to 0pt
\lstset{aboveskip = 0pt, belowskip = 0pt}
\parindent = 0pt
\begin{document}
Normal
\begin{mybox}
\begin{lstlisting}
Ag
\end{lstlisting}
\end{mybox}
\begin{mybox}
\begin{lstlisting}
Ag
Ag
\end{lstlisting}
\end{mybox}
Multicols
\begin{multibox}
\begin{lstlisting}
Ag
\end{lstlisting}
\end{multibox}
\begin{multibox}
\begin{lstlisting}
Ag
Ag
\end{lstlisting}
\end{multibox}
\begin{multibox}
\begin{lstlisting}
Ag
Ag
Ag
\end{lstlisting}
\end{multibox}
\end{document}