在LaTeX中列出包含列表包的最后一行

时间:2017-05-24 07:34:19

标签: latex listings

我将LaTeX与listings包一起使用,并通过以下方式对代码的每五行编号:

\lstset{
numbers=left,
stepnumber=5,
firstnumber=1,
numberfirstline=true
}

现在由于这些设置中的numberfirstline=true,除了五的倍数之外,每个列表的第一个行也是编号,但我希望最后一行代码行也要编号。因此,如果我有17行代码的列表,我希望看到的行数为1 5 10 15 17

有什么方法可以让我的列表行为像这样吗?我试过了numberlastline=true,但这似乎不存在。

修改:我希望将其与\lstinputlisting一起使用,而无需修改以此方式导入的代码。

1 个答案:

答案 0 :(得分:4)

实际上,由于您正在使用numberfirstline=true,因此这比您想象的更容易实现。 listings包提供了一种机制,可以通过escapeinside从列表中间的逐字模式中逃脱,以便能够插入其他宏。这里的诀窍是,从转义的代码返回后,它将下一行视为"第一个"再次排队,即使没有重置计数。因此,您所要做的就是在列表的倒数第二行退出(并且什么也不做!)。如果你在最后一次这样做,那你来不及了!下面的例子演示如何使用它来获得你想要的东西。

\documentclass{article}
\usepackage{listings}

\lstset{
numbers=left,
stepnumber=5,
firstnumber=1,
numberfirstline=true
escapeinside={|(}{)|}
}

\begin{document}

\begin{lstlisting}
lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.
ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt|()|
mollit anim id est laborum.
\end{lstlisting}

\end{document}

listing with number on last line

您还应该查看this question about arbitrarily altering line numbering

<强>更新

这需要修改列表来源,因此在使用\lstinputlisting时可能不够。另一种方法是修改列表包本身的逻辑,以便在通过lastlinelinerange键明确指定时对最后一行进行编号,如下所示。

\documentclass{article}
\usepackage{listings}

\lstset{
numbers=left,
stepnumber=5,
firstnumber=1,
numberfirstline=true,
}

\makeatletter

\gdef\lst@SkipOrPrintLabel{%
    \ifnum\lst@skipnumbers=\z@
        \global\advance\lst@skipnumbers-\lst@stepnumber\relax
        \lst@PlaceNumber
        \lst@numberfirstlinefalse
    \else
        \ifnum\lst@lineno=\lst@lastline
            \lst@PlaceNumber
            \lst@numberfirstlinefalse
        \fi
        \lst@ifnumberfirstline
            \lst@PlaceNumber
            \lst@numberfirstlinefalse
        \fi
    \fi
    \global\advance\lst@skipnumbers\@ne}

\makeatother

\begin{document}

\lstinputlisting[lastline=13]{input.tex}

\end{document}

这确实需要您手动指定每个列表的最后一个行号,但考虑到操作临时文件的难度,这似乎是一个合理的牺牲,这可能是动态发现只需要纯粹的行计数的唯一真正解决方案TeX的。如果可以接受非可移植解决方案,则可以通过wc -l运行\write18之类的shell命令来获取行数。这当然要求所选择的命令出现在所使用的源的所有系统上,如果这些系统跨越不同的操作系统,则可能导致困难。有关如何捕获其输出的\write18this question的说明,请参见this question

值得注意的是,当使用linerange时,它将使用numberfirstline=true对每个单独范围的最后一行进行编号,但不是每个范围的第一行。虽然这可以类似地改变,linerange已经产生了足够的这样的怪癖,如果这是一个问题,那么它很可能与此处的问题分开。