14

How would I best go about creating a custom directory similar to the Table of Contents, List of Figures, or List of Tables. For the sake of this example, I will call it a "List of Examples".

Let's say I have a custom environment that utilizes the convenience and readability of xparse of the environment definition and the beauty/robustness of tcolorbox for multiple-page support. A known issue is that I implement the optional argument incorrectly in that it does not support automatic line breaking. Also, perhaps the colon after Example would cause a funny-looking list of examples when no optional argument is provided.

\NewDocumentEnvironment{qikexample}{ O{} } % Optional Title, appears in List of Examples
{
\colorlet{colexam}{gray}
\newtcolorbox[use counter=qikexample,]{qikexamplebox}{%
    % Example Frame Start
    empty,% Empty previously set parameters
    title={Example: #1},% use \thetcbcounter to access the qikexample counter text
    % Attaching a box requires an overlay
    attach boxed title to top left,
    % (boxed title style requires an overlay)
    boxed title style={empty,size=minimal,toprule=0pt,top=4pt,overlay={}},
    coltitle=colexam,fonttitle=\bfseries,
    before=\par\medskip\noindent,parbox=false,boxsep=0pt,left=0pt,right=3mm,top=2pt,breakable,pad at break=0mm,
    before upper=\csname @totalleftmargin\endcsname0pt, % Use instead of parbox=true. This ensures parskip is inherited by box.
    % Handles box when it exists on one page only
    overlay unbroken={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: first page
    overlay first={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: middle page
    overlay middle={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: last page
    overlay last={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },%
    }
\begin{qikexamplebox}}
{\end{qikexamplebox}\endlist}

I would implement this in a document like this:

\begin{qikexample}[List Contents of Directory in Unix]
ls
\end{qikexample}

I would like to add logic that lists their names and page numbers.

After running a command like \listofexamples, the output might look something like:

List of Examples

Example: List Contents of Directory in Unix .................. 23

Example: List Contents of Directory in Windows .................. 23

Code

\documentclass{article}
\usepackage{fontspec}

\usepackage[most]{tcolorbox}
\usepackage{xparse}
% Counters
\newcounter{qikexample}

\NewDocumentEnvironment{qikexample}{ O{} } % Optional Title, appears in List of Examples
{
\colorlet{colexam}{gray}
\newtcolorbox[use counter=qikexample,]{qikexamplebox}{%
    % Example Frame Start
    empty,% Empty previously set parameters
    title={Example: #1},% use \thetcbcounter to access the qikexample counter text
    % Attaching a box requires an overlay
    attach boxed title to top left,
    % (boxed title style requires an overlay)
    boxed title style={empty,size=minimal,toprule=0pt,top=4pt,overlay={}},
    coltitle=colexam,fonttitle=\bfseries,
    before=\par\medskip\noindent,parbox=false,boxsep=0pt,left=0pt,right=3mm,top=2pt,breakable,pad at break=0mm,
    before upper=\csname @totalleftmargin\endcsname0pt, % Use instead of parbox=true. This ensures parskip is inherited by box.
    % Handles box when it exists on one page only
    overlay unbroken={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: first page
    overlay first={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: middle page
    overlay middle={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: last page
    overlay last={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },%
    }
\begin{qikexamplebox}}
{\end{qikexamplebox}\endlist}

\begin{document}

%\listofexamples

\begin{qikexample}[List Contents of Directory in Unix]
ls
\end{qikexample}
\end{document}

2 Answers2

14

It's all contained already in tcolorbox with list inside= option and the \tcblistof command.

First define \newtcolorbox[other options,list inside=qex]{...} to generate a new .toc like file with .qex extension (quick examples), then use \tcblistof[\section*]{qex}{Some title}.

\documentclass{article}
\usepackage{fontspec}

\usepackage[most]{tcolorbox}
\usepackage{xparse}
\newcounter{qikexample}


\NewDocumentEnvironment{qikexample}{ O{} } % Optional Title, appears in List of Examples
{
\colorlet{colexam}{gray}
\newtcolorbox[use counter=qikexample,list inside=qex]{qikexamplebox}{%
  % Example Frame Start
    empty,% Empty previously set parameters
    title={Example: #1},% use \thetcbcounter to access the qikexample counter text
    % Attaching a box requires an overlay
    attach boxed title to top left,
    % (boxed title style requires an overlay)
    boxed title style={empty,size=minimal,toprule=0pt,top=4pt,overlay={}},
    coltitle=colexam,fonttitle=\bfseries,
    before=\par\medskip\noindent,parbox=false,boxsep=0pt,left=0pt,right=3mm,top=2pt,breakable,pad at break=0mm,
    before upper=\csname @totalleftmargin\endcsname0pt, % Use instead of parbox=true. This ensures parskip is inherited by box.
    % Handles box when it exists on one page only
    overlay unbroken={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: first page
    overlay first={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: middle page
    overlay middle={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: last page
    overlay last={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },%
    }
\begin{qikexamplebox}}
{\end{qikexamplebox}\endlist}

\begin{document}

%\listofexamples
\tcblistof[\section*]{qex}{List of Examples}

\begin{qikexample}[List Contents of Directory in Unix]
ls
\end{qikexample}


\begin{qikexample}[Delete all]
rm *.*
\end{qikexample}
\end{document}

enter image description here


This is code Harish Kumar (who is no user of TeX.SE any longer unfortunately) smuggled into my answer ;-)

tcolorbox provides options with functionality similar to that of xparse provided the library \tcbuselibrary{xparse} is loaded. For example, your box can be generated by

\colorlet{colexam}{gray}
\DeclareTColorBox[use counter=qikexample,list inside=qex]{qikexample}{ O{} }{%
    % Example Frame Start
    empty,% Empty previously set parameters
    title={Example: #1},% use \thetcbcounter to access the qikexample counter text
    % Attaching a box requires an overlay
    attach boxed title to top left,
    % (boxed title style requires an overlay)
    boxed title style={empty,size=minimal,toprule=0pt,top=4pt,overlay={}},
    coltitle=colexam,fonttitle=\bfseries,
    before=\par\medskip\noindent,parbox=false,boxsep=0pt,left=0pt,right=3mm,top=2pt,breakable,pad at break=0mm,
    before upper=\csname @totalleftmargin\endcsname0pt, % Use instead of parbox=true. This ensures parskip is inherited by box.
    % Handles box when it exists on one page only
    overlay unbroken={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: first page
    overlay first={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: middle page
    overlay middle={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: last page
    overlay last={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },%
}

I am wondering whether the outer \NewDocumentEnvironment is necessary at all!

New version with some combination of tocloft and tcolorbox features:

The tocloft command \newlistof will automatically define the counter and the \l@.... command as well as the \listof... macro.

Since the tcolorbox uses the qikexample counter, it's necessary to say

\newcommand{\listofexamplesname}{List of Examples}
\newlistof{qikexample}{qex}{\listofexamplesname}

\renewcommand{\cftqikexampledotsep}{\cftnodots}

\NewDocumentCommand{\listofexamples}{}{%
  \listofqikexample
}

Now \listofexamples is a wrapper of \listofqikexample which uses the \l@qikexample entry type.

This has to be specified as list type=qikexample in the tcolorbox options.

Now all \cftX.... macros are available, see the example with \cftqikexampledotsep.

Here is the modified example

\documentclass{article}
\usepackage{fontspec}

\usepackage[most]{tcolorbox}
\usepackage{xparse}
\usepackage{tocloft}

%\newcounter{qikexample}

\newcommand{\listofexamplesname}{List of Examples}
\newlistof{qikexample}{qex}{\listofexamplesname}

\renewcommand{\cftqikexampledotsep}{\cftnodots}

\NewDocumentCommand{\listofexamples}{}{%
  \listofqikexample
}

\NewDocumentEnvironment{qikexample}{ O{} } % Optional Title, appears in List of Examples
{
\colorlet{colexam}{gray}
\newtcolorbox[use counter=qikexample,list inside=qex,list type=qikexample]{qikexamplebox}{%
  % Example Frame Start
    empty,% Empty previously set parameters
    title={Example: #1},% use \thetcbcounter to access the qikexample counter text
    % Attaching a box requires an overlay
    attach boxed title to top left,
    % (boxed title style requires an overlay)
    boxed title style={empty,size=minimal,toprule=0pt,top=4pt,overlay={}},
    coltitle=colexam,fonttitle=\bfseries,
    before=\par\medskip\noindent,parbox=false,boxsep=0pt,left=0pt,right=3mm,top=2pt,breakable,pad at break=0mm,
    before upper=\csname @totalleftmargin\endcsname0pt, % Use instead of parbox=true. This ensures parskip is inherited by box.
    % Handles box when it exists on one page only
    overlay unbroken={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: first page
    overlay first={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: middle page
    overlay middle={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: last page
    overlay last={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },%
    }
\begin{qikexamplebox}}
{\end{qikexamplebox}\endlist}

\begin{document}

\listofexamples

\begin{qikexample}[List Contents of Directory in Unix]
ls
\end{qikexample}


\begin{qikexample}[Delete all]
rm *.*
\end{qikexample}
\end{document}
  • 2
    That's pretty cool. I did not know tcolorbox could do such things. Is there anything it cannot do? – Steven B. Segletes Nov 03 '15 at 11:59
  • @StevenB.Segletes: If it can not do something it's perhaps a very tiny feature -- just write to Thomas Sturm and he will add it ;-) The \tcblistof feature is a little bit hidden actual in the manual, see page 104 etc. of the current manual. –  Nov 03 '15 at 12:02
  • But can it stack? ;^) – Steven B. Segletes Nov 03 '15 at 12:03
  • @StevenB.Segletes: I have no idea what you are referring too :D -- What do you want to stack? –  Nov 03 '15 at 12:04
  • 2
    @StevenB.Segletes I think it hasn't included coffee stains, yet :p – cgnieder Nov 03 '15 at 12:06
  • @clemens: That's perhaps very easy to use it as an overlay ;-) –  Nov 03 '15 at 12:07
  • @HarishKumar: It was a suggestion only... –  Nov 03 '15 at 12:24
  • @HarishKumar: Don't you dare :D –  Nov 03 '15 at 12:25
  • @ChristianHupfer Oh ho! I dared! :P Vote only tomorrow :) –  Nov 03 '15 at 12:28
  • @ChristianHupfer peace of cake! ;) – cgnieder Nov 03 '15 at 12:46
  • @ChristianHupfer \NewDocumentEnvironment may not be necessary but my work ethic is just because you can do something does not necessarily mean you should. I prefer to keep environments and commands wrapped, because it maintains consistency e.g. grep -Ein '\\NewDocumentEnvironment' Preamble.tex will list all environments defined in the Preamble if the developer, who is me, does things consistently and predictably. Another thing I have not looked into but would like to know: I am not sure I can customize the formatting of the List of Examples like tocloft does. Maybe you know? – Jonathan Komar Nov 04 '15 at 19:49
  • @macmadness86: See my update please. You can trick tcolorbox to use tocloft features as soon as list type=... is used. I did not test all \cft... stuff however –  Nov 04 '15 at 22:41
  • @ChristianHupfer Now we're talking! That is really nice. Tested/working: \cftqikexampledotsep, \cftqikexamplefont, \cftbeforeqikexampleskip, \cftqikexampleindent, \cftqikexamplenumwidth. Tested/not working: \cftbeforeqikexampletitleskip, \cftafterqikexampletitleskip, \cftqikexampletitlefont. I am a control freak :) – Jonathan Komar Nov 04 '15 at 23:12
  • @macmadness86: Untested: Shouldn't that be \cftbeforeqextitleskip etc. because those macros get the extension (qex) as part of the name, i.e. the \cftZ... name scheme? –  Nov 04 '15 at 23:21
6

I suggest you use the tocloft package, creating, in the preamble the following:

\newcommand{\listexamplesname}{List of examples}
\newlistof{qikexample}{xmp}{\listexamplesname}

You can, then, in the qikexample environment use \refstepcounter{qikexample} to advance the counter and

    \addcontentsline{xmp}{example}
    {\protect\numberline{\thesection.\theqikexample}#1}\par

to add it to the list. Then in the document \listofqikexamples will print it.

EDIT: I was inspired by this post, and tried to summarize here its content.

Here is a compilable example:

\documentclass{article}
\usepackage{fontspec}
\usepackage{tocloft}
\usepackage{etoolbox}
\usepackage[most]{tcolorbox}
\usepackage{xparse}
% Counters
\newcommand{\listexamplesname}{List of examples}
\newlistof{qikexample}{xmp}{\listexamplesname}
\NewDocumentEnvironment{qikexample}{ O{} } % Optional Title, appears in List of Examples
{
\refstepcounter{qikexample}
\addcontentsline{xmp}{example}
    {\protect\numberline{\thesection.\theqikexample}#1}\par
\colorlet{colexam}{gray}
\newtcolorbox{qikexamplebox}{%
    % Example Frame Start
    empty,% Empty previously set parameters
    title={Example: #1},% use \thetcbcounter to access the qikexample counter text
    % Attaching a box requires an overlay
    attach boxed title to top left,
    % (boxed title style requires an overlay)
    boxed title style={empty,size=minimal,toprule=0pt,top=4pt,overlay={}},
    coltitle=colexam,fonttitle=\bfseries,
 before=\par\medskip\noindent,parbox=false,boxsep=0pt,left=0pt,right=3mm,top=2pt,breakable,pad at break=0mm,
    before upper=\csname @totalleftmargin\endcsname0pt, % Use instead of parbox=true. This ensures parskip is inherited by box.
    % Handles box when it exists on one page only
    overlay unbroken={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: first page
    overlay first={\draw[colexam,line width=.5pt] ([xshift=-10pt]title.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: middle page
    overlay middle={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },
    % Handles multipage box: last page
    overlay last={\draw[colexam,line width=.5pt] ([xshift=-10pt]frame.north west) -- ([xshift=-10pt]frame.south west); },%
    }
\begin{qikexamplebox}}
{\end{qikexamplebox}\endlist}
\begin{document}
\listofqikexample
\begin{qikexample}[List Contents of Directory in Unix]
ls
\end{qikexample}
\end{document}
Moriambar
  • 11,466
  • 1
    Adding a small example that compiles would greatly improve the quality of your answer. Welcome to the site! – Steven B. Segletes Nov 03 '15 at 11:52
  • Working on it right now – Moriambar Nov 03 '15 at 11:53
  • @StevenB.Segletes here you go. – Moriambar Nov 03 '15 at 12:11
  • @ilFuria It seems your code has some overlap with another list in tocloft, the figure formatting controlled by e.g. \renewcommand{\cftfigfont}{\color{blue}} due to \addcontentsline{xmp}{figure} would make entries in both lists (LoF and List of Examples) blue. This makes it difficult to format the list of figures independently of the list of examples. For the heading of the ToC I would use \cftbeforetoctitleskip, \cftaftertoctitleskip, \cfttoctitlefont. Is there a way to improve your answer to include formatting of the List of Examples independent of other lists? – Jonathan Komar Nov 04 '15 at 20:07
  • @macmadness86 I corrected, the second arguments of \addcontentsline should've been somthing like example. Try now. – Moriambar Nov 04 '15 at 20:13
  • @ilFuria Cool beans. I already tried that, but \renewcommand{\cftexamplesfont}{\color{blue}} does not work to format entries as expected (how I would expect it anyway). I suppose I will need to investigate how tocloft \cft???font etc. commands are defined. – Jonathan Komar Nov 04 '15 at 20:46