如何扩展 \lstinputlisting 命令

如何扩展 \lstinputlisting 命令

答案来自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@basicstylelst@tabsize

它应该与任何:

  • 文档类别中的字体大小
  • 基本样式中的字体大小
  • 标签大小

局限性(如果有人能解决我会非常高兴):

  • 它需要columns=flexiblebasicstyle=\ttfamily
  • 如果tabsizebasicstyle作为选项传递给\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,这将同时设置firstlinefirstnumber

*请注意,我在使用设置长度的语法时遇到了一些麻烦\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}

相关内容