答案来自lstinputlistings 的 autogobble
我设法创建了一个命令,它\lstinputlisting
可以吞噬firstnumber
并使 开始firstline
。我想将其重写为一个包,以便它挂接到\lstinputlisting
,但正如代码可能反映的那样,我对 LaTeX 编程经验很少。
我的目标是能够写作
\lstset{tabsize=3,numbers=left,frame=single,basicstyle=\footnotesize\ttfamilily,}
\lstinputlisting[levels=1,linerange={2-4},...]{hello.c}
其中的点是可能的额外常规列表选项。
或者更棒的是:
\lstset{tabsize=3,numbers=left,frame=single,basicstyle=\footnotesize\ttfamilily,}
\lstinputlisting[autogobble,linerange={2-4},...]{hello.c}
LaTeX 会自动计算标签的数量,如下所示 如何自动跳过列表中的前导空格。
平均能量损失
\documentclass{article}
\usepackage{listings,xifthen}
\lstset{tabsize=3,numbers=left,frame=single,basicstyle=\Huge\ttfamily,columns=flexible}
\newlength{\gobble}
\newlength{\gobblea}
% The width of a single space. basicstyle from lstset should be used
\sbox0{\Huge\ttfamily \ }
\newcommand{\mylist}[5]{
%#1 is number of tabs, could be calculated like in listings-autogobble with autogobble=true or be an extra option
%#2 is tabsize, which is set in lstset
%#3 is firstline from lstset
%#4 is lastline from lstset
%#5 is the filename, the only thing which should be an argument and not an option.
% Remove a single space
\setlength{\gobble}{-\the\wd0}
% Reindent a bit by multiplying with 0.9, then multiply by tabsize and number of indentation levels
\setlength{\gobble}{0.9\gobble*#1*#2}
\setlength{\gobblea}{\gobble}
\addtolength{\gobblea}{10pt}
% Check if firstline is defined
\ifthenelse{\isempty{#3} \OR \equal{#3}{0}}{%
% Check if lastline is defined
\ifthenelse{\isempty{#4}}{%
\lstinputlisting[firstnumber=1,firstline=1,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}{
\lstinputlisting[firstnumber=1,firstline=1,lastline=#4,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}
}{
\ifthenelse{\isempty{#4}}{%
\lstinputlisting[firstnumber=#3,firstline=#3,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}{
\lstinputlisting[firstnumber=#3,firstline=#3,lastline=#4,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}
}
}
\begin{document}
%mylist{#tabs}{#tabsize}{firstline}{lastline}{filename}
\mylist{1}{3}{2}{4}{hello1.c}
\end{document}
编辑
我只是稍微修改了@cyberSingularity 的代码以使用lst@basicstyle
和lst@tabsize
。
它应该与任何:
- 文档类别中的字体大小
- 基本样式中的字体大小
- 标签大小
局限性(如果有人能解决我会非常高兴):
- 它需要
columns=flexible
和basicstyle=\ttfamily
- 如果
tabsize
或basicstyle
作为选项传递给\lstinputlisting
,则必须在之前写入widthgobble
- 如果使用 XeLaTeX,则必须在 Polyglossia 之前加载命令,否则所有文本都将被格式化为
\ttfamily
\documentclass[10pt]{article}
\usepackage{listings}
\usepackage{filecontents}
\begin{filecontents*}{hello1.c}
if (a<b){
if (b<a){
printf("hello")
}
}
\end{filecontents*}
\lstset{tabsize=3,numbers=left,frame=single,basicstyle=\Huge\ttfamily,columns=flexible}
\makeatletter
\newlength{\singlespace}
\newlength{\gobble}
\newlength{\numbersep}
% The width of a single space.
\settowidth{\singlespace}{\lst@basicstyle \ }
\setlength{\singlespace}{-\singlespace}
\lst@Key{firstlineandnumber}\relax{\def\lst@firstline{#1\relax}\def\lst@firstnumber{#1\relax}}
\lst@Key{widthgobble}{0}{%
\setlength{\gobble}{0.9\singlespace}% reindent a bit
\setlength{\gobble}{\lst@tabsize\gobble}% multiply by tabsize
\setlength{\gobble}{#1\gobble}% multiply by number of tabs
\def\lst@xleftmargin{\gobble}% move left margin left
\def\lst@framexleftmargin{\gobble}% move left frameborder left
\setlength{\numbersep}{\gobble}%
\addtolength{\numbersep}{10pt}%
\def\lst@numbersep{\numbersep}% distance between numbers and left frameborder
}
\makeatother
\begin{document}
%widthgobble=#tabs,firstlineandnumber sets firstline and firstnumber
\lstinputlisting[widthgobble=1,firstlineandnumber=2,lastline=4]{hello1.c}
\end{document}
答案1
您是否在寻找类似的东西?我提供了新密钥:
widthgobble
,它以#tabs*#tabsize
firstlineandnumber
,这将同时设置firstline
和firstnumber
*
请注意,我在使用设置长度的语法时遇到了一些麻烦\gobble
,因此实施了一个丑陋的解决方法(目前意味着的参数widthgobble
应该始终有两个用星号分隔的数字):
\documentclass{article}
\usepackage{listings}
\usepackage{filecontents}
\begin{filecontents*}{hello1.c}
if (a<b){
if (b<a){
//do something
}
}
\end{filecontents*}
\errorcontextlines=\maxdimen
\lstset{tabsize=3,numbers=left,frame=single,basicstyle=\Huge\ttfamily,columns=flexible}
\newlength{\rawgobble}
\newlength{\gobble}
\newlength{\gobblea}
% The width of a single space. basicstyle from lstset should be used
\sbox0{\Huge\ttfamily \ }
% Remove a single space
\settowidth{\rawgobble}{\Huge\ttfamily \ }
\setlength{\rawgobble}{-\rawgobble}
\makeatletter
\def\sepstar#1*#2\relax{%
\def\sepstarone{#1}%
\def\sepstartwo{#2}%
}
\lst@Key{firstlineandnumber}\relax{\def\lst@firstline{#1\relax}\def\lst@firstnumber{#1\relax}}
\lst@Key{widthgobble}{0*0}{%
% Reindent a bit by multiplying with 0.9, then multiply by tabsize and number of indentation levels
\sepstar #1\relax
\setlength{\gobble}{0.9\rawgobble}%
\setlength{\gobble}{\sepstarone\gobble}%
\setlength{\gobble}{\sepstartwo\gobble}%
\setlength{\gobblea}{\gobble}%
\addtolength{\gobblea}{10pt}%
\def\lst@xleftmargin{\gobble}%
\def\lst@framexleftmargin{\gobble}%
\def\lst@numbersep{\gobblea}%
}
\makeatother
\begin{document}
%widthgobble=#tabs*#tabsize,firstlineandnumber sets firstline and firstnumber
\lstinputlisting[widthgobble=1*3,firstlineandnumber=2,lastline=4]{hello1.c}
\end{document}