我想使用 listings 包在文档中包含代码片段。在我的文档中,有以下内容:
\begin{figure}[!htbp]
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{0pt}%
\begin{center}
\lstset{language=Java, numbers=left, showspaces=false,
showstringspaces=false, tabsize=2, breaklines=true}
\begin{lstlisting}
public class AutoRegistry {
public void registerCar(int ssn, int vin) {
// ...
PersonCarDirect personCar = new PersonCarDirect();
personCar.setId(ssn);
personCar.setVin(vin);
// ...
}
}
\end{lstlisting}
\end{center}
\vspace{-12pt}
\caption{AutoRegistry client class}
\label{fig:autoRegistryClientC}
\end{figure}
当我使用 pdflatex 生成 PDF 文档时,行号太靠左 - 我不希望它们位于页边距中。(见下图。)我该如何纠正这个问题?
答案1
您可以使用\begin{lstlisting}[xleftmargin=5.0ex]
调整左边距,或将此选项添加到\lstset
。这会将您的列表向右移动,包括行号和任何框架。
该lipsum
包用于在列表前提供一些虚拟文本。我还提供了查看边距的geometry
选项。[showframe]
\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{lipsum}
\usepackage{listings}
\begin{document}
\lipsum[1]
\begin{figure}[!htbp]
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{0pt}%
%\begin{center}
\centering
\lstset{language=Java, numbers=left, showspaces=false,
showstringspaces=false, tabsize=2, breaklines=true,
xleftmargin=5.0ex,
%numberstyle=\scriptsize,numbersep=0pt
}
\begin{lstlisting}
public class AutoRegistry {
public void registerCar(int ssn, int vin) {
// ...
PersonCarDirect personCar = new PersonCarDirect();
personCar.setId(ssn);
personCar.setVin(vin);
// ...
}
}
\end{lstlisting}
%\end{center}
%\vspace{-12pt}
\caption{AutoRegistry client class}
\label{fig:autoRegistryClientC}
\end{figure}
\end{document}
正如@Mico 指出的那样,你应该使用\centering
而不是\begin{center}...\end{center}
。这也可以让你消除\vspace{-12pt}
。参见我应该对图形和表格使用 center 还是 centering ?了解更多详情。以防有人复制上述代码而不阅读其他解决方案,我已经在代码中做了那些更改,并将您的原始代码保留为注释。
将数字与列右侧对齐
如果空间有限并且想要将数字对齐到列的右侧,则使用:
\newlength{\MaxSizeOfLineNumbers}%
\settowidth{\MaxSizeOfLineNumbers}{99}% Adjust to maximum number of lines
\addtolength{\MaxSizeOfLineNumbers}{2.5ex}%
并设置:
xleftmargin=\MaxSizeOfLineNumbers
这项2.5ex
调整是将数字放在边距左侧,然后我们根据数字的宽度进行移动99
。
当然,这假设您的列表中的行数少于 100,因此请进行相应调整。此外,如果您碰巧使用 之类的东西更改了数字样式numberstyle=\tiny
,{99}
则应将参数相应调整为{\tiny 99}
。
答案2
这listings
包裹通过宏 排版行号\lst@PlaceNumber
。此宏根据为键 指定的值具有不同的含义numbers
。但是,边距对齐键xleftmargin
与 中包含的元素没有任何联系\lst@PlaceNumber
,因此很难准确地使数字与左边距齐平。即使@JanHlavacek 的回答很好地将长度元素添加到一起,使得列表行号与左边距齐平,我认为重新定义为\lst@PlaceNumber
用户提供了对行号和分隔符间距的更多控制,并且使调整更容易xleftmargin
。例如,
\makeatletter
\def\lst@PlaceNumber{%
\makebox[3em][l]{\normalfont\lst@numberstyle{\thelstnumber}}%
}
\makeatother
将数字放在宽度为 的左对齐框中3em
(从而固定宽度,而不必担心行号分隔符或左边距的移动)。因此, 的含义xleftmargin
已被修改,并且更容易理解为整个列表的缩进,包括行号。
以下是一个例子:
\documentclass{article}
\usepackage[showframe]{geometry}% http://ctan.org/pkg/geometry
\usepackage{listings}% http://ctan.org/pkg/listings
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\begin{document}
\newlength{\linenumwidth} \setlength{\linenumwidth}{3em}% Redefine as required
\makeatletter
\def\lst@PlaceNumber{%
\makebox[\linenumwidth][l]{\normalfont\lst@numberstyle{\thelstnumber}}%
}
\makeatother
\lipsum[1]
\begin{figure}[!htb]
\centering
\lstset{language=Java, showspaces=false,%
showstringspaces=false, tabsize=2, breaklines=true}
\begin{lstlisting}[firstnumber=8]
public class AutoRegistry {
public void registerCar(int ssn, int vin) {
// ...
PersonCarDirect personCar = new PersonCarDirect();
personCar.setId(ssn);
personCar.setVin(vin);
// ...
}
}
\end{lstlisting}
\caption{AutoRegistry client class}
\label{fig:autoRegistryClientC}
\end{figure}
\lipsum[2]
\end{document}
下面是一个将整个列表缩进的示例20pt
:
\lstset{language=Java, showspaces=false, xleftmargin=20pt,%
showstringspaces=false, tabsize=2, breaklines=true}
以下是稍微复杂一点的行号对齐:
\usepackage{calc}% http://ctan.org/pkg/calc
...
\makeatletter
\newlength{\linenumwidth} \setlength{\linenumwidth}{3em}% Redefine as required
\newlength{\numwidth}%
\setlength{\numwidth}{\widthof{\normalfont{\lst@numberstyle{99}}}}% Up to 2-digit (99) line numbers
\def\lst@PlaceNumber{%
\makebox[\numwidth+1em][l]{%
\makebox[\numwidth][r]{\normalfont\lst@numberstyle{\thelstnumber}}%
}%
}
\makeatother
答案3
你可以发出指令
\lstset{numberstyle=\scriptsize,numbersep=3pt}
减小字体大小和行号的水平间距。
顺便说一句,如果您用单个指令替换命令对\begin{center}
... ,那么您也可以摆脱命令前的命令。:-)\end{center}
\centering
\vspace{-12pt}
\caption
答案4
这里结合了 Peter Grill 的自动宽度检测(将数字对齐到列的右侧)、Werner 的\lst@PlaceNumber
以及我自己的程序,后者使用totcount
包和一些丑陋的代码来记住最大值lstnumber
,并循环遍历所有数字以查找最大值。我这样做是因为例如 9999 比 11111 宽,而您的最大行号将是 11111。LaTeX 的默认字体不是这种情况,但可能是另一种字体的情况,或者您在排版行号时可能有一些条件性的东西。
请注意,您需要通过 LaTeX 处理两次(因为它存储了文件中的最大行号aux
,并使用前一次运行的值来计算保留宽度)。
\documentclass{article}
\usepackage{lipsum}
\usepackage{listings}
\usepackage{totcount}
\newcounter{maxlstnumber}
\regtotcounter{maxlstnumber}
\def\updatemaxlstnumber{%
\ifnum\value{lstnumber}>\value{maxlstnumber}%
\setcounter{maxlstnumber}{\the\value{lstnumber}}%
\fi%
}
\lstset{numbers=left, gobble=2, numbersep=5pt, firstnumber=11109, escapeinside={//*}{*//}}
\newlength{\MaxSizeOfLineNumbers}%
\makeatletter
% The following command allows you to customize line number style, without affecting \ref{}.
% Here, the style is "\thelstnumber." (with a dot at the end)
\def\renderlstnumber{\normalfont\lst@numberstyle{\thelstnumber.}\kern\lst@numbersep}
\def\lst@PlaceNumber{\updatemaxlstnumber\makebox[\MaxSizeOfLineNumbers][r]{\renderlstnumber}}
% This must be called after \begin{document}
\def\autosizelstnumber{
\newlength{\LoopSizeOfLineNumber}
\setcounter{lstnumber}{\the\totvalue{maxlstnumber}}
\loop\ifnum\value{lstnumber}>\z@
\settowidth{\LoopSizeOfLineNumber}{\renderlstnumber}
\ifdim\LoopSizeOfLineNumber>\MaxSizeOfLineNumbers
\setlength{\MaxSizeOfLineNumbers}{\LoopSizeOfLineNumber}
%\message{Found larger line number \the\value{lstnumber}}
\fi
\addtocounter{lstnumber}{-1}
\repeat
% \setcounter{maxlstnumber}{0}
}
\makeatother
\begin{document}
\autosizelstnumber
\parindent 0pt
\lipsum[1]
\begin{lstlisting}
aline
bline//*\label{bline}*//
yet another line//*\label{largestline}*//
\end{lstlisting}
Line \ref{bline} contains the character \verb!b!. Notice that even
though the line numbering says ``\ref{bline}.'', the
\verb!\ref{bline}! used here says ``\ref{bline}''. The dot is taken
into account when calculating the width to reserve for line numbers.
\begin{lstlisting}[firstnumber=123]
class Foo {
public static void main() {}
}//*\label{lastline}*//
\end{lstlisting}
Notice that even if we end with line \ref{lastline}, the with reserved
for line numbers is large enough to include \ref{largestline}, the
largest line.
\lipsum[2]
\end{document}