I'd like to add a humble contribution to the contest. But beware, don't expect too much. After all, it's me. :)

Before the code is properly unveiled, I'd like to provide some background, so everybody will understand why I came up with it. There we go.

Background

I'm the coordinator of a small choir in a parish. I decided to come up with a personal songbook to help me on keeping track of songs we use during masses or processions. But it is not an easy task.

First of all, I decided to use the songs package. IMHO it's a nice package for handling songbooks and it really suits my purposes. As a bonus, it can handle chords beautifully. But unfortunately, the whole process of cataloging songs required much more than a good layout.

Catholic liturgy teaches us that music is an important part of the mass. So I had to have every rite or gesture mapped to the correct song, e.g, entrance song, Kyrie, Gloria, Alleluia, Presentation of the Gifts, and so forth.

So I wrote down how many categories I had to map to my songs. I came up with 22 categories. So far so good.

But it was not that simple. I had to map songs according to their categories and also taking the time of the liturgical year into consideration, e.g, Advent, Christmas, Ordinary Time, Lent and Easter. So I had to cross map all categories along the year. Besides, I also had to take into consideration the calendar of saints, feasts and the sacraments. Oh my!

How should I do such project using LaTeX? We will see how I did it.

Implementation

First of all, the songs package is a prerequisite. I decided to use it and I'm quite satisfied with the result. I must warn you that the CTAN version is very outdated, so please download the updated one from here.

I had 22 categories, so I decided to convert them to 22 indices. I usually search songs by their category, so it was a natural choice. imakeidx is the way to go, very easy to use and powerful. Ah, I decide to use another one for a thematic index, so saints, feasts and sacraments were correctly mapped.

I won't write my real code, as it is more a monstruous example than a minimal one. :) But you will probably get the idea. Lets check it:

% the document class, no big deal \documentclass[a4paper,oneside,11pt]{book} % the usual packages \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} % index features \usepackage{imakeidx}

No secret here. Now let's then create, say, four categories:

% four indices will be created, each % one representing a category \makeindex[name=foo,title=Index of Foo] \makeindex[name=bar,title=Index of Bar] \makeindex[name=foobar,title=Index of Foobar] \makeindex[name=qux,title=Index of Qux]

Please, don't expect the 23 categories I have! :) Ah, in my real document, I use the splitindex option for imakeidx , otherwise we will run out of registers. Let's move on:

% my favorite layout lifesaver \usepackage{idxlayout} % drawing stuff \usepackage{tikz} % swiss army knife \usepackage{etoolbox} % for string comparison \usepackage{xstring}

In every song, I want to display the categories, so I wrote the following code to display an acronym to represent every category:

% this command will draw a circle % with #1 text inside it

