列表的实际行号:firstnumber=\inputlineno 差一个

列表的实际行号:firstnumber=\inputlineno 差一个

我希望在代码清单旁边显示实际的行号,但如果我使用firstnumber=\inputlineno,则会过早评估一行:

\documentclass{article}
\usepackage{listings}
\lstset{numbers=left, firstnumber=\inputlineno, frame = single}
\begin{document}
\begin{lstlisting}
... here is some great code on line 6 in our file ...
\end{lstlisting}
This is line $\the\inputlineno$ in our file.
\end{document}

显示第 5 行,应为第 6 行

我天真地想做firstnumber=\inputlineno+1。怎么办?

我已经尝试过firstnumber=\value{mycounter}在代码清单开头通过\AtBeginEnvironment或将此计数器设置为正确的值\lstnewenvironment。两者都给了我错误“您不能在水平模式下使用'\inputlineno'。”。

答案1

我们listings.sty发现

\def\lst@InitLstNumber{%
     \global\c@lstnumber\lst@firstnumber
     \global\advance\c@lstnumber\lst@advancenumber
     \global\advance\c@lstnumber-\lst@advancelstnum
     \ifx \lst@firstnumber\c@lstnumber
         \global\advance\c@lstnumber-\lst@advancelstnum
     \fi%
     \lst@ifincluderangemarker\else%
         \global\advance\c@lstnumber by 1%
     \fi%
     }

还有lstmisc.sty其他相关代码:

\lst@Key{firstnumber}{auto}{%
    \lstKV@SwitchCases{#1}%
    {auto&\let\lst@firstnumber\@undefined\\%
     last&\let\lst@firstnumber\c@lstnumber
    }{\def\lst@firstnumber{#1\relax}}}
\lst@AddToHook{PreSet}{\let\lst@advancenumber\z@}
\lst@AddToHook{PreInit}
    {\ifx\lst@firstnumber\@undefined
         \def\lst@firstnumber{\lst@lineno}%
     \fi}
\gdef\lst@SetFirstNumber{%
    \ifx\lst@firstnumber\@undefined
        \@tempcnta 0\csname\@lst no@\lst@intname\endcsname\relax
        \ifnum\@tempcnta=\z@ \@tempcnta\lst@firstline
                       \else \lst@nololtrue \fi
        \advance\@tempcnta\lst@advancenumber
        \edef\lst@firstnumber{\the\@tempcnta\relax}%
    \fi}
\gdef\lst@SaveFirstNumber{%
    \expandafter\xdef
        \csname\@lst no\ifx\lst@intname\@empty @ \else @\lst@intname\fi
        \endcsname{\the\c@lstnumber}}
\newcounter{lstnumber}% \global
\global\c@lstnumber\@ne % init
\renewcommand*\thelstnumber{\@arabic\c@lstnumber}

因此,firstnumber=\inputlineno当处理选项时发现时,内部计数器lstnumber会被赋予的当前值\inputlineno,该值始终是 TeX 当前正在读取的文件在读取时的行号。

因此,\inputlineno

\begin{lstlisting}[firstnumber=\inputlineno]

正在处理;对于行号的实际排版,listings使用 的当前值lstnumber

解决方法显然是

firstnumber=\numexpr\inputlineno+1\relax

确保选项位于选项的最后一行,以防在中未使用\lstset。例如,

\documentclass{article}
\usepackage{listings}

\begin{document}
\begin{lstlisting}[
  numbers=left,
  frame = single,
  firstnumber=\numexpr\inputlineno+1\relax]
... here is some great code on line 6 in our file ...
\end{lstlisting}
This is line $\the\inputlineno$ in our file.
\end{document}

\lstset方法当然更好。

在此处输入图片描述

相关内容