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