我想在 esminted
中创建多个列表tcolorbox
。类似于https://tex.stackexchange.com/a/396731,我想调整 的大小tcolorbox
以包含行号。但是,链接的解决方案使用 4mm 的固定偏移量,这对于 3 位或更多位数字的行号来说太短了;当我想使用 打印某些现有代码的部分内容时,很容易发生这种情况tcbinputlisting
。当列表中的所有行号都只使用一位或两位数字时,将偏移量设置为足够大以容纳 4 位数字的行号对我来说也不太好看。理想情况下,我希望根据最长行号的长度自动调整此偏移量(应始终是最后一个行号)。
这可能吗?或者我是否必须根据行号的数字使用不同的宏?
答案1
尝试一下这个不够优雅的尝试。
一些关键思想:
Verbatim
使用新计数器为每个环境分配一个唯一的编号verbatim@cnt
。- 获取每个环境的结束代码行号
Verbatim
(存储在计数器中FancyVerbLine
),将其转换为维度,并使其与唯一的环境编号链接起来。 - 将此关系写入辅助文件,该文件将在第二次编译时读取。
- 在每个自定义
tcolorbox
环境中,使用当前Verbatim
环境编号来检索相应的尺寸,然后使用它来设置/tcb/left
在 /tcb/overlay 中绘制的行号的左填充和背景颜色的偏移量。
\documentclass[11pt,letterpaper]{article}
\usepackage[most, minted]{tcolorbox}
\newcounter{verbatim@cnt}
\makeatletter
\AtEndEnvironment{Verbatim}{%
\stepcounter{verbatim@cnt}%
\protected@write\@auxout{}{%
\global\protect\@namedef{verbatim@numwidth@\the\c@verbatim@cnt}{%
\ifnum\c@FancyVerbLine>999
7.5mm%
\else\ifnum\c@FancyVerbLine>99
6mm%
\else
4mm%
\fi\fi
}%
}%
}
\def\minted@auto@numwidth#1{%
\ifcsname verbatim@numwidth@\the\numexpr\c@verbatim@cnt#1\relax\endcsname
\csname verbatim@numwidth@\the\numexpr\c@verbatim@cnt#1\relax\endcsname
\else
4mm%
\fi
}
\makeatother
\makeatletter
\newtcblisting{myminted}[2][]{%
listing engine=minted,
minted language=#2,
listing only,
breakable,
enhanced,
minted options = {
linenos,
breaklines=true,
breakbefore=.,
fontsize=\footnotesize,
numbersep=2mm
},
overlay={%
\begin{tcbclipinterior}
\fill[gray!25] (frame.south west) rectangle ([xshift=\dimexpr\minted@auto@numwidth{}\relax]frame.north west);
\end{tcbclipinterior}
},
% in "left", \c@verbatim@cnt is not stepped yet, hence the argument "+1"
left=\dimexpr\minted@auto@numwidth{+1}\relax,
#1
}
\makeatother
%\usepackage{unravel}
\providecommand\unravel[1]{#1}
\providecommand\unravelsetup[1]{}
\unravelsetup{max-action=1000, max-input=1000, max-output=100}
\begin{document}
\begin{myminted}[minted options app={firstnumber=8}]{c}
#include <stdio.h>
void main ()
{
printf("hello world");
}
\end{myminted}
\begin{myminted}[minted options app={firstnumber=98}]{c}
#include <stdio.h>
void main ()
{
printf("hello world");
}
\end{myminted}
\begin{myminted}[minted options app={firstnumber=998}]{c}
#include <stdio.h>
void main ()
{
printf("hello world");
}
\end{myminted}
\end{document}