ewcommand*\drawtype[1]{% \begin{tikzpicture}

ode[draw,circle,inner sep=1pt, minimum height=0.5cm, minimum width=0.5cm] {\scriptsize #1}; \end{tikzpicture}% }

The songs package, of course:

% songs \usepackage[lyric]{songs}

Remember the divisions of the liturgical year? I decided to use the following plan: Imagine five bullets in front of a song name. The order for the times of the liturgical year is well-defined, so each bullet represents one time. If, say, the first bullet is filled ( \bullet ), the song might be used in this time, otherwise an empty bullet ( \circ ) will be used. Let's say we have four times, A , B , C and D :

% print the bullets according to the % #1 input \DeclareRobustCommand*\drawbullets[1]{% {\footnotesize% \IfSubStr{#1}{A}{$\bullet$}{$\circ$}% \IfSubStr{#1}{B}{$\bullet$}{$\circ$}% \IfSubStr{#1}{C}{$\bullet$}{$\circ$}% \IfSubStr{#1}{D}{$\bullet$}{$\circ$}}~% }

And I want to have the liturgical time being displayed in the song, so I wrote another code for it:

% draw a little square with #1 text % inside it

ewcommand*\timebox[1]{% \begin{tikzpicture}

ode[draw,inner sep=1pt, minimum height=0.3cm, minimum width=0.3cm] {\tt\raisebox{0pt}[\height][0pt]{#1}}; \end{tikzpicture}% } % print a timebox and add a space

ewcommand*\indextime[1]{% \timebox{#1}~% }

I love this part. Thanks to the etoolbox package, I can iterate through elements of a list, so I add a new list parser:

% declare a new list parser \DeclareListParser*{\myforeach}{,}

Now I create a command to iterate through a list of times:

% create a command that will print a % timebox for every letter found

ewcommand*\settime[1]{% \myforeach{\indextime}{#1}% }

This part is the heart of my implementation. I read the category of the current song and index it accordingly:

% index song according to the % category

ewcommand*\indexsong[1]{% \IfEq{#1}{F}{% \resettitles% \index[foo]{\songtitle@\songliturgy \songtitle} \drawtype{F}~% }{% \IfEq{#1}{B}{% \resettitles% \index[bar]{\songtitle@\songliturgy \songtitle} \drawtype{B}~% }{% \IfEq{#1}{FB}{% \resettitles% \index[foobar]{\songtitle@\songliturgy \songtitle} \drawtype{FB}~% }{% \IfEq{#1}{Q}{% \resettitles% \index[qux]{\songtitle@\songliturgy \songtitle} \drawtype{Q}~% }{% \textbf{Error!}% }% }% }% }% }%

Again, for every category of every song, let's index it:

% create a command to index the current song % according to the list of categories

ewcommand*\classify[1]{% \myforeach{\indexsong}{#1}% }

Now, I need to add support to these entries in my song environment:

% create a new song key to print the categories

ewsongkey{cla}{\def\songclassify{}} {\def\songclassify{ #1 \par}} % create a new song key to print the time

ewsongkey{tin}{\def\songliturgy{}} {\def\songliturgy{#1}} % Renew the song prelude to print % the categories \renewcommand{\extendprelude}{% \showrefs{\footnotesize\showauthors}% {\ttfamily\songclassify}% }

Now I create both author and song indices required by the songs package and set the chorus font to be bold:

% create both song and author indices

ewindex{reltitleidx}{cbreltitle}

ewauthorindex{relauthidx}{cbrelauth} % bold chorus font \renewcommand{\chorusfont}{\bfseries}

Thanks to egreg, the following code will add the song number instead of the page number to my indices entries:

% add the song number instead of % page number \makeatletter \patchcmd{\@wrindex}{\thepage}{\thesongnum}{}{}% \makeatother

Now it's simple enough. The document begins and the songs are added:

\begin{document} \showindex{My songs}{reltitleidx} \begin{songs}{reltitleidx,relauthidx} \beginsong{My cool song}[by={Some guy},sr={},cla={\classify{F,B}},cr={\settime{A,C}},tin={\drawbullets{A,C}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \beginsong{Another cool song}[by={Some guy},sr={},cla={\classify{B}},cr={\settime{A}},tin={\drawbullets{A}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \beginsong{Cool cool cool}[by={Some guy},sr={},cla={\classify{FB}},cr={\settime{D}},tin={\drawbullets{D}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \beginsong{Cooler song}[by={Some guy},sr={},cla={\classify{Q}},cr={\settime{A,D}},tin={\drawbullets{A,D}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \beginsong{Cool yeah}[by={Some guy},sr={},cla={\classify{F,FB}},cr={\settime{B,C}},tin={\drawbullets{B,C}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \beginsong{Coolness}[by={Some guy},sr={},cla={\classify{B,Q}},cr={\settime{C}},tin={\drawbullets{C}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \beginsong{Hallelujah cool!}[by={Some guy},sr={},cla={\classify{F,Q}},cr={\settime{B}},tin={\drawbullets{B}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \beginsong{Coolest song!}[by={Some guy},sr={},cla={\classify{F}},cr={\settime{A,B}},tin={\drawbullets{A,B}}] \beginchorus This is a cool song, I wrote it by myself! \rep{2} \endchorus \beginverse Meow, said the cat! Of course you will love this song! \endverse \endsong \end{songs} \printindex[foo] \printindex[bar] \printindex[foobar] \printindex[qux] \end{document}

The output is as we expect:

And the indices are correct:

I can now easily find the songs I want! By the way, my original songbook has now 2000+ songs, powered by LaTeX. :)