使用 linerange 选项时如何删除前导不必要的空格?

使用 linerange 选项时如何删除前导不必要的空格?

说实话,我正在寻找已经listings完整阅读文档的人。如果这些人也无法解决问题,那么文档中就没有提到任何内容。抱歉给您带来不便。

但至少我可以通过向您提供最小的工作示例来展示我的努力。

\documentclass[preview,border=12pt,12pt]{standalone}
\usepackage{filecontents}

\begin{filecontents*}{Program.cs}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Delegate
{
    class Program
    {
        // start
        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }
        // stop
    }
}
\end{filecontents*}


\usepackage{accsupp}
\newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}

\usepackage{xcolor}
\usepackage{listings}


\lstdefinestyle{Common}
{   
    language={[Sharp]C},
    numbers=left,
    numbersep=1em,
    numberstyle=\tiny\noaccsupp,
    frame=single,
    framesep=\fboxsep,
    framerule=\fboxrule,
    rulecolor=\color{red},
    xleftmargin=\dimexpr\fboxsep+\fboxrule,
    xrightmargin=\dimexpr\fboxsep+\fboxrule,
    breaklines=true,
    breakindent=0pt,
    tabsize=2,
    columns=flexible,
    includerangemarker=false,
    rangeprefix=//\ ,
}


\lstdefinestyle{A}
{
    style=Common,
    backgroundcolor=\color{yellow!10},
    basicstyle=\scriptsize\ttfamily,
    keywordstyle=\color{blue}\bf,
    identifierstyle=\color{black},
    stringstyle=\color{red},
    commentstyle=\color{green}
}

\begin{document}
\section*{Full Code}
\lstinputlisting[style=A]{Program.cs}
\section*{Code Snippet}
\lstinputlisting[style=A,linerange=start-stop]{Program.cs}
\end{document}*

在此处输入图片描述

我的问题是如何在使用选项时删除前导空格linerange

编辑

请考虑以下一些极端情况。

情况1

namespace Delegate
{
    class Program
    {
        // start
        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }      
    }        
}
// stop

代码应呈现如下

includrangemarker=true

        // start
        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }      
    }        
}
// stop

includerangemarker=false

        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }      
    }        
}

案例 2

namespace Delegate
{
    class Program
    {
    // start
        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }      
    }        
}
    // stop

代码应呈现如下

includerangemarker=true

    // start
        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }      
    }        
}
    // stop

includerangermarker=false

        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }      
    }        
}

答案1

这是一个解决方案。更多详细信息如下。

在此处输入图片描述

选项的限制gobble(由 提供listings

listings包提供了一个名为的密钥gobble,它允许用户指定固定的每行开头要吞掉的字符数(空格或其他字符)。但是,gobble存在以下限制。

  • 它缺乏自动化:用户必须事先查看列表来确定应该占用多少空间。
  • gobble键仅与嵌入式列表兼容(即使用环境排版lstlisting),最强调的是不是列表位于独立文件中(即使用 排版\lstinputlisting)。

选项的限制autogobble(由 提供lstautogobble

lstautogobble包提供了一个名为的布尔键autogobble,它可以自动吞噬前导空格;更具体地说,它可以测量前导空格在第一行(无论是否排版)并将该值传递给gobble键。但是,autogobble存在以下限制。

  • 因为它计算列表第一行的前导空格,所以如果排版的行范围不是从第 1 行开始,它可能不会删除适当数量的前导空格。
  • 因为它基于gobble密钥,所以它继承了后者与的不兼容性\lstinputlisting

删除前导空格的新键:autounindent autodedent

下面的方法定义了一个布尔键,称为autounindent autodedent, 哪个,

  • 如果设置,则即使只排版了一定范围的行,也会删除前导空格(即,如果使用了firstline选项或选项),linerange
  • 兼容lstlisting\lstinputlisting

已知限制

下面的代码还不能正确处理制表符。

此外,期望的行为极端情况您的编辑中介绍的内容似乎很难实现,因为它需要两次传递。我力不从心!我能做的最好的就是吞噬标记后面行首的尽可能多的空格(即代码中// start以 开头的行)。static void

若有任何其他问题,请通知我。

更新:我已将密钥重命名为autodedent(这比autounindent)。我还更正了OP 报告的问题, 根据Heiko Oberdiek 的回答。最后,为了方便起见,我在一个名为的小包中实现了该功能lstautodedent;alpha 版本可在https://github.com/jubobs/lstautodedent

代码

\documentclass[preview,border=12pt,12pt]{standalone}

\usepackage{filecontents}

\begin{filecontents*}{Program.cs}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Delegate
{
    class Program
    {
        // start
        static void Main(string[] args)
        {
            for (int x = 0; x < 10; x++)
                Console.WriteLine(x);
        }
        // stop
    }
}
\end{filecontents*}


\usepackage{accsupp}
\newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}

\usepackage{xcolor}
\usepackage{listings}
\usepackage{lstautodedent}


\lstdefinestyle{Common}
{   
    language={[Sharp]C},
    numbers=left,
    numbersep=1em,
    numberstyle=\tiny\noaccsupp,
    frame=single,
    framesep=\fboxsep,
    framerule=\fboxrule,
    rulecolor=\color{red},
    xleftmargin=\dimexpr\fboxsep+\fboxrule,
    xrightmargin=\dimexpr\fboxsep+\fboxrule,
    breaklines=true,
    breakindent=0pt,
    tabsize=2,
    columns=flexible,
    includerangemarker=false,
    rangeprefix=//\ ,
}


\lstdefinestyle{A}
{
    style=Common,
    backgroundcolor=\color{yellow!10},
    basicstyle=\scriptsize\ttfamily,
    keywordstyle=\color{blue}\bf,
    identifierstyle=\color{black},
    stringstyle=\color{red},
    commentstyle=\color{green}
}

\begin{document}
\section*{Full Code}
\lstinputlisting[style=A]{Program.cs}
\section*{Code Snippet}
\lstinputlisting[style=A,linerange=start-stop,autodedent]{Program.cs}
\end{document}*

相关内容