2

I am compiling a private song book using a tcolorbox for each song. The tcolorbox package provides a nice interface for automatic numbering and creation of a list-of-tcolorboxes and even integrating this directly into the table of contents.

How can I additionally provide an alphabetical list of all songs (tcolorboxes) by title?

enter image description here

    \documentclass[twoside]{article}
    \usepackage[T1]{fontenc}
    \usepackage{lmodern}
    \usepackage[utf8]{inputenc}
    \usepackage[hidelinks]{hyperref}

    \usepackage[breakable]{tcolorbox}
    \newtcolorbox[auto counter, number within=section, list inside=toc]{song}[1]{before title={\textbf{\thetcbcounter}\quad}, title={#1}}

    \renewcommand{\thesection}{\Alph{section}}

    \begin{document}
        \tableofcontents

        \section{English Songs}
        \begin{song}{Old MacDonald}
            Old MacDonald....
        \end{song}

        \begin{song}{Happy Birthday}
            Happy Birthday...
        \end{song}

        \begin{song}{Oh When The Saints}
            Oh when the saints...
        \end{song}

        \section{German Songs}

        \begin{song}{Alle meine Entchen}
            Alle meine Entchen...
        \end{song}

        \begin{song}{Häschen in der Grube}
            Häschen in der Grube...
        \end{song}

        \section{Alphabetical List of Songs}

        But how?    
    \end{document}
  • Note that song titles may contain nonascii characters (Umlauts), like in "Häschen in der Grube" – bonus points to get that right :-) I am currently using pdflatex, but switching to lualatex would perfectly be possible. – Daniel May 3 '19 at 8:24
3

It is fairly straightforward to put all of the songs into a latex3 sequence and then print them out at the end of the document with a \ListSongs command, so as to produce:

enter image description here

The \AllSongs macro will print all of the songs that have appeared up to that point in the document. With a little more work you could save all of the songs to the aux file (or a "songs" file), and then read them back in, which would mean that the complete could be printed anywhere in the document.

As requested in the comments, I have updated the format of the list of songs so that it now includes song numbers, sing titles and page numbers, similar to a table of contents listing. Both the song titles and the page numbers are hyperlinks. To get this to work I added after=\AddSong{#1} to the definition of the songs environment, which simply adds the title for the current song to the list of songs. For the hyperlinks to work at the end of the song environment the code now adds labels to each song of the form songA.1, songA.1, .... If the songs contain any counters etc, which seems unlikely, then these labels may be slightly wrong.

Here is the full code:

\documentclass[twoside]{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage[hidelinks]{hyperref}
\usepackage{enumitem}

\usepackage{xparse,expl3}
\ExplSyntaxOn
\seq_new:N \g_songs_seq
\NewDocumentCommand\AddSong{m}
{
  \label{song\thetcbcounter}
  \seq_gpush:Nx \g_songs_seq {{#1}{\thetcbcounter}}
}
\cs_new_protected:Nn \list_song:nn {
  \item[#2]\hyperref[song#2]{#1}\dotfill\pageref{song#2}
}
\NewDocumentCommand\ListSongs{}
{
  \seq_if_empty:NF \gongs_seq
  {
    % first sort the songs following
    % https://tex.stackexchange.com/questions/333646
    \seq_sort:Nn \g_songs_seq {
      \int_compare:nTF { \pdftex_strcmp:D { ##1 } { ##2 } > 0 }
        { \sort_return_swapped: }
        { \sort_return_same: }
    }
    % print the list of songs in an itemize environment
    \begin{enumerate}[nosep]
      \seq_map_inline:Nn \g_songs_seq {\list_song:nn ##1}
    \end{enumerate}
  }
}
\ExplSyntaxOff

\usepackage[breakable]{tcolorbox}
\newtcolorbox[
    auto counter,
    number within=section,
    list inside=toc
]{song}[1]{%
    before title={\textbf{\thetcbcounter}\quad},
    title={#1},
    after=\AddSong{#1}
}

\renewcommand{\thesection}{\Alph{section}}

\begin{document}
    \tableofcontents

    \section{English Songs}

    \begin{song}{Old MacDonald}
        Old MacDonald....
    \end{song}

    \begin{song}{Happy Birthday}
        Happy Birthday...
    \end{song}

    \begin{song}{Oh When The Saints}
        Oh when the saints...
    \end{song}

    \section{German Songs}

    \begin{song}{Alle meine Entchen}
        Alle meine Entchen...
    \end{song}

    \begin{song}{Häschen in der Grube}
        Häschen in der Grube...
    \end{song}

    \newpage
    \section{Alphabetical List of Songs}

    \ListSongs
\end{document}
|improve this answer|||||
  • Thanks Andrew! Regarding the formatting, you are right: I did not specify this explicitly, as I want it to be similar to the ToC formatting (without the section headings, obviously), that is, with song number and title as clickable hyperlinks (as produced by \contentsline). The latter still gives me a headache, as it requires a lot of "expand the right things at the right time", which I don't know yet how to achieve in xparse. – Daniel May 4 '19 at 8:32
  • @Daniel The comments say how to make it look a little more like a TOC entry but adding a dot fill. Adding the song number would perhaps look strange with the alphabetical sorting by title? How exactly do you want it to look? Also, currently you have no hyperlnks in the document so this an unexpected requirement! – Andrew May 4 '19 at 9:15
  • @Daniel I have updated the code so that it produces a listing similar to the table of contents, including hyperlinks. – Andrew May 4 '19 at 23:48
  • Right, just define labels – I was thinking too complicated. Thanks again! – Daniel May 5 '19 at 20:01

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.