5

I am writing a reference document that contains a lot of nested lists. In order to highlight the indentation level of each list element, I would like to draw a subtle line in each level of identention in every list. In my mind it looks something like that:

quick_example

The closest analogue of such thing, I can remember, is an algorithmicx code sample:

enter image description here

But I don't know how to implement this with a list; would appreciate any ideas.

2

REVISED SOLUTION (takes guesswork out of parameter selection)

With this revision, the guesswork is removed from the process, which is accomplished by forcing uniformity across the nested lists with topsep, parsep, and itemsep. Instead, one must just specify 9 well understood parameters, as well as the colors of each bar.

\tpset=2pt\relax% uniform \topset
\psep=2pt\relax% uniform \parsep
\itsep=2pt\relax% uniform \itemsep
\rlthk=2pt\relax% Colorbar thickness
\def\fixlm{20pt}% Fixed indent per itemize level
\def\bulhwd{2.29pt}% Half Width of "bullet"; controls L/R shift of colorbars
\def\botscale{1.0}% controls vertical extent of bottom of colorbar
\def\topscale{1.0}% controls vertical extent of top of colorbar
\def\mybullet{$\bullet$}% bullet of itemized list

One of the tricks here is that label* adds the current label onto (i.e., to the right of) the label from the next higher level. Therefore, placing a bullet in the level 1 label makes a bullet show up on the left side of the level 2 label, and so forth. To avoid this, I created \bul[] which will only print a bullet if no optional argument is passed. Thus, I just make sure that the labels in levels 2, 3, 4, etc. start with an optional argument (here given as [x]), in order to nullify the trailing bullet from the prior level. Neat!

In the MWE below, I demonstrate the result for two separate sets of parameters.

\documentclass{article}
\usepackage{enumitem,xcolor}
\newlength\rlthk
\newlength\psep
\newlength\tpset
\newlength\itsep
%%%%%%%%%%%%%%%%%USER PARAMETERS
\tpset=2pt\relax% uniform \topset
\psep=2pt\relax% uniform \parsep
\itsep=2pt\relax% uniform \itemsep
\rlthk=2pt\relax% Colorbar thickness
\def\fixlm{20pt}% Fixed indent per itemize level
\def\bulhwd{2.29pt}% Half Width of "bullet"; controls L/R shift of colorbars
\def\botscale{1.1}% controls vertical extent of bottom of colorbar
\def\topscale{1.1}% controls vertical extent of top of colorbar
\def\mybullet{$\bullet$}% bullet of itemized list
%%%%%%%%%%%%%%%
\newcommand\rl[1][black]{\textcolor{#1}{%
  \rule[-\allseps]{\rlthk}{%
  \dimexpr\allseps-.3\baselineskip+\topscale\baselineskip+\topscale\psep+\topscale\tpset}}}
