Номер последней строки с пакетом предложений в LaTeX
Я использую LaTeX с listings
пакет, и я нумерую каждую пятую строку кода, имея:
\lstset{
numbers=left,
stepnumber=5,
firstnumber=1,
numberfirstline=true
}
Теперь из-за numberfirstline=true
в этих настройках, кроме кратных пяти, первая строка каждого списка тоже нумеруется, но я бы хотел, чтобы и последняя строка кода была пронумерована. Поэтому, если у меня есть список с 17 строками кода, строки, которые я хотел бы видеть пронумерованными, будут 1 5 10 15 17.
Есть ли способ, которым я могу сделать так, чтобы списки вели себя так? Я старался numberlastline=true
, но этого, похоже, не существует.
Изменить: я бы предпочел использовать это с \lstinputlisting
и без необходимости изменять код, который импортируется таким образом.
1 ответ
На самом деле, так как вы используете 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}
Вы также должны проверить этот вопрос о произвольном изменении нумерации строк.
ОБНОВИТЬ
Это требует внесения изменений в источник листинга, и поэтому может быть недостаточным при использовании \lstinputlisting
, Альтернативный подход заключается в изменении логики самого пакета листингов для нумерации последней строки, когда это явно указано через lastline
или же linerange
ключи, как показано ниже.
\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
чтобы получить количество строк. Это, конечно, потребовало бы, чтобы выбранная команда присутствовала во всех системах, в которых используется источник, что может вызвать трудности, если эти системы работают в разных операционных системах. Смотрите этот вопрос для объяснения \write18
и этот вопрос о том, как захватить его вывод.
Стоит отметить, что при использовании linerange
, он будет нумеровать последнюю строку каждого отдельного диапазона, но не первую строку для каждого диапазона при использовании numberfirstline=true
, Хотя это также может быть изменено, linerange
уже приводит к достаточному количеству таких причуд, что, если это будет проблемой, то это, скорее всего, отдельно от рассматриваемой здесь проблемы.