%% 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,
	},
}
