10

I am creating a book with guitar chords using a customized version of the songbook package. As most songs use the same chorus multiple times, I created the very simple macro \refChorus which just prints out [Chorus] and is defined like so:

\newcommand*{\refChorus}{\textsf{\textbf{[Chorus]}}}

Pretty basic. In the songbook package, a chorus is contained in the SBChorus environment. Now here's my question:

Is it possible in LaTeX to change the \refChorus command so it repeats the last chorus? Implementation wise I would guess that I just define a variable which is updated with each chorus occurrence to hold the content of that environment and then a command to just print out this variable. Unfortunately I have no idea how to accomplish that.

I want to redefine the command \refChorus so this code

\begin{SBChorus}
    This is chorus 1
\end{SBChorus}
\refChorus
\refChorus

\begin{SBChorus}
    This is chorus 2
\end{SBChorus}
\refChorus

Outputs

This is chorus 1

This is chorus 1

This is chorus 1

This is chorus 2

This is chorus 2

EDIT: I have been asked to provide a compilable example. This is it:

\documentclass[12pt]{book}
\usepackage[chordbk]{songbook} 

\newcommand*{\refChorus}{\textsf{\textbf{[Chorus]}}}

\begin{document}
    \begin{song}{Songtitle} %Songtitel
        {} %in my version of songbook I am not using this
        {} %or this
        {Composer} 
        {Album} 
        {Year} 

        \begin{SBChorus}
            Chorus with a \Ch{C}{chord}
        \end{SBChorus}

        \refChorus %this just outputs [Chorus] but it should just repeat the last chorus (ideally the first chorus of a song if there's multiple in one song)

    \end{song}

    \begin{song}{Title Song 2} %Songtitel
        {} %in my version of songbook I am not using this
        {} %or this
        {Composer} 
        {Album} 
        {Year} 

        \begin{SBChorus}
            Chorus 2 with a \Ch{G}{chord}
        \end{SBChorus}

        \refChorus %this just outputs [Chorus] but it should just repeat the last chorus (ideally the first chorus of a song if there's multiple in one song)

    \end{song}

\end{document}
  • Welcome to TeX.SX. Please do not post such fragments only. Provide a compilable document. It should be possible if you catch the content of the environment SBChorus. – user31729 Feb 11 '17 at 14:19
  • According to your definition, \refChorus has an argument, but you call it without argument, this will lead to errors – user31729 Feb 11 '17 at 14:25
10

The following macros redefine the environment SBChorus such that it

  • stores its contents in the macro \lastChorus which then is used by \refChorus if used without an optional argument
  • stores its contents under a name given as an optional argument to the SBchorus environment, which then can be used by \refChorus if given this name as optional argument.

enter image description here

\documentclass{article}
\usepackage[wordbk]{songbook}
\usepackage{environ,ifthen}
\let\origSBChorus\SBChorus
\let\origendSBChorus\endSBChorus
\RenewEnviron{SBChorus}[1][]%
  {\global\let\lastChorus\BODY
   \ifthenelse{\equal{#1}{}}%
     {}%
     {\expandafter\global\expandafter\let\csname BODY:SBchorus:#1\endcsname\BODY}%
   \origSBChorus\lastChorus\origendSBChorus
  }
\newcommand\refChorus[1][]%
   {\origSBChorus
    \ifthenelse{\equal{#1}{}}%
      {\lastChorus}%
      {\csname BODY:SBchorus:#1\endcsname}
    \origendSBChorus
   }
\begin{document}
\begin{SBChorus}[main]% chorus gets label "main"
    This is chorus 1
\end{SBChorus}
\refChorus      % refers to the last chorus
\refChorus[main]% refers to the chorus labeled "main" (which happens to be last chorus)

\begin{SBChorus}
    This is chorus 2
\end{SBChorus}
\refChorus      % refers to the last chorus (which is the second one)
\refChorus[main]% refers to the chorus labeled "main" (which was the first one)
\end{document}
  • This works great, thanks! As every SBChorus is nested in a song environment, would it be possible to only redefine the variable for the first chorus in a song or even store all choruses of a song in an array, accessible via \refChorus[1] etc.? – Taxel Feb 11 '17 at 14:41
  • 1
    @Taxel I've updated my answer. Storing the choruses in an array is not the best solution, since the numbers may change when inserting a new chorus. With my updated solution you can now assign a name to a chorus and later recall it under this name. – gernot says Reinstate Monica Feb 11 '17 at 15:25

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.