%% moeptikz-doc.tex
%% Copyright 2015-2026 Stephan M. Guenther
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%   https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Stephan M. Guenther.
%
% This work consists of the files moeptikz.sty, moeptikz-doc.tex,
% README.md and Makefile and the derived file moeptikz-doc.pdf.
%
% The complete work and its issue tracker are available at
%   https://github.com/moepinet/moeptikz

\documentclass{scrartcl}

\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{xspace}

\usepackage[shading]{moeptikz}
\usepackage{siunitx}
\usepackage{calc}
\usepackage{inconsolata}

\usepackage[%
	a4paper,
	top=20mm,
	bottom=20mm,
	left=20mm,
	right=20mm,
]{geometry}

\usetikzlibrary{calc}

\newcommand*{\TikZ}{Ti\textit{k}Z\xspace}
\newcommand*{\moeptikz}{mo\reflectbox{e}p\TikZ}
\newcommand*{\nodelabel}[1]{{\scriptsize\bfseries\ttfamily #1}}

\title{The \moeptikz{} package}
\subtitle{a library for typesetting computer networks}
\author{Stephan M. G\"unther}
% version and date as given by \ProvidesPackage{moeptikz}[<date> <version> <info>],
% parsed like \GetFileInfo of the doc package (a missing field shows as ?)
\makeatletter
\def\moeptikz@fileinfo#1 #2 #3\relax#4\relax{\date{#2, #1}}
\expandafter\expandafter\expandafter\moeptikz@fileinfo
	\csname ver@moeptikz.sty\endcsname\relax? ? \relax\relax
\makeatother

% \presentnode[<text box>]{<shape>}{<text>}[<options>]
% <text box> encloses the text, \colorbox{white} by default (hides the lines
% behind the text below a shape).  The <options> are applied after the minimum
% size of 2cm and may override it.  All nodes get the same text: the internet
% cloud grows with its text, hence the nodes would differ in size otherwise.
% Two copies of the node over the gray lines carry the four red crosses, the
% cross below first: the text box of the second copy hides it wherever the
% node text sits at the same place (all shapes but internet and key).
\NewDocumentCommand{\presentnode}{O{\colorbox{white}} m m O{}}{%
	\begin{tikzpicture}[x=1mm,y=1mm,
			presented/.style={#2,minimum size=2cm,#4,font=\footnotesize\ttfamily}]
		\node[presented] (x) at (0,0) {#1{#3}};
		\foreach \x in {0,1,...,7} {
			\node[circle,fill=black!40,minimum width=1mm,inner sep=0pt]
				(p\x) at ($(x)+(\x*45:20)$) {};
			\draw[line width=1pt,black!40] (x) -- (p\x);
		}
		\node[rectangle,draw=black!40,line width=.5pt,inner sep=0pt,minimum
			size=4cm] at (x) {};
		\node[presented,label=below:\color{red}$\times$] at (0,0) {#1{#3}};
		\node[presented,label=above:\color{red}$\times$,label=left:\color{red}$\times$,
			label=right:\color{red}$\times$] at (0,0) {#1{#3}};
	\end{tikzpicture}
}

% \examplenetwork{<spacing>}
% The network of the first two figures, which differ only in the vertical
% distance <spacing> (in cm) between the clients.
\newcommand*{\examplenetwork}[1]{%
	\begin{tikzpicture}[x=1cm,y=1cm]
		\node[internet,puffs=13,minimum width=3cm,empty,line width=1pt]
			(inet) at (4.25,0) {\nodelabel{Internet}};
		\node[router] (r1) at (.5,0) {};
		\node[router,minimum size=5mm] (r2) at (inet.west) {};
		\node[switch] (s1) at (-2,0) {};
		\node[server,minimum size=12mm,label=below:\nodelabel{heimdall.moepi.net}]
			(server1) at (-2,-1.5) {};
		\node[server,minimum size=12mm,label=above:\nodelabel{dc.poorcompany.net}]
			(server2) at (-2,1.5) {};
		\node[server,minimum size=12mm,label=above:\nodelabel{8.8.8.8}]
			(server3) at (8,0) {};

		\foreach \x in {1,2,3} {
			\node[client,label=left:\nodelabel{PC\,\x}]
				(c\x) at ($(s1)+(-2.8,2.6-#1*\x)$) {};
			\draw[black,line width=1pt] (c\x) -- (s1);
		}

		\draw[black,line width=1pt] (s1) -- (r1);
		\draw[black,line width=1pt] (s1) -- (server1);
		\draw[black,line width=1pt] (s1) -- (server2);
		\draw[black,line width=1pt] (inet) -- (server3);
		\draw[black,line width=1pt] (r1) -- (r2.west);

		\draw[dashed,black,line width=1pt] (r1.west) -- ++(-1,1)
			node[above right] {\nodelabel{eth0: 172.16.0.1/24}} -- ++(3,0);

		\draw[line width=1.5pt,-latex,black!40] (r1) to[bend right]
			node[below,yshift=-2mm,messageclosed,minimum size=5mm] {} (server3);
	\end{tikzpicture}%
}

% \example[<width>][<setup>]{<code>}
% Draws the TikZ <code> in a box of <width> (1.75cm by default) and lists it
% next to the picture as \verb would.  The optional <setup> is drawn first, but
% not listed.  <code> is a verbatim argument (one line, balanced braces), hence
% \example cannot be used in the argument of another command.
\makeatletter
\NewDocumentCommand{\example}{O{1.75cm} o v}{%
	\par\vskip\baselineskip
	\noindent
	\begin{minipage}{#1}%
		\begin{tikzpicture}\IfValueT{#2}{#2}\scantokens{#3}\end{tikzpicture}%
	\end{minipage}%
	\begin{minipage}{\textwidth-#1}%
		{\verbatim@font\let\do\@makeother\dospecials\@noligs
			\language\l@nohyphenation\@vobeyspaces\frenchspacing\scantokens{#3}}%
	\end{minipage}\par}
\makeatother

\begin{document}


\maketitle

The \moeptikz{} package provides shapes for typesetting computer networks, e.\,g.\@ shapes for hubs, switches, routers, and more.
It has been in use since 2012 for the lecture materials of an introductory course in computer networks due to shortcomings of some commercial products and (at that time) the lack of meaningful alternatives.
Currently the package provides the following shapes, styles and commands:
\begin{itemize}\itemsep0pt
	\item \verb|hub|, \verb|switch|, \verb|mlswitch|, \verb|router|,
	\verb|fwrouter|, \verb|fw|, \verb|nuc| (alias \verb|ap|), \verb|modem|,
	\verb|wlanmodem|
	\item \verb|client|, \verb|notebook|, \verb|smartphone|, \verb|server|,
	\verb|rack|, \verb|db|, \verb|internet|
	\item \verb|user|, \verb|usergroup|, \verb|messageclosed|,
	\verb|messageopen|, \verb|key|, \verb|keyhole|
	\item \verb|waves| (wireless links, Section~\ref{sec:waves})
	\item \verb|\tikzextractx|, \verb|\tikzextracty|
	\item \verb|\moeptikzset|{}
\end{itemize}

\section{What it can do}
Did you ever try to build slides for a networking lecture from scratch?
If so, do you care about off-topic details such as using solely vector graphics, perfect alignment of nodes, easy modification of hundreds of figures when you decide to change fonts or colors, and doing all that without even thinking about a pointing device?
Then you probably like what \moeptikz{} can do for you:

\begin{figure}[ht!]
\centering
\examplenetwork{1.2}
\caption{What \protect\moeptikz{} can (or cannot?) do for you}
\label{fig:moeptikz-intro}
\end{figure}


\section{What it cannot do}
You probably noticed the misalignment of \verb|PC2| (and its friend) in Figure~\ref{fig:moeptikz-intro}.
Well, you might not have noticed it in the first place (I didn't either), but now, as you know about that, it must drive you crazy.
The good news: it's your fault (in this particular case it is my fault, of course).
\moeptikz cannot calculate coordinates for you.
If you are interested in writing \TikZ{} instead of pointing around you will notice the difference:

\begin{figure}[ht!]
\centering
\examplenetwork{1.3}
\caption{What \protect\moeptikz{} can do for you if you can do your math}
\end{figure}


\section{Package options}

The only package option currently defined is \texttt{shading=<true|false>}.
If true (default), nodes are shaded to create the visual effect of a spotlight.
If false, nodes are filled with a flat color instead (the envelopes of the message shapes are flat in either case).
The options \texttt{shading} and \texttt{noshading} are short forms of \texttt{shading=true} and \texttt{shading=false}.
The shading has only a marginal impact on the resulting document size but may be undesirable depending on the personal preference.


\section{The shapes}

Figures~\ref{fig:shapes} to~\ref{fig:shapes3} present the different shapes as printed by \verb|\node[<shape>] at ...| (the label font is typewriter here, but that's up to you).
The default label shows the name of the corresponding shape.
The nodes are drawn with \verb|minimum size=2cm|; the gray box around each shape measures $\SI{4}{\centi\meter}\,\times\,\SI{4}{\centi\meter}$.
The red crosses mark the positions of \verb|label=<pos>:<labeltext>|; the node text hides the cross below (except for \verb|internet| and \verb|key|).
The gray lines end at the automatically calculated border points; the compass anchors lie there as well, e.\,g.\@ \verb|(x.north east)| is \verb|(x.45)| (except for \verb|internet|), \verb|base| on the baseline of the node text and \verb|mid| .5ex above it.

If the node option \verb|minimum size| is omitted, nodes will be drawn in a bounding box of $\SI{1}{\centi\meter}\,\times\,\SI{1}{\centi\meter}$.
The line widths of the shapes scale with their size; the line width of the picture (e.\,g.\@ \verb|thick| or \verb|line width=<width>|) does not affect them, it is meant for the links between the nodes.
The only exception is the outline of \verb|internet|.
Since not all shapes fill their bounding box, the node text is not placed at a fixed position but directly below the visible shape, exactly where \verb|label=below:<text>| would put a label (exceptions: \verb|internet| and \verb|key|, see Sections~\ref{sec:internet} and~\ref{sec:key}).
Hence the text of a server is closer to the node center than the text of a client, but the gap between shape and text is the same for all shapes.
Like a label, the node text counts for the size of the picture.

Some shapes combine others: \verb|mlswitch| is a multilayer switch, i.\,e.\@ a switch with the arrows of a router on its lid, \verb|fwrouter| is a router with a firewall on top (Section~\ref{sec:fw}), and \verb|rack| shows four servers on top of each other.
These shapes have the size, the anchors and the border of the shapes they are based on, hence they can replace them in a figure without moving anything.
The exception is \verb|rack|, which is as high as a router or a switch.
Similarly, \verb|usergroup| shows three users and \verb|wlanmodem| is a modem with two antennas, e.\,g.\@ a home router with built-in modem and WLAN.

\begin{figure}[ht!]
	\centering
	\presentnode{hub}{hub}
	\hskip5mm%
	\presentnode{switch}{switch}
	\hskip5mm%
	\presentnode{router}{router}
	\vskip5mm
	\presentnode{client}{client}
	\hskip5mm%
	\presentnode{server}{server}
	\hskip5mm%
	\presentnode{nuc}{nuc}
	\vskip5mm
	\presentnode{messageclosed}{messageclosed}
	\hskip5mm%
	\presentnode{messageopen}{messageopen}
	\hskip5mm%
	\presentnode{notebook}{notebook}
	\caption{Shapes currently defined}
	\label{fig:shapes}
\end{figure}

\begin{figure}[ht!]
	\centering
	\presentnode{mlswitch}{mlswitch}
	\hskip5mm%
	\presentnode{fwrouter}{fwrouter}
	\hskip5mm%
	\presentnode{rack}{rack}
	\vskip5mm
	\presentnode{fw}{fw}
	\hskip5mm%
	\presentnode{fw}{fw,horizontal}[horizontal]
	\hskip5mm%
	\presentnode{db}{db}
	\vskip5mm
	\presentnode[\mbox]{internet}{internet}[minimum width=3.5cm,minimum height=1pt]
	\caption{Shapes currently defined, continued (\texttt{internet} with \texttt{minimum width=3.5cm}, see Section~\ref{sec:internet})}
	\label{fig:shapes2}
\end{figure}

\begin{figure}[ht!]
	\centering
	\presentnode{smartphone}{smartphone}
	\hskip5mm%
	\presentnode{user}{user}
	\hskip5mm%
	\presentnode{usergroup}{usergroup}
	\vskip5mm
	\presentnode{modem}{modem}
	\hskip5mm%
	\presentnode{wlanmodem}{wlanmodem}
	\vskip5mm
	\presentnode{key}{key}
	\hskip5mm%
	\presentnode{keyhole}{keyhole}
	\caption{Shapes currently defined, continued (for \texttt{key} see Section~\ref{sec:key})}
	\label{fig:shapes3}
\end{figure}


\subsection{Changing node colors}
There are very few occasions where you might want to highlight a specific node by changing its color.
Or you are upset by the default mark color (black), i.\,e.\@, the color of arrows on top of some shapes.
You may change it at will: all shapes support custom colors using the \verb|fill=<color>| option.
In addition to that, the shapes with arrows (\verb|hub|, \verb|switch|, \verb|mlswitch|, \verb|router|, \verb|fwrouter|), the message shapes and \verb|internet| also let you change the color of their arrows or lines with the \verb|draw=<color>| option.
The shape names take no value: put \verb|fill|, \verb|draw| and \verb|minimum size| after the shape name, as in \verb|\node[router,fill=red]|; in front of it, the defaults of the shape may override them.
The sheet of paper in \verb|messageopen| has a color of its own, \verb|paper color=<color>| (default black): it is shaded in light tones of this color (also with \texttt{noshading}) and outlined in \verb|<color>!80|.

\example{\node[router,fill=blue,draw=orange] at (0,0) {};}

\example{\node[messageclosed,fill=red!40,draw=red] at (0,0) {};}

\example{\node[messageopen,fill=orange!40,paper color=blue,draw=orange] at (0,0) {};}

\vskip\baselineskip

The effect of the \verb|draw| option depends on the actual shape:
the shapes with arrows will change the color of their marking (the arrows) while \verb|messageopen| and \verb|messageclosed| change the line color of the envelope and \verb|internet| the color of its outline (Section~\ref{sec:internet}); all other shapes ignore the \verb|draw| option.
This behavior may seem inconsistent but is intended -- give it a try, or come up with a fix.


\subsection{The internet shape}
\label{sec:internet}
The \verb|internet| shape draws a cloud with a configurable number of puffs.
Unlike the other shapes, the node text is placed in the middle of the cloud and the cloud grows with its text.

\example[3.5cm]{\node[internet] {Internet};}

\example[3.5cm]{\node[internet,puffs=7,fill=blue] {Internet};}

\example[3.5cm]{\node[internet,puffs=13,minimum width=3cm,empty,draw=red] {Internet};}

\vskip\baselineskip

The following options are supported:
\begin{itemize}\itemsep0pt
	\item \verb|puffs=<n>|: number of puffs (default 10)
	\item \verb|minimum width|, \verb|minimum height|: enlarge the cloud
	\item \verb|aspect=<ratio>|: ratio of width to height (default 2)
	\item \verb|fill=<color>|: color of the cloud, shaded or flat depending on the package option \texttt{shading}
	\item \verb|empty| or \verb|fill=none|: the cloud is not filled
	\item \verb|draw=<color>|, \verb|line width=<width>|: color and width of the outline
\end{itemize}
These colors affect only the cloud, use \verb|text=<color>| for the text.

The geometry, the border and the anchors \verb|center|, \verb|mid|, \verb|base| and the compass anchors (\verb|north|, \verb|north east|, \dots) are taken from the \verb|cloud| shape of the \TikZ{} library \verb|shapes.symbols|, which is loaded by \moeptikz{}.
An \verb|internet| node does not have the anchors \verb|puff 1| to \verb|puff <n>| of the cloud.
Use at least 5 puffs.
Wide clouds (3\,cm and more) need about 8 puffs, otherwise the puffs at the sides degenerate.


\subsection{Firewalls}
\label{sec:fw}
The \verb|fw| shape draws a brick wall.
By default the wall stands upright and shows its narrow end, the option \verb|horizontal| lays it down.
The graph drawing library \verb|graphdrawing| of \TikZ{} (LuaLaTeX only) has an option \verb|horizontal=<tail> to <head>| as well, which causes an error in the options of a picture or scope, e.\,g.\@ \verb|\tikz[layered layout,horizontal=a to b]|; write \verb|/graph drawing/horizontal=a to b| there instead.
Conversely, with this library loaded, the option \verb|horizontal| of a node inside \verb|\graph| goes to graph drawing and the firewall silently stays upright; write \verb|/tikz/horizontal| there, e.\,g.\@ \verb|a[fw,/tikz/horizontal]|.
The \verb|fwrouter| shape is a router with a firewall on top.
The bricks are drawn in the fill color of \verb|fw| and in the color \verb|fw color=<color>| of \verb|fwrouter|, both \verb|red!50!black| by default (dark enough to stand out in grayscale); \verb|fill| and \verb|draw| of \verb|fwrouter| work as for a router.

\example{\node[fw] at (0,0) {};}

\example{\node[fw,horizontal,fill=black!40] at (0,0) {};}

\example{\node[fwrouter,fw color=orange,draw=white] at (0,0) {};}


\subsection{Keys}
\label{sec:key}
The shapes \verb|key| and \verb|keyhole| are meant for security topics, e.\,g.\@ private and public keys in different colors.
Both are drawn in their fill color with some depth to the back.
The key lies diagonally in its bounding box, so the border points at \ang{90} and \ang{270} lie on the blade in the middle of the key.
Hence its node text is placed below the lowest point of the key (the bit) instead of where \verb|label=below:<text>| would put a label, and labels above or below overlap the key (Figure~\ref{fig:shapes3}).
Use the node text or labels at other positions for keys.

\example{\node[key,fill=red] at (0,0) {};}

\example{\node[key,fill=green!60!black] at (0,0) {};}

\example{\node[keyhole,fill=yellow!80!black] at (0,0) {};}


\subsection{Wireless links}
\label{sec:waves}
The path style \verb|waves| draws concentric arcs instead of a line, e.\,g.\@ for a wireless link.
The arcs are centered at the start of the path and grow up to its end; between two nodes they start at the border of the first one.
The option \verb|waves=<n>| sets the number of arcs (default 6), \verb|wave angle=<angle>| their opening angle (default 70).
By default the arcs are thin and gray; an own color or line width has to be given after \verb|waves|.

\example[3.5cm][{\node[ap] (a) at (0,0) {}; \node[notebook] (n) at (2.2,-.6) {};}]{\draw[waves] (a) to (n);}

\example[3.5cm]{\draw[waves=10,wave angle=40] (0,0) to (2.5,0);}

\example[3.5cm]{\draw[waves,blue,line width=.8pt] (0,0) to (2,1);}



\section{The commands}
\moeptikz{} provides three commands to make your life with \TikZ{} easier:
\begin{enumerate}\itemsep0pt
	\item \verb|\tikzextractx{(x,y)}{\<macroname>}|{}
		stores the \verb|x|-component of a coordinate in \verb|\<macroname>|.
	\item \verb|\tikzextracty{(x,y)}{\<macroname>}|{}
		stores the \verb|y|-component of a coordinate in \verb|\<macroname>|.
	\item \verb|\moeptikzset{<key>=<value>}|{}
		sets the internal key \verb|<key>|{} to value \verb|<value>|.
		Currently, the only defined key is \verb!shading=<true|false>!.
\end{enumerate}


\section{Known incompatibilities}
\label{sec:incompatibilities}
Some keys of \moeptikz{} have the names of keys or shapes of other packages, and only one of them can take effect; \moeptikz{} warns about these clashes at \verb|\begin{document}|.
\begin{itemize}\itemsep0pt
	\item \verb|circuitikz| defines the key \verb|switch| (a switch in a circuit) and the shape \verb|waves|.
	Whichever of \moeptikz{} and \verb|circuitikz| is loaded last wins the key \verb|switch|; with \moeptikz{} loaded last, \verb|to[closing switch]| still draws the switch of \verb|circuitikz|.
	With its option \verb|compatibility|, \verb|circuitikz| calls its switch \verb|*switch|, which avoids the clash.
	The path style \verb|waves| of \moeptikz{} hides the shape \verb|waves| of \verb|circuitikz|; write \verb|shape=waves| for the latter.
	\item \verb|tikz-feynman| and the graph drawing library use the key \verb|horizontal| for the orientation of a graph, e.\,g.\@ \verb|horizontal=a to b|.
	Write it with its path in the options of a picture, scope or diagram, e.\,g.\@
	\begin{quote}
		\verb|\feynmandiagram[/graph drawing/horizontal=a to b] {...};|
	\end{quote}
	Section~\ref{sec:fw} explains this for the graph drawing library.
	Without LuaTeX (pdfLaTeX, XeLaTeX, latex with dvips), load \verb|tikz-feynman| before \moeptikz{}; otherwise \verb|horizontal| only warns that it needs LuaTeX.
\end{itemize}
The warnings can be hidden with the package \verb|silence| and \verb|\WarningsOff[moeptikz]|.


\end{document}

