![使用 linerange 选项时如何删除前导不必要的空格?](https://linux22.com/image/281337/%E4%BD%BF%E7%94%A8%20linerange%20%E9%80%89%E9%A1%B9%E6%97%B6%E5%A6%82%E4%BD%95%E5%88%A0%E9%99%A4%E5%89%8D%E5%AF%BC%E4%B8%8D%E5%BF%85%E8%A6%81%E7%9A%84%E7%A9%BA%E6%A0%BC%EF%BC%9F.png)
说实话,我正在寻找已经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
下面的方法定义了一个布尔键,称为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}*