# Patching a song environment

I'm having some fun with another songbook project, and this one has a particular feature: in the header, the range of song numbers is displayed, in order to ease the searching (similar to a dictionary).

I'm using both songs and fancyhdr package. Consider the following code:

\documentclass[twoside]{article}

\usepackage{ifthen}
\usepackage{fancyhdr}

\renewcommand{\sectionmark}[1]{}
\newcommand{\mymarks}{%
\ifthenelse{\equal{\leftmark}{\rightmark}}
{\rightmark}
{From \rightmark\ until \leftmark}}

\pagestyle{fancy}

\usepackage[lyric]{songs}
\newindex{titleidx}{cbtitle}

\begin{document}

\songpos{0}

\begin{songs}{titleidx}

\beginsong{Amazing Grace}[
by={John Newton},
sr={Luke 15:4; 2 Corinthians 4:8,9; Ephesians 2:8; Revelation 14:3},
cr={Public domain.}]

\markboth{\thesongnum}{\thesongnum}

\beginverse
A\[E]mazing \[E/D#]grace! How \[A/C#]sweet the \[E/B]sound
That \[E]saved a \[E/C#]wretch like \[B7]me!
I \[E]once was \[E/D#]lost, but \[A/C#]now am \[E/B]found;
Was \[A]blind, but \[A/B]now I \[E]see.
\endverse

\beginverse
T'was ^grace that ^taught my ^heart to ^fear,
And ^grace my ^fears re^lieved;
How ^precious ^did that ^grace ap^pear
The ^hour I ^first be^lieved!
\endverse

\endsong

<<... MORE SONGS HERE ...>>

\end{songs}

\end{document}


The code works like a charm:

The magic happens with \markboth{\thesongnum}{\thesongnum} in every song; \thesongnum represents the current song number. So far so good.

I'd like to avoid repetition, so I decided to add some spice with etoolbox. My first idea was to append the magic line right after the beginning of the song environment.

I came up with the following line:

\apptocmd{\beginsong}{\markboth{\thesongnum}{\thesongnum}}{}{}


And it works. Well, kind of. The options enclosed between squared brackets are ignored:

I'm probably patching it wrong. Wait, I am patching it wrong. But I can't figure out how would be the correct way to do it.

I could patch the \endsong command with:

\pretocmd{\endsong}{\markboth{\thesongnum}{\thesongnum}}{}{}


And it would work, except for the fact that when a song goes in two pages, the mark points to the second page, not the first one where the song starts. So I have to somehow patch the first one.

Any ideas?

-

You should try and patch the \SB@@@beginsong command:

\makeatletter
\appto\SB@@@beginsong{\markboth{\thesongnum}{\thesongnum}}
\makeatother


In general, patching a command with an optional argument is tricky. If it's defined via the general LaTeX mechanism, the command to patch must be called via

\expandafter\patchcmd\csname\string\xyz\endcsname...


where \patchcmd stands for one of etoolbox commands for patching. If, as in this case, the command is defined via \@ifnextchar, one has to follow all the called macro. Here \SB@@@beginsong seems to be the last one.

-
Fantastic answer, egreg! Thanks a lot. :) –  Paulo Cereda Nov 16 '11 at 8:14