Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
ch-tikz
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Christoffer Holm
ch-tikz
Commits
240c88c2
Commit
240c88c2
authored
4 months ago
by
Christoffer Holm
Browse files
Options
Downloads
Patches
Plain Diff
Added a proof-of-concept implementation of \drawlist which draws linked lists
parent
6ff0e800
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ch-tikz.tex
+238
-0
238 additions, 0 deletions
ch-tikz.tex
with
238 additions
and
0 deletions
ch-tikz.tex
+
238
−
0
View file @
240c88c2
...
@@ -828,3 +828,241 @@
...
@@ -828,3 +828,241 @@
\drawarray
@NextArg
\drawarray
@NextArg
}
}
\makeatother
\makeatother
%%%% draw list %%%%
\makeatletter
%% TODO: Implement directions and overflow handling
\newcommand
{
\drawlist
}
[3][]
{
%
%% Draw an linked list inside a tikzpicture, highly customizable.
%%
%% Parameters:
%%
%% #1 (optional): Options
%% #2: List name
%% #3: Index 0 content
%% #N: index (N-3) content
%%
%% Options:
%%
%% x = <x position>:
%% sets the x position of the first element.
%%
%% y = <y position>:
%% sets the y position of the first element.
%%
%% position = <coordinate or position>: This option
%% overrides the x and y settings. Allows the user
%% to specify a specific position which could be a
%% named coordinate. For example:
%%
%% \drawlist[anchor=north, position=node.south]{my list}{0}{1}{2}
%%
%% will place an list directly underneath the named
%% position 'node'.
%%
%% anchor = <tikz anchor>:
%% sets which anchor should be used when placing
%% the first element node.
%%
%% element = {<node styling>}:
%% Passes the styling options to each element
%% node.
%%
%% element size = <size>:
%% Set the minimum size of each element.
%%
%% fill = <color>:
%% Set a fill color for *all* the elements.
%%
%% show index:
%% Option that inserts a label for each index in
%% the list as well, the position of the labels
%% are set to 'south' by default. This is disabled
%% by default.
%%
%% index start = <start index>:
%% Set what index the list should start at (0 by default).
%%
%% index position = <left|right|up|down|west|east|north|south>:
%% Specify which side of the nodes the index label
%% should be placed. By default set to 'south'
%%
%% index style = {<node styling>}:
%% Passes the styling options to each index node.
%%
%% Example:
%%
%% \begin{tikzpicture}
%% \drawlist[element size=1cm]{my list}{'a'}{'b'}{'c'}
%% \drawlist[x=4cm, y=0cm]{other list}{1}{2}{34}
%% \end{tikzpicture}
%%
\pgfkeys
{
/drawlist, default, #1
}
%
\edef\list
@Name
{
#2
}
%
\edef\list
@Nodes
{}
%
\pgfmathtruncatemacro
{
\list
@Index
}{
\list
@StartIndex
}
%
%% Fix the coordinate either based on position or specific x and y coords
\ifx\list
@Position
\undefined
%
\coordinate
(list origin) at (
$
(
\list
@X,
\list
@Y
)
+
(
\list
@xshift,
\list
@yshift
)
$
);
%
\else
%
\coordinate
(list origin) at (
$
(
\list
@Position
)
+
(
\list
@xshift,
\list
@yshift
)
$
);
%
\fi
%
% Once the initial position is set, undef it so that it is
% not defined for the next \drawlist
\undef\list
@Position
\drawlist
@Element[list origin]
{
#3
}
%
\pgfmathtruncatemacro
{
\list
@Index
}{
\list
@Index + 1
}
%
%% Goto next argument
\drawlist
@NextArg
%
}
\newcommand
{
\drawlistset
}
[1]
{
%
%% Allow the user to set specific keys and generate styles
%% etc. for the \drawlist command.
%%
%% Parameters:
%%
%% #1: pgfkey statements, all occuring in the
%% /drawlist family by default.
%%
%% Example:
%%
%% \drawlistset{my index/.style={show index, index style={font=\tiny\ttfamily}}}
%% \begin{tikzpicture}
%% \drawlist[my index]{my list}{1}{2}{3}
%% \end{tikzpicture}
%%
\pgfkeys
{
/drawlist, #1
}
%
}
%% Options and settings for \drawlist
\pgfkeys
{
%% Create a family for \drawlist
/drawlist/.is family,
%% set /drawlist as the current family
/drawlist,
%% Assign the default values for each key
default/.style =
{
x = 0,
y = 0,
offset=0.5cm,
xshift = 0,
yshift = 0,
anchor = center,
index style=
{}
,
index start=0,
index position=south,
element =
{}
,
element size = 1.5em,
container =
{}
,
fill=none,
}
,
%% x position of list
x/.estore in =
\list
@X,
%% y position of list
y/.estore in =
\list
@Y,
%% the offset between each node
offset/.estore in =
\list
@Offset,
position/.estore in =
\list
@Position,
%% shift operations
xshift/.estore in =
\list
@xshift,
yshift/.estore in =
\list
@yshift,
%% Which anchor of the first element should be used
anchor/.estore in =
\list
@Anchor,
%% Custom element settings
element/.code =
{
\tikzset
{
list element/.style=
{
#1
}}}
,
%% element size determines the size of the element
element size/.estore in =
\list
@ElementSize,
%% Custom styling for the container node
container/.code =
{
\tikzset
{
list container/.style=
{
#1
}}}
,
%% Show the index for each element
show index/.code =
{
\def\list
@ShowIndex
{
1
}}
,
index start/.estore in =
\list
@StartIndex,
%
%% Position of the styling: takes the same options as 'direction'
index position/.style =
{
directions/#1/.get =
\list
@IndexPosition,
%
opposites/#1/.get =
\list
@IndexAnchor
}
,
%% Customize index style
index style/.code =
{
\tikzset
{
list index/.style=
{
#1
}}}
,
%% Customized styling
fill/.estore in =
\list
@Fill,
%
%% define each option for direction
/drawlist,
directions/.cd,
east/.initial = east,
west/.initial = west,
north/.initial = north,
south/.initial = south,
right/.initial = east,
left/.initial = west,
up/.initial = north,
down/.initial = south,
%% define the different opposite directions
/drawlist,
opposites/.cd,
east/.initial = west,
west/.initial = east,
north/.initial = south,
south/.initial = north,
right/.initial = west,
left/.initial = east,
up/.initial = south,
down/.initial = north
}
\newcommand
{
\drawlist
@Element
}
[2][
$
(
\ExpandWithSpaceBetween
{
\list
@Name
}{
\list
@PrevIndex
}
.east
)
+
(
\list
@Offset,
0
)
$
]
{
%
%% Save the nodes in a list so that we can pass to fit later
\xdef\list
@Nodes
{
\list
@Nodes(
\ExpandWithSpaceBetween
{
\list
@Name
}{
\list
@Index
}
)
}
%
\edef\list
@CurrentValue
{
\ExpandWithSpaceBetween
{
\ExpandWithSpaceBetween
{
\list
@Name
}{
value
}}{
\list
@Index
}}
\edef\list
@CurrentNext
{
\ExpandWithSpaceBetween
{
\ExpandWithSpaceBetween
{
\list
@Name
}{
next
}}{
\list
@Index
}}
\pgfmathtruncatemacro
{
\list
@PrevIndex
}{
\list
@Index - 1
}
%
\node
[minimum width=
\list
@ElementSize,
%
minimum height=
\list
@ElementSize,
%
fill=
\list
@Fill,
%
rectangle, draw=black, anchor=west,
%
list element]
%
(
\list
@CurrentValue)
%
at (#1)
{
#2
}
;
%
\node
[minimum width=
\list
@ElementSize,
%
minimum height=
\list
@ElementSize,
%
xshift=-
\pgflinewidth
,
%
fill=
\list
@Fill,
%
rectangle, draw=black, anchor=west,
%
list element]
%
(
\list
@CurrentNext)
%
at (
\list
@CurrentValue.east)
{}
;
%
\node
[inner sep=0, outer sep=0, fit=(\list@CurrentValue)(\list@CurrentNext)]
%
(
\ExpandWithSpaceBetween
{
\list
@Name
}{
\list
@Index
}
)
{}
;
%
\ifx\list
@ShowIndex
\undefined
%
% Do nothing
\else
%
\node
[list index, anchor=\list@IndexAnchor]
%
(
\ExpandWithSpaceBetween
{
\list
@Name label
}{
\list
@Index
}
)
%
at (
\ExpandWithSpaceBetween
{
\list
@Name
}{
\list
@Index
}
.
\list
@IndexPosition)
{
\list
@Index
}
;
%
\fi
%
}
%% Check if next character after the macro is a opening
%% curly brace, if it is expand \drawlist@GobbleArg to
%% process the content of those braces, otherwise: generate
%% the container node.
\newcommand
{
\drawlist
@NextArg
}{
%
\@
ifnextchar
\bgroup
{
%
\drawlist
@GobbleArg
%
}{
%
\node
[inner sep=0, outer sep=0,
%
list container, fit=
\list
@Nodes] (
\list
@Name)
{}
;
%
}
%
}
%
\newcommand
{
\drawlist
@GobbleArg
}
[1]
{
%
\drawlist
@Element
{
#1
}
%
\draw
[->]
(
\ExpandWithSpaceBetween
{
\ExpandWithSpaceBetween
{
\list
@Name
}{
next
}}{
\list
@PrevIndex
}
.center) -- (
\ExpandWithSpaceBetween
{
\list
@Name
}{
\list
@Index
}
);
\pgfmathtruncatemacro
{
\list
@Index
}{
\list
@Index + 1
}
%
\drawlist
@NextArg
}
\makeatother
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment