我想在一些基于 minted 的源代码后面放置一个网格。(这是用于编程考试;我想为学生提供一些写作指导……)。
以下是一些几乎可以正常工作的 MWE(基于 DrawBox 的在逐字文本上叠加红色矩形):
\documentclass{article}
\usepackage{minted}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\usetikzlibrary{backgrounds}
\newcommand\DrawGrid[2]{%
\begin{tikzpicture}[remember picture, overlay]
\draw[help lines]
([yshift=-0.25\baselineskip,xshift=0em]pic cs:#1)
grid [xstep=0.525em, ystep = \baselineskip]
([yshift=-0.25\baselineskip,xshift=+60em]pic cs:#2);
\end{tikzpicture}%
}
\begin{document}
\begin{minted}[escapeinside=??]{py}
?\tikzmark{start}?
def f(x):
y = x + 123456789012345678901234567879
return y
?\tikzmark{end}?
\end{minted}
\DrawGrid{start}{end}
\end{document}
它几乎给出了正确的结果,但水平线保持在文本行的中心,无论应用的 yshifts 值如何。这让我很惊讶。这里有几个位置(例如,TikZ 网格线,帮助生成布局的软件包?背景中的方格纸?) 认为 yshift 应该可以解决问题。事实上,yshift 确实会移动网格,但会保持水平线的对齐不变。
有什么方法可以将这些线向下移动,以便它们与文本行的底部对齐?
非常感谢您的意见,谢谢!
更新/可能的解决方案
根据以下两个答案,特别是基于 tcolorbox,我整理出了这个解决方案。它不是最优雅的解决方案,因为它仍然需要一些常数因素来让一切完美排列,但它对我来说很有效。
多谢!
\documentclass{article}
\usepackage{lipsum}
\usepackage{tcolorbox}
\tcbuselibrary{minted,skins,breakable}
\newtcblisting{pythongrid}[0]{
listing engine=minted,
breakable,
colback=white,
colframe=black!0,
listing only,
frame empty,
minted style=colorful,
minted language=python,
minted options={baselinestretch=1.5,linenos=true,fontsize=\large, numbersep=3mm,texcl=true},
left=0.7mm,
enhanced,
underlay={
\begin{tcbclipinterior}
\draw[help lines,
xstep=4*0.62em,
ystep=1.17*1.5*\baselineskip,
shift={([xshift=0.45em, yshift=1.5*1.3\baselineskip]interior.north west)}]
(interior.south west) grid (interior.north east);
\end{tcbclipinterior}
}
}
\begin{document}
\section{Python example}
\lipsum[1]
\begin{pythongrid}
# some comment line
def f(x):
y = x + 12345678901234567890123456787901234567879
return y
# end to check vertical alignment
\end{pythongrid}
\lipsum[1]
\end{document}
答案1
如果我可以添加一个替代解决方案:
合并围绕铸造环境的盒子和在盒子中生成网格有可能以更自动化的方式实现 OP 的期望。解决方案用于tcolorbox
创建框并在每个环境etoolbox
中“修补”框。minted
以下 MWE 产生:
我并不是它的忠实用户,tcolorbox
因此可能还有改进的空间(当然,这是值得欢迎的)
平均能量损失
\documentclass{article}
\usepackage{minted}
\usepackage[most]{tcolorbox}
\usepackage{etoolbox}
\newtcolorbox{mybox}{
breakable, enhanced,
arc=0pt, outer arc=0pt, %sets rounded corners to sharp
frame empty, %removes frame line
boxsep=0pt, left=0pt, top=0pt, bottom=0pt, %inner margins
colback=white, %backgound color
underlay={
\begin{tcbclipinterior}
\draw[help lines,
xstep=0.525em,
ystep=\baselineskip,
shift={([yshift=0.25\baselineskip]interior.north west)}]
(interior.south west) grid (interior.north east);
\end{tcbclipinterior}
}
}
\BeforeBeginEnvironment{minted}{\begin{mybox}}%
\AfterEndEnvironment{minted}{\end{mybox}}%
\begin{document}
\begin{minted}{py}
def f(x):
y = x + 123456789012345678901234567879
return y
\end{minted}
\end{document}
答案2
从绘图命令中删除yshift
并将移位添加到 的选项中tikzpicture
。
\begin{tikzpicture}%
[remember picture, overlay,
xshift=-0.45em,yshift=-0.25\baselineskip
]
\documentclass{article}
\usepackage{minted}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\usetikzlibrary{backgrounds}
\newcommand\DrawGrid[2]{%
\begin{tikzpicture}%
[remember picture, overlay,
xshift=-0.45em,yshift=-0.25\baselineskip
]
\draw[help lines]
(pic cs:#1)
grid [xstep=0.525em, ystep = \baselineskip]
([xshift=+60em]pic cs:#2);
\end{tikzpicture}%
}
\begin{document}
\begin{minted}[escapeinside=??]{py}
?\tikzmark{start}?
def f(x):
y = x + 123456789012345678901234567879
return y
?\tikzmark{end}?
\end{minted}
\DrawGrid{start}{end}
\end{document}