lstlistingをミニページに配置するとxleftmargin設定が壊れる

lstlistingをミニページに配置するとxleftmargin設定が壊れる

灰色のボックス内にリストを表示し、その両側にスペースを設けたいです。次のように
設定しました。\lstset

\lstset{basicstyle=\ttfamily,keywordstyle=\bfseries
,commentstyle=\itshape\color{green},
xleftmargin=\parindent,  <<--- minipage breaks this setting.
backgroundcolor=\color{light-gray},
framexleftmargin=\parindent,
framextopmargin=6pt,
framexbottommargin=6pt, 
frame=tb, framerule=0pt}

短いリストにページ区切りを入れたくありません。ミニページを使用してこれを修正します。ただし、これにより余白設定が壊れます。

\documentclass[]{article}
\usepackage{float}
\usepackage{listings} 
\usepackage{color}
\usepackage[margin=1in]{geometry}
%\usepackage{fontspec}
%\setmonofont{Bitstream Vera Sans Mono}[Scale=0.85]
\definecolor{light-gray}{gray}{0.95}
\definecolor{darkgreen}{RGB}{0,64,0}
\lstset{basicstyle=\ttfamily,keywordstyle=\bfseries,commentstyle=\itshape    \color{darkgreen}, xleftmargin=\parindent,backgroundcolor=\color{light-gray},
framexleftmargin=\parindent,
framextopmargin=6pt,
framexbottommargin=6pt, 
frame=tb, framerule=0pt}
\begin{document}
\section{listing}
\noindent
\begin{minipage}[H]{\linewidth}
\begin{lstlisting}[language=Delphi,caption={get the next block},label={ref:bitset_next},
                   keywords={function,int,asm,end},xleftmargin=\parindent]
function bitset.next(previous_block_index: int): int;
//***************************************************************************
//pseudo code:
//***************************************************************************
//Load the bitset into a register
//shift out the bits that we've already processed
//count the number of inactive blocks
//next_block_index = previous_block_index + inactive_blocks_inbetween + 1
asm
  //rcx = self = pointer to bitset
  //edx = previous_block_index
  mov rax,[rcx]            //rax = bitset.
  lea ecx,[edx+1]          //go to the next bit    
  shr rax,cl               //shift out the bits we've already processed
  tzcnt rax,rax            //count empty positions to skip
  add eax,ecx              //return (prev+1+empty positions found)
end;  
\end{lstlisting}
\end{minipage}
\end{document}

これにより、次の出力が生成されます。

ここに画像の説明を入力してください

\noindentとを削除すると、minipage次のようになります。

ここに画像の説明を入力してください

リスト内に正しいインデントがあります。リスト内にページ区切りを入れずに、灰色のボックス内のスペースを正しく維持するにはどうすればよいでしょうか。

私はもう試した

\begin{lstlisting}[float,floatplacement=H]

しかし、上記と同じ出力が生成されますminipage

答え1

@egreg に感謝します。ここで答えを見つけました:ミニページで同じパースキップを保存する方法

上記のリンクされた回答をコピーして貼り付けるだけでは、テキストの残りの部分を超えて灰色の背景が表示されるため、いくつかの調整が必要になります。

\parindent修正方法は、内の変数を置き換える新しい -fixed- 長さを定義することですminipage

次の変更により問題は解決されます。

\newlength{\listingindent}                %declare a new length
\setlength{\listingindent}{\parindent}    %make it a fixed version of \parindent
\lstset{basicstyle=\ttfamily,keywordstyle=\bfseries,commentstyle=\itshape\color{darkgreen},backgroundcolor=\color{light-gray},
xleftmargin=\listingindent,         <<-- make fixed 
framexleftmargin=\listingindent,    <<-- make fixed
framextopmargin=6pt,
framexbottommargin=6pt, 
frame=tlrb, framerule=0pt,linewidth=\linewidth}
....
\noindent      <<-- force noident, or the frame will appear out of bounds
\begin{minipage}[H]{\linewidth}
\begin{lstlisting}[language=Delphi,caption={get the next block},label={ref:bitset_next},
                   keywords={function,int,asm,end}]
function bitset.next(previous_block_index: int): int;
...
\end{lstlisting}
\end{minipage}

今は次のようになっています:

ここに画像の説明を入力してください

リストの途中でページが区切られたり、背景がずれたりすることはありません。

関連情報