# Clipped minted environment inside a new PGF node shape

I want to make a file or page-like node shape in PGF and put a minted environment in that shape. See the image below:

There are a few issues. One is that the text is drawn over the border at the bottom and right. The other is that I'd like to be able to scale the contents of the minted environment by 0.5, say. I'd also like it if I could supply all the minted stuff as an attribute to the node or shape, something like \node [draw, shape=document, minted={python,class.py}] {};, but I'd settle if that isn't possible. I'm not attached to the minipage implementation in any way.

For the text on the border, I think probably the current line width could be subtracted from the minipage dimensions. I tried a scalebox inside the minipage for scaling, but the minted verbatim environments failed there. I really have no idea how to maybe pass the minted parameters as an attribute to the node.

Implementation:

\documentclass{standalone}

\usepackage{minted}

\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

\renewcommand{\familydefault}{\sfdefault}

\begin{filecontents}{class.py}
class MyClass:
variable = "blah"

def function(self):
print("This is a message inside the class.")

myobjectx = MyClass()

myobjectx.variable
\end{filecontents}

\makeatletter
\pgfdeclareshape{document}{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
% ... and possibly more
\backgroundpath{% this is new
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
% compute corner of ‘‘flipped page’’
\pgf@xc=\pgf@xb \advance\pgf@xc by-7.5pt % this should be a parameter
% construct main path
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
\pgfpathclose
\pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
}
}
\makeatother

\begin{document}

\begin{tikzpicture}

\node [draw, line width=3pt, shape=document] {\begin{minipage}[t][1cm][t]{4cm}\inputminted{python}{class.py}\end{minipage}};

\end{tikzpicture}

\end{document}

Something similar can be done with tcolorbox, although I don't know how to clip the listing.

\documentclass{article}
\usepackage[most, minted]{tcolorbox}

\tcbset{
mylisting/.style={
listing engine=minted, minted style=trac,
minted language=python, listing only,
enhanced,
boxrule=1mm,
colback=yellow!50,
colframe=yellow!20!black,
sharp corners,rounded corners=northeast,arc is angular,arc=3mm,
underlay={%
\path[fill=tcbcolback] ([yshift=-3mm]interior.north east)-|([xshift=-3mm]interior.north east);
\path[draw=tcbcolframe, shorten <=-0.5mm,shorten >=-0.5mm, line width=1mm] ([yshift=-3mm]interior.north east)-|([xshift=-3mm]interior.north east);},
#1
}
}

\begin{filecontents}{class.py}
class MyClass:
variable = "blah"

def function(self):
print("This is a message inside the class.")

myobjectx = MyClass()

myobjectx.variable
\end{filecontents}

\begin{document}
\tcbinputlisting{mylisting, listing file=class.py}
\end{document}

• This is useful, thanks. I may end up hacking the tcolorbox to set custom dimensions and put the listing back in a node.
– tsj
Sep 11, 2020 at 13:10