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

Fre*_*ijk 5 latex listings

我正在使用LaTeX listings包,并且我通过以下方式对代码的每第五行进行编号:

\lstset{
numbers=left,
stepnumber=5,
firstnumber=1,
numberfirstline=true
}
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:我更喜欢使用它\lstinputlisting,而不必修改以这种方式导入的代码.

Hik*_*eto 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}
Run Code Online (Sandbox Code Playgroud)

最后一行列出数字

您还应该查看有关任意更改行编号的问题

更新

这需要修改列表源,因此在使用时可能不够\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}
Run Code Online (Sandbox Code Playgroud)

这确实需要您手动指定每个列表的最后一个行号,但是考虑到操作临时文件的难度,这似乎是一个合理的牺牲,这可能是动态发现行数的唯一真正的解决方案,只需要纯 TeX。如果可以接受不可移植的解决方案,您可以运行 shell 命令(例如wc -lvia)\write18来获取行数。当然,这需要所选命令出现在使用源的所有系统上,如果这些系统跨越不同的操作系统,这可能会造成困难。有关如何捕获其输出的说明,请参阅此问题\write18

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