Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}}
\fancyhead[LE,RO]{\mymarks} 
\fancyhead[LO,RE]{\thepage}

\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:

Header

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:

The shame!

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?

share|improve this question
add comment

1 Answer 1

up vote 3 down vote accepted

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.

share|improve this answer
    
Fantastic answer, egreg! Thanks a lot. :) –  Paulo Cereda Nov 16 '11 at 8:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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