Bulleted list with vertical lines
Final solution (edit3)
Now, the code should work with page breaks in lists as well. Hope you like it :) If anything is unclear or you want some explanation about parts, just let me know!
\documentclass{article}
\usepackage{tikz,tikzpagenodes}
\usetikzlibrary{calc}
\usepackage{refcount}
\newcounter{mylist} % new counter for amount of lists
\newcounter{mycnt}[mylist] % create new item counter
\newcounter{mytmp}[mylist] % tmp counter needed for checking before/after current item
\newcommand{\drawoptionsconn}{gray, shorten <= .5mm, shorten >= .5mm, thick}
\newcommand{\drawoptionsshort}{gray, shorten <= .5mm, shorten >= -1mm, thick}
\newcommand{\myitem}{% Modified `\item` to update counter and save nodes
\stepcounter{mycnt}%
\item[\linkedlist{%
i\alph{mylist}\arabic{mycnt}}]%
\label{item-\alph{mylist}\arabic{mycnt}}%
\ifnum\value{mycnt}>1%
\ifnum\getpagerefnumber{item-\alph{mylist}\arabic{mytmp}}<\getpagerefnumber{item-\alph{mylist}\arabic{mycnt}}%
\begin{tikzpicture}[remember picture,overlay]%
\expandafter\draw\expandafter[\drawoptionsshort] (i\alph{mylist}\arabic{mycnt}) --
++(0,3mm) --
(i\alph{mylist}\arabic{mycnt} |- current page text area.north);% draw short line
\end{tikzpicture}%
\else%
\begin{tikzpicture}[remember picture,overlay]%
\expandafter\draw\expandafter[\drawoptionsconn] (i\alph{mylist}\arabic{mytmp}) -- (i\alph{mylist}\arabic{mycnt});% draw the connecting lines
\end{tikzpicture}%
\fi%
\fi%
\addtocounter{mytmp}{2}%
\IfRefUndefinedExpandable{item-\alph{mylist}\arabic{mytmp}}{}{% defined
\ifnum\getpagerefnumber{item-\alph{mylist}\arabic{mytmp}}>\getpagerefnumber{item-\alph{mylist}\arabic{mycnt}}%
\begin{tikzpicture}[remember picture,overlay]%
\expandafter\draw\expandafter[\drawoptionsshort] (i\alph{mylist}\arabic{mycnt}) --
++(0,-3mm) --
(i\alph{mylist}\arabic{mycnt} |- current page text area.south);% draw short line
\end{tikzpicture}%
\fi%
}%
\addtocounter{mytmp}{-1}%
}
\newcommand{\linkedlist}[1]{
\raisebox{0pt}[0pt][0pt]{\begin{tikzpicture}[remember picture]%
\node (#1) [gray,circle,fill,inner sep=1.5pt]{};
\end{tikzpicture}}%
}
\newenvironment{myitemize}{%
% Create new `myitemize` environment to keep track of the counters
\stepcounter{mylist}% increment list counter
\begin{itemize}
}{\end{itemize}%
}
\begin{document}
\rule[-32\baselineskip]{2pt}{32\baselineskip}
\begin{myitemize}
\myitem test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph.
\myitem test
\myitem test
\end{myitemize}
And a new list:
\begin{myitemize}
\myitem test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph.
\myitem test
\end{myitemize}
\end{document}
edit2: I managed to solve the problems @Tom mentioned by using \pgfmathsetmacro\result{int(\x-1)}
and \result
rather than \pgfmathparse{int(\x-1)}
and \pgfmathresult
. It looks like tikz uses \pgfmathparse
for internal calculations that crashed the code. Using a name for it (\result
), solves this issue. Also, I used the easier shorten
syntax by @Ignasi.
TL;DR: Now thick
works as it should, as well as the other options.
edit: Made the code work with many lists on many pages.
I used a list counter mylist
and iterate over each node to plot the connecting line in the end of the newly created environment myitemize
. This supports multiple lists on multiple pages.
Original solution: works as long as you have a single list. If you need multiple lists, page breaking, etc., you need to expand the code.
I used a new counter to name and save the nodes automatically and iterate over them in the end.
You can use shorten
option to fix a certain distance between node's border and end of line. There's no nees for calc
:
\documentclass{article}
\usepackage{tikz}
%\usetikzlibrary{calc}
\newcommand{\linkedlist}[1]{
\begin{tikzpicture}[remember picture]%
\node (#1) [gray,circle,fill,inner sep=1.5pt]{};
\end{tikzpicture}%
}
\begin{document}
\begin{itemize}
\item[\linkedlist{a}] test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph.
\item[\linkedlist{b}] test
\item[\linkedlist{c}] test
\end{itemize}
\begin{tikzpicture}[remember picture,overlay]
\draw[gray, shorten >=1mm, shorten <=1mm] (a)-- (b);
\draw[gray, shorten >=1mm, shorten <=1mm] (b)-- (c);
\end{tikzpicture}
\end{document}
Update
If itemize
list is replaced by an enumerate
list, it's possible to declare a new linkedlist
environment which does all the work and uses regular \item
s.
It works with only for one level lists and it doesn't break between pages.
\documentclass{article}
\usepackage{tikz}
\newcommand{\linkeditem}[1]{
\begin{tikzpicture}[remember picture]%
\node (#1) [gray,circle,fill,inner sep=1.5pt]{};
\end{tikzpicture}%
}
\newenvironment{linkedlist}{%
\renewcommand{\theenumi}{\protect\linkeditem{\arabic{enumi}}}
\renewcommand{\labelenumi}{\theenumi}
\begin{enumerate}
}{ \end{enumerate} \begin{tikzpicture}[remember picture,overlay]
\ifnum\value{enumi}>1% Only if there are at least 2 bullet points
\foreach \x [remember=\x as \lastx (initially 1)]
in {2,...,\value{enumi}}{% iterate over them
\draw[gray, shorten >=1mm, shorten <=1mm] (\lastx) -- (\x);}% and draw the connecting lines
\fi
\end{tikzpicture}
}
\begin{document}
\begin{linkedlist}
\item test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph. test with a very long paragraph.
\item test
\item test
\end{linkedlist}
\end{document}