\newcommand\hs[1]{\hspace{#1}}
\newcommand\bul[1][\relax]{\ifx\relax#1\mybullet\fi}
\def\offlm{\dimexpr\bulhwd-0.5\rlthk\relax}
\def\modlm{\dimexpr\leftmargin-\bulhwd-.5\rlthk\relax}
\def\allseps{\dimexpr\tpset+\psep-.9\baselineskip+\botscale\baselineskip+\itemsep}
\setlist[itemize,1]{label*=\bul,
  labelwidth=\fixlm,topsep=\tpset, parsep=\psep, itemsep=\itsep}
\setlist[itemize,2]{
   label*=[x]\smash{           \rl[red]\hs{\modlm}}\bul,
  leftmargin=\fixlm,topsep=\tpset, parsep=\psep, itemsep=\itsep}
\setlist[itemize,3]{
   label*=[x]\smash{\hs{\offlm}\rl[blue]\hs{\modlm}}\bul,
  leftmargin=\fixlm,topsep=\tpset, parsep=\psep, itemsep=\itsep}
\setlist[itemize,4]{
   label*=[x]\smash{\hs{\offlm}\rl[green]\hs{\modlm}}\bul,
  leftmargin=\fixlm,topsep=\tpset, parsep=\psep, itemsep=\itsep}
\begin{document}
\begin{itemize}
\item A1
\item A2
  \begin{itemize}
  \item B1
    \begin{itemize}
    \item C1 
      \begin{itemize}
      \item D1 
      \item D2
      \end{itemize}
    \item C2
    \end{itemize}
  \item B2
  \item B3
  \end{itemize}
\item A3
\end{itemize}
\noindent\hrulefill
%%%%%%%%%%%%%%%%%USER PARAMETERS
\tpset=1pt\relax% uniform \topset
\psep=1pt\relax% uniform \parsep
\itsep=1pt\relax% uniform \itemsep
\rlthk=4pt\relax% Colorbar thickness
\def\fixlm{30pt}% Fixed indent per itemize level
\def\bulhwd{5.7pt}% Half Width of "bullet"; controls L/R shift of colorbars
\def\botscale{1}% controls vertical extent of bottom of colorbar
\def\topscale{1}% controls vertical extent of top of colorbar
\def\mybullet{\raisebox{-3pt}{\Huge$\bullet$}}% bullet of itemized list
%%%%%%%%%%%%%%%
\begin{itemize}
\item A1
\item A2
  \begin{itemize}
  \item B1
    \begin{itemize}
    \item C1 
      \begin{itemize}
      \item D1 
      \item D2
      \end{itemize}
    \item C2
    \end{itemize}
  \item B2
  \item B3
  \end{itemize}
\item A3
\end{itemize}
\end{document}

enter image description here

ORIGINAL SOLUTION (requires parameter specification)

Because parameters like topsep, parsep and itemsep change, by default, with each level of itemization, the parameters that govern the color bar placement need fitting. However, this solution is simpler to understand than the full solution given above.

So, there's a little guesswork with the parameters at each level, but not so bad. Once the parameters are determined for each level, it works with just the normal itemize environment syntax.

EDITED for color

\documentclass{article}
\usepackage{enumitem,xcolor}
\def\rlthk{2pt}
\newcommand\rl[3][black]{\textcolor{#1}{\rule[-#2pt]{\rlthk}{#3\baselineskip}}}
\newcommand\hs[1]{\hspace{#1pt}}
\newcommand\bul[1][\relax]{\ifx\relax#1$\bullet$\fi}
\begin{document}
\setlist[itemize,1]{label*=\bul}
\setlist[itemize,2]{label*=[x]\smash{        \rl[red]  {14.5}{2.9}\hs{18.9}}\bul}
\setlist[itemize,3]{label*=[x]\smash{\hs{1.4}\rl[blue] {10.5}{2.2}\hs{15.4}}\bul}
\setlist[itemize,4]{label*=[x]\smash{\hs{1.2}\rl[green]{09.0}{1.9}\hs{13.8}}\bul}
\begin{itemize}
\item A1
\item A2
  \begin{itemize}
  \item B1
    \begin{itemize}
    \item C1
      \begin{itemize}
      \item D1
      \item D2
      \end{itemize}
    \item C2
    \end{itemize}
  \item B2
  \item B3
  \end{itemize}
\item A3
\end{itemize}
\end{document}

enter image description here

  • It works just great, but with only one exeption: if the ident item has more than one line, a gap in the highlighting occurs: dl.dropboxusercontent.com/spa/dvgcwyfatsch0lf/bofxisdp.png I can't figure out how it may be handled. – kvaleev Mar 12 '15 at 23:49
  • @TeXNewbie Problem confirmed. Let me give it some thought. – Steven B. Segletes Mar 13 '15 at 16:04
  • 1
    @TeXNewbie Using my revised solution, right before the multi-line \item, set \def\botscale{2} or some appropriate value. After that \item, reset it to the default value: \def\botscale{1.1}. – Steven B. Segletes Mar 13 '15 at 16:09
3

This is one possible solution where tikzmark is utilized here and \VerticalLine is defined that takes 3 arguments defined in the code as remarks.

enter image description here

Code

\documentclass{article}
\usepackage[left=3in,top=2in]{geometry}
\usepackage{tikz,amsmath,enumitem}
%
\setlist{nosep,before=\vspace{\baselineskip},after=\vspace{\baselineskip}}
\newcommand{\tikzmarkA}[1]{\tikz[overlay,remember picture,] \node[xshift=2pt] (#1) {};}

\newcommand\VerticalLine[3][]{%
    % #1 = draw options
    % #2 = top mark
    % #3 = bottom mark
\draw[#1] 
(#2)  --  (#2 |- #3);
}

\begin{document}

\begin{itemize}
\item[$\bullet$] indent level one
\item[$\bullet$] indent level one
\item[\tikzmarkA{a1}$\bullet$] indent level one
    \begin{itemize}
    \item[$\bullet$] indent level two
    \item[$\bullet$] indent level two
    \item[\tikzmarkA{a2}$\bullet$] indent level two
          \begin{itemize}
          \item[$\bullet$] indent level three
          \item[$\bullet$] indent level three
          \item[\tikzmarkA{a3}$\bullet$] indent level three
                \begin{itemize}
                 \item[$\bullet$] indent level four
                 \item[$\bullet$] indent level four
                 \item[\tikzmarkA{a4}$\bullet$] indent level four
                \end{itemize}
           \end{itemize}
   \end{itemize}
\end{itemize}

\begin{tikzpicture}[overlay,remember picture]
\VerticalLine[ultra thick,gray]{a1}{a4}
\VerticalLine[ultra thick,blue]{a2}{a4}
\VerticalLine[ultra thick,red]{a3}{a4}
\end{tikzpicture}

\end{document}
  • A minor improvement might be to define a \newlint which uses the before and after keys of enumitem to automatically add the \tikzmark at the start and end of a list and add the appropriate draw commands at the end of the top level list. I haven't tried it so not sure that there are not complications with this approach. Also, there are issues if the lists span more than one page. – Peter Grill Nov 19 '14 at 19:54
  • Yeah, the tikzpicture is limited to one page and this is recently commented in tex.stackexchange.com/q/212863/34618. That is why the proposal uses color lines so that manually page break in such case may help, IMHO. – Jesse Nov 19 '14 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.