在 itemize 内的颜色框中使用 Verbatim 时出现不必要的缩进

在 itemize 内的颜色框中使用 Verbatim 时出现不必要的缩进

我想将带有背景颜色的Verbatimfrom包放在 里面。为了实现这一点,我将 Verbatim 放在 里面。fvextraitemizecolorbox

不幸的是,存在两个问题:

  1. 颜色框内部有不需要的凹痕;
  2. 颜色框的背景超出了线宽

我已经使用 解决了问题 2,parbox但无法解决缩进问题。似乎 Verbatim 知道它在环境中itemize,并想缩进其内容……但整个颜色框已经缩进。

以下是该问题的打印版:

打印问题,显示错误出在哪里!

这有可能吗...也许是负边距,与当前项目缩进的大小相同?但我真的迷路了。

以下是代码:

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\usepackage[dvipsnames]{xcolor}
\definecolor{bgcolor}{cmyk}{0,0.01,0.1,0}
\usepackage{fvextra}
\begin{document}
\begin{itemize}
\item
    Some text here... I want to keep writing so that the text wraps to the next line.
    This is needed, because I want to see where the line ends, and know what is the line width.

    \begin{Verbatim}
This is OK! But I want a bgcolor...
    \end{Verbatim}

    \setbox0\vbox\bgroup
    \begin{Verbatim}
This has an extra indent, and also the right side goes
beyond the line width... BAD
    \end{Verbatim}
    \egroup\fboxsep0pt \colorbox{bgcolor}{\usebox0}

    \setbox0\vbox\bgroup
    \begin{Verbatim}
I was unable to find a way to un-indent this text
    \end{Verbatim}
    \egroup\fboxsep0pt \colorbox{bgcolor}{\parbox{\linewidth}{\usebox0}}

    Some more text

\begin{itemize}
\item
    sub text

        \setbox0\vbox\bgroup
        \begin{Verbatim}
Indentation proportional to item level,
but the colorbox is already indented.
        \end{Verbatim}
        \egroup\fboxsep0pt \colorbox{bgcolor}{\parbox{\linewidth}{\usebox0}}
\end{itemize}

\end{itemize}
\end{document}

答案1

我会使用 LaTeX 功能而不是\vbox

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\usepackage[dvipsnames]{xcolor}
\definecolor{bgcolor}{cmyk}{0,0.01,0.1,0}
\usepackage{fvextra}
\usepackage{enumitem}

\newsavebox{\verbbgbox}
\newenvironment{bgVerbatim}
 {%
  \VerbatimEnvironment
  \begin{lrbox}{\verbbgbox}%
  \begin{minipage}[t]{\linewidth}%
  \begin{Verbatim}%
 }
 {%
  \end{Verbatim}%
  \end{minipage}%
  \end{lrbox}%
  \setlength{\fboxsep}{0pt}%
  \par\addvspace{\topsep}
  \noindent\colorbox{bgcolor}{\usebox\verbbgbox}%
  \par\vspace{\dp\strutbox}\addvspace{\topsep}
 }

\begin{document}

Some text here. I want to keep writing so that the text wraps 
to the next line. This is needed, because I want to see where the 
line ends, and know what is the line width.

\begin{bgVerbatim}
A full width Verbatim
A full width Verbatim
A full width Verbatim
\end{bgVerbatim}

\begin{itemize}[parsep=0pt]
\item Some text here. I want to keep writing so that the text wraps 
      to the next line. This is needed, because I want to see where the 
      line ends, and know what is the line width.

\begin{Verbatim}
This is OK! But I want a bgcolor...
\end{Verbatim}

Some more text

\begin{bgVerbatim}
This has an extra indent, and also the right side goes
beyond the line width... BAD
\end{bgVerbatim}

Some more text

\begin{itemize}[parsep=0pt]
\item sub text

\begin{bgVerbatim}
Indentation proportional to item level,
but the colorbox is already indented.
\end{bgVerbatim}

\item another item
\end{itemize}

\end{itemize}

\end{document}

在此处输入图片描述

答案2

我想到了两个可能的解决方案......不知道它是否适用于其他有类似问题的人的 100% 的情况,因为我不是 LaTeX 专家。

我所做的是Verbatim用代码替换环境,解决了我所有的问题,包括不必要的缩进。

SOLUTION START下面的每一段代码都有/这样的注释,SOLUTION END 方便大家查看具体代码在哪里。

解决方案 1:缩进嵌套 Verbatim

