%% memorygraphs.tex
%% Copyright 2018-2019 C. Staps
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status “maintained”.
%
% The Current Maintainer of this work is C. Staps.
%
% This work consists of the files memorygraphs.sty and the documentation in
% memorygraphs.tex and example-fibonacci.tex.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{memorygraphs}[2019/01/06 v0.1.1 Draw memory graphs using TikZ]

\RequirePackage{tikz}
\usetikzlibrary{arrows.meta,calc,positioning,shapes}

\def\pgfaddtoshape#1#2{%
       \begingroup
       \def\pgf@sm@shape@name{#1}%
       #2%
       \endgroup
}

\pgfaddtoshape{rectangle split}{%
       \pgfmathsetcount\c@pgf@counta{\pgfkeysvalueof{/pgf/rectangle split parts}}%
       \edef\parts{\the\c@pgf@counta}%
       \expandafter\xdef\csname pgf@anchor@rectangle split@head north east\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle split@one split north\endcsname}%
       \expandafter\xdef\csname pgf@anchor@rectangle split@head south east\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle split@one split south\endcsname}%
       \expandafter\xdef\csname pgf@anchor@rectangle split@head north west\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle split@north west\endcsname}%
       \expandafter\xdef\csname pgf@anchor@rectangle split@head south west\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle split@south west\endcsname}%
       \pgfmathloop%
               \ifnum\pgfmathcounter>\parts%
               \else%
                       \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
                       \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space center\endcsname{%
                               \expandafter\noexpand\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space north\endcsname%
                               \pgf@ya=\pgf@y%
                               \expandafter\noexpand\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space south\endcsname%
                               \advance\pgf@ya by-\pgf@y%
                               \advance\pgf@y by.5\pgf@ya}%
                       \c@pgf@counta=\pgfmathcounter%
                       \advance\c@pgf@counta by-1\relax%
                       \edef\name{\ifnum\c@pgf@counta=0 head\else arg \the\c@pgf@counta\fi}%
                       \expandafter\xdef\csname pgf@anchor@rectangle split@\name\endcsname{%
                               \expandafter\noexpand\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\endcsname}%
                       \pgfutil@for\pgf@lib@sh@rs@temp:={center,north,east,south,west}\do{%
                               \expandafter\xdef\csname pgf@anchor@rectangle split@\name\space\pgf@lib@sh@rs@temp\endcsname{%
                                       \expandafter\noexpand\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space\pgf@lib@sh@rs@temp\endcsname}}%
       \repeatpgfmathloop%
}
\pgfaddtoshape{rectangle}{%
       \expandafter\xdef\csname pgf@anchor@rectangle@head north east\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle@north east\endcsname}%
       \expandafter\xdef\csname pgf@anchor@rectangle@head south east\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle@south east\endcsname}%
       \expandafter\xdef\csname pgf@anchor@rectangle@head north west\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle@north west\endcsname}%
       \expandafter\xdef\csname pgf@anchor@rectangle@head south west\endcsname{%
               \expandafter\noexpand\csname pgf@anchor@rectangle@south west\endcsname}%
}

\newcommand{\memorygraphs@arg}[1]{%
       \pgfmathsetcount\c@pgf@counta{#1}%
       \advance\c@pgf@counta by1\relax%
       \expandafter\nodepart\expandafter{\expandafter\pgf@lib@sh@toalpha\expandafter{\the\c@pgf@counta}}}

\newdimen\memorygraphs@marklength
\memorygraphs@marklength=4pt

\tikzset{
       memory graph/.style={
               node distance=1.5em,
       },
       every block/.style={},
       block/.style={
               draw,
               text height=height("I"),
               text depth=depth("I"),
               anchor=mid,
               every block,
       },
       block/.append code={%
               \let\arg\memorygraphs@arg%
               \gdef\memorygraphs@arity{0}%
       },
       block mark north east/.style={
               append after command={
                       \pgfextra
                               \pgfinterruptpath
                               \draw[#1]
                                       ($(\tikzlastnode.head north east)-(\ifnum\memorygraphs@arity=0 .5\pgflinewidth\else0\fi,.5\pgflinewidth)$)
                                       -- +(0,-\memorygraphs@marklength)
                                       -- ($(\tikzlastnode.head north east)-(\ifnum\memorygraphs@arity=0 .5\pgflinewidth\else0\fi+\memorygraphs@marklength,.5\pgflinewidth)$)
                                       -- cycle;
                               \endpgfinterruptpath
                       \endpgfextra
               },
       },
       block mark south east/.style={
               append after command={
                       \pgfextra
                               \pgfinterruptpath
                               \draw[#1]
                                       ($(\tikzlastnode.head south east)+(\ifnum\memorygraphs@arity=0 -.5\pgflinewidth\else0\fi,.5\pgflinewidth)$)
                                       -- +(0,\memorygraphs@marklength)
                                       -- ($(\tikzlastnode.head south east)+(\ifnum\memorygraphs@arity=0 -.5\pgflinewidth\else0\fi-\memorygraphs@marklength,.5\pgflinewidth)$)
                                       -- cycle;
                               \endpgfinterruptpath
                       \endpgfextra
               },
       },
       block mark north west/.style={
               append after command={
                       \pgfextra
                               \pgfinterruptpath
                               \draw[#1]
                                       ($(\tikzlastnode.head north west)+(.5\pgflinewidth,-.5\pgflinewidth)$)
                                       -- +(0,-\memorygraphs@marklength)
                                       -- ($(\tikzlastnode.head north west)-(-.5\pgflinewidth-\memorygraphs@marklength,.5\pgflinewidth)$)
                                       -- cycle;
                               \endpgfinterruptpath
                       \endpgfextra
               },
       },
       block mark south west/.style={
               append after command={
                       \pgfextra
                               \pgfinterruptpath
                               \draw[#1]
                                       ($(\tikzlastnode.head south west)+(.5\pgflinewidth,.5\pgflinewidth)$)
                                       -- +(0,\memorygraphs@marklength)
                                       -- ($(\tikzlastnode.head south west)+(.5\pgflinewidth+\memorygraphs@marklength,.5\pgflinewidth)$)
                                       -- cycle;
                               \endpgfinterruptpath
                       \endpgfextra
               },
       },
       arity/.style={
               block,
               rectangle split,
               rectangle split parts=#1+1,
               rectangle split horizontal,
               rectangle split every empty part={},
               rectangle split empty part width=.2em,
       },
       arity/.append code={%
               \pgfmathsetcount\c@pgf@counta{\pgfkeysvalueof{/pgf/rectangle split parts}}%
               \ifnum\c@pgf@counta=0\else\advance\c@pgf@counta by-1 \fi
               \xdef\memorygraphs@arity{\the\c@pgf@counta}%
       },
 ref/.style={
               {Circle[length=3pt]}-Latex,
               shorten <=-1.5pt,
               rounded corners=.2em,
       },
}