# Put a letter-aligned grid behind a minted source code snippet?

I'd like to put a grid behind some minted-based source code. (It is for an exam in programming; I'd like to give students some guidelines where to write....).

Here is an MWE of something almost working (based on DrawBox from Overlay red rectangles on top of verbatim text):

\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}


It almost gives the right result, but the horizontal lines stay in the center of the text lines, irrespective the value of the yshifts applied. This is surprising to me. A couple of positions here (e.g., TikZ grid lines, A package to help with layout generation? Graph paper in the background?) argue that yshift should do the trick. In fact, yshift does shift the grid, but keeps the alignment of the horizontal lines fixed.

Is there any way to shift those lines downward so that they align with the bottom of the text lines?

Any input much appreciated, thanks!

# Update/Possible solution

Based on the two answers below, and in particular based on tcolorbox, I put together this solution. It isn't the most elegant one as it still needs some playing with constant factors to get everything lined up perfectly, but it works for me.

Thanks a lot!

\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}


If I may add an alternative solution:

Combining Box around minted environment with Generating grid in a box it is possible to achieve what the OP desires in an even more automatic way. The solution uses tcolorbox to create the box and etoolbox to "patch" the box around every minted environment.

The below MWE produces:

I'm not a huge user of tcolorbox so that may have room for improvement (which is welcome, of course)

# MWE

\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}

• Thats a great approach , thanks a lot - I didn't know about tcolorbox. I fiddled a bit more and ended up with the following MWE, which perfectly suits my needs. – Holger Karl Jan 5 '17 at 13:41
• You should maybe post the MWE you came up with as an answer. I really like it, as it uses tcolorbox's features better. Also, feel free to accept your own answer afterwards (I think you have to wait a couple of days to accept it though) I won't be mad. ;D – Guilherme Zanotelli Jan 5 '17 at 14:11

Remove the yshift from the draw commands and add the shift to the options of 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}

• So easy... guess I was blind there :-) - but the tcolorbox solution is very convenient. – Holger Karl Jan 5 '17 at 13:40