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

既知の制限

以下のコードではタブ文字がまだ適切に処理されていません。

さらに、極端なケースあなたの編集でカバーされている部分は、2 回のパスが必要になるため、実装が非常に難しいようです。私には手に負えません。私にできる最善のことは、マーカーの直後の行の先頭(つまり、コード内で// startで始まる行) にあるスペースをできるだけ多く埋めることです。static void

他に問題があればお知らせください。

アップデート: キーの名前を に変更しましたautodedent( よりも読みやすく書きやすいですautounindent)。また、OP によって報告された問題、 によるとハイコ・オベルディエックによるこの回答最後に、利便性のために、この機能を という小さなパッケージに実装しました。lstautodedentアルファ版は以下から入手できます。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}*

関連情報