此解决方案包括在实际之前添加负水平间距Verbatim。它将取消颜色框内的文本缩进。

为此,我查看了itemize和的源代码enumerate,以了解它们如何跟踪嵌套级别。它们使用变量\@itemdepth\@enumdepth

此外,我在本问答中发现,我可以使用\leftmargin来了解一个缩进级别的大小。这存在一个问题,因为我见过有人为每个嵌套级别单独设置缩进度量。当前解决方案是将 乘以总和\leftmargin\@itemdepth + \@enumdepth这是一个问题,但它为我解决了问题。

它看起来是这样的:

该图显示了解决方案 1 的样子

解决方案 1 的完整代码:

\documentclass[]{article}
\usepackage[utf8]{inputenc}

\usepackage[dvipsnames]{xcolor}
\definecolor{codebgcolor}{cmyk}{0,0.01,0.1,0}

\usepackage{xfp}
\makeatletter\def\autogobble{\fpeval{(\@itemdepth+\@enumdepth+1)}}\makeatother

% SOLUTION START
\usepackage{fvextra}
\makeatletter
\let\oldv\Verbatim
\def\Verbatim{%
    \setbox0\vbox\bgroup\oldv%
}
\def\unindent{%
    \hspace{-\dimexpr\leftmargin*(\@itemdepth+\@enumdepth)\relax}%
}
\let\oldendv\endVerbatim
\def\endVerbatim{%
    \oldendv\egroup\fboxsep0pt \par\colorbox{codebgcolor}{%
        \parbox{\linewidth}{%
            \unindent\usebox0%
        }%
    }\par%
}
\makeatother
% SOLUTION END

\begin{document}
    \begin{itemize}
        \item
        Some text here... I want to keep writing so that the text
        wraps to the next line, and we can see what is the line
        width.
        \begin{Verbatim}[gobble=\autogobble]
        This is OK!
        \end{Verbatim}
        Some more text
        \begin{itemize}
            \item
            sub text
            \begin{Verbatim}[gobble=\autogobble]
            Also OK!
            \end{Verbatim}
        \end{itemize}
    \end{itemize}
\end{document}

解决方案 2:全宽嵌套 Verbatim

此解决方案包括消除嵌套itemize/内单个段落的缩进enumerate,并将 放在colorbox此段落内。由于颜色框中的内容已缩进,因此内容将显示在相同的缩进级别,但颜色框将具有整行的宽度……背景本身不会缩进。

它看起来是这样的:

该图显示了解决方案 2 的样子

解决方案 2 的完整代码:

\documentclass[]{article}
\usepackage[utf8]{inputenc}

\usepackage[dvipsnames]{xcolor}
\definecolor{codebgcolor}{cmyk}{0,0.01,0.1,0}

\usepackage{xfp}
\makeatletter\def\autogobble{\fpeval{(\@itemdepth+\@enumdepth+1)}}\makeatother

% SOLUTION START
\usepackage{fvextra}
\makeatletter
\let\oldv\Verbatim
\def\Verbatim{%
    \setbox0\vbox\bgroup\oldv%
}
\newcommand\NoIndent[1]{%
    \begingroup\par\parshape0#1\par\endgroup%
}
\let\oldendv\endVerbatim
\def\endVerbatim{%
    \oldendv\egroup\fboxsep0pt \NoIndent{%
        \colorbox{codebgcolor}{%
            \usebox0%
        }%
    }%
}
\makeatother
% SOLUTION END

\begin{document}
    \begin{itemize}
        \item
        Some text here... I want to keep writing so that the text
        wraps to the next line, and we can see what is the line
        width.
        \begin{Verbatim}[gobble=\autogobble]
        This is OK!
        \end{Verbatim}
        Some more text
        \begin{itemize}
            \item
            sub text
            \begin{Verbatim}[gobble=\autogobble]
            Also OK!
            \end{Verbatim}
        \end{itemize}
    \end{itemize}
\end{document}

额外:\autogobble

另外,我还找到了一种在内部缩进 TeX 代码的方法Verbatim,并在渲染 PDF 时删除缩进。

有一个参数gobble=N,其中 N 是一个数字,该数字Verbatim 可识别,用于从每行的开头删除那么多 N 个字符。

因此我使用\@itemdepth\@enumdepth变量来计算 TeX 代码中所需的嵌套量,并执行此\autogobble命令将其从呈现的 PDF 中删除:

\usepackage{xfp}
\makeatletter\def\autogobble{\fpeval{(\@itemdepth+\@enumdepth+1)}}\makeatother

相关内容