6

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

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:

enter image description here

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
3

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
  ]

enter image description here

\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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.