summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/songs/songs.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/songs/songs.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/songs/songs.dtx')
-rw-r--r--macros/latex/contrib/songs/songs.dtx12455
1 files changed, 12455 insertions, 0 deletions
diff --git a/macros/latex/contrib/songs/songs.dtx b/macros/latex/contrib/songs/songs.dtx
new file mode 100644
index 0000000000..3f6889fda2
--- /dev/null
+++ b/macros/latex/contrib/songs/songs.dtx
@@ -0,0 +1,12455 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2018 Kevin W. Hamlen
+%
+% This program is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License
+% as published by the Free Software Foundation; either version 2
+% of the License, or (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 51 Franklin Street, 5th Floor, Boston,
+% MA 02110-1301, USA.
+%
+% The latest version of this program can be obtained from
+% http://songs.sourceforge.net.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{songs.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{songs}
+%<*package>
+ [2018/09/12 v3.1 Songs package]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+
+% This documentation compiles as part of the Songs self-installer, so it
+% needs to work even on tiny LaTeX installations with few packages. We
+% therefore try to be especially robust to missing package failures.
+\newcommand\trypackage[4][]{\IfFileExists{#2.sty}{\usepackage[#1]{#2}#3}{#4}}
+\trypackage{microtype}{\linepenalty=20 \parfillskip=0pt plus\textwidth\relax}{}
+\trypackage{lmodern}{\usepackage[T1]{fontenc}}{}
+\trypackage{ifpdf}{}{\expandafter\newif\csname ifpdf\endcsname\pdffalse}
+\trypackage{color}{}{}
+\ifpdf
+ \trypackage[bookmarks,linkbordercolor={.6 0 0}]{hyperref}{}{}
+\fi
+\usepackage[nopdfindex]{songs}
+
+% Provide back-up hyperlinking and color macros that do nothing,
+% in case the hyperref and/or color packages are absent.
+\providecommand\href[2]{#2}
+\providecommand\url[1]{#1}
+\providecommand\pdfbookmark[3][]{}
+\providecommand\hyperdef[3]{}
+\providecommand\hyperlink[2]{#2}
+\providecommand\texorpdfstring[2]{#1}
+\providecommand\definecolor[3]{}
+\providecommand\color[1]{}
+\providecommand\textcolor[2]{#2}
+\providecommand\microtypesetup[1]{}
+
+% Configure the document:
+\let\oldSE\StopEventually
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+%\OnlyDescription
+
+% Create the \Songs logo, if the musix13 font is available:
+\newcommand\Songs{\texorpdfstring{{\sffamily songs}}{songs}}
+\newcount\imode
+\imode=\interactionmode
+\batchmode
+\newfont\musicfont{musix13}
+\interactionmode=\imode
+\ifx\musicfont\nullfont\else
+ \newdimen\msize
+ \newcommand\wholenote{%
+ \msize4ex
+ \expandafter\ifx\csname musicfont\the\msize\endcsname\relax
+ \expandafter\newfont\csname musicfont\the\msize\endcsname
+ {musix13 at \the\msize}%
+ \fi
+ \kern.13ex
+ \raise.5ex\hbox{{\csname musicfont\the\msize\endcsname\symbol9}}%
+ \kern1.53ex
+ }
+ \renewcommand\Songs{\texorpdfstring{{\sffamily s\wholenote ngs}}{songs}}
+\fi
+
+% Create the logo for Christopher Rath's Songbook package:
+\newcommand{\Rath}{{\sffamily Song$\flat$ook}}
+
+% Colors
+\definecolor{myred}{rgb}{0.6,0,0}
+\definecolor{myblu}{rgb}{0,0,0.6}
+\definecolor{mygra}{gray}{0.33}
+\def\PrintDescribeMacro#1{\strut{\MacroFont\color{myred}\string#1}\ }
+\let\PrintMacroName\PrintDescribeMacro
+\def\PrintDescribeEnv#1{\strut{\MacroFont\color{myred}#1}\ }
+\let\PrintEnvName\PrintDescribeEnv
+{\makeatletter\gdef\verbatim@font{\normalfont\color{myblu}\ttfamily}}
+
+% For some reason, doc.sty removes the \verbatim@font customization hook
+% for \verb|...|. (Why??) That's not nice, so we put it back:
+{\makeatletter
+ \gdef\verb {\relax\ifmmode\hbox\else\leavevmode\null\fi
+ \bgroup \let\do\do@noligs \verbatim@nolig@list
+ \verbatim@font \verb@eol@error \let\do\@makeother \dospecials
+ \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}}
+}
+
+% Define some environments to simulate the interior of a verse,
+% for showing samples in the documentation:
+{\makeatletter
+ \gdef\likeverse{%
+ \SB@insongtrue\SB@inversetrue
+ \SB@loadactives
+ \global\SB@ctail\SB@cr@
+ }
+ \gdef\chordheight{\SB@setbaselineskip}
+}
+
+% Typeset a block of LaTeX code:
+\newcommand\pfs{\parfillskip0pt plus1fil\relax}
+\newenvironment{codeblock}{%
+ \medskip
+ \begingroup
+ \ifdim\parindent=0pt \parindent=20pt\fi
+ \indent\vbox\bgroup
+ \hsize\linewidth
+ \advance\hsize-\parindent
+ \rightskip=0pt plus1fil\pfs
+ \parindent=0pt
+ \color{myblu}%
+ \obeylines
+}{%
+ \egroup\endgroup
+ \medskip
+}
+
+% Typeset a sample song or scripture quotation:
+\songcolumns{0}
+\newenvironment{sample}{%
+ \medskip
+ \noindent\hfil
+ \vbox\bgroup
+ \hsize.5\hsize
+ \advance\hsize-.5\columnsep
+ \versesep=5pt
+ \pfs
+}{%
+ \egroup{\pfs\par}\medskip
+}
+
+% Typeset a sample lyric book fragment:
+\newenvironment{lyrics}{%
+ \medskip
+ \noindent\hfil
+ \vbox\bgroup\begingroup
+ \hsize=.7\textwidth
+ \leftskip=20pt\rightskip=0pt plus1fil\pfs
+ \parindent=-20pt
+ \likeverse\obeylines
+}{%
+ \par\endgroup\egroup
+ \hfil{\pfs\par}
+ \medskip
+}
+
+% Typeset a sample chord book fragment:
+\newenvironment{chorded}{%
+ \medskip
+ \noindent\hfil
+ \vbox\bgroup\begingroup
+ \hsize=.7\textwidth
+ \leftskip=20pt\rightskip=0pt plus1fil\pfs
+ \parindent=-20pt
+ \likeverse\obeylines
+ \versesep=5pt\chordheight
+}{%
+ \par\endgroup\egroup
+ \hfil{\pfs\par}
+ \medskip
+}
+
+% Typeset a "<code> produces <text>" example:
+\newlength\prodlen
+\setlength{\prodlen}{2.7in}
+\newbox\prodbox
+\newcommand{\example}{%
+ \medskip\setbox\prodbox\hbox\bgroup\begingroup\color{myblu}%
+}
+\newcommand{\produces}{%
+ \endgroup\egroup
+ \indent
+ \vbox{\hbox to\prodlen{\unhbox\prodbox\hfil}}
+ \ {\it produces}\quad
+ \afterassignment\prodprefix
+ \setbox\prodbox\hbox
+}
+\newcommand{\prodprefix}{%
+ \likeverse\chordheight
+ \aftergroup\prodsuffix
+}
+\newcommand{\prodsuffix}{\unhbox\prodbox{\pfs\par}\medskip}
+\newbox\vcbox
+\newdimen\vcadjust
+\newcommand{\vcenterbox}[1]{%
+ \setbox\vcbox\vbox{\hbox{#1}}%
+ \vcadjust=.5\ht\vcbox
+ \advance\vcadjust by-6pt
+ \lower\vcadjust\box\vcbox
+}
+
+% Recode \DescribeMacro and \DescribeEnv to make nice pdfbookmark entries.
+% Also create some \MainImpl macros that make pdfbookmarks to help the reader
+% find the "real" implementations of important macros.
+\newcount\seclevel
+\newcommand\mybookmark[2]{%
+ \ifnum\value{subsection}=0 \seclevel=2
+ \else\ifnum\value{subsubsection}=0 \seclevel=3
+ \else\seclevel=4 \fi\fi
+ \setcounter{tocdepth}{4}%
+ \pdfbookmark[\the\seclevel]{#1}{#2}%
+ \setcounter{tocdepth}{3}%
+}
+{\makeatletter
+ \xdef\bschar{\@backslashchar}
+ \global\let\For\@for}
+\newcommand\DescMacro[1]{%
+ \ifhmode\unskip\fi
+ \mybookmark{\bschar\bschar#1}{macdef-#1}%
+ \expandafter\DescribeMacro\expandafter{\csname#1\endcsname}%
+ \hyperdef{macro}{#1}{}\unpenalty
+ \ignorespaces
+}
+\newcommand\DescMacroGroup[3]{%
+ \ifhmode\unskip\fi
+ \mybookmark{\bschar\bschar#2}{macdef-#1}%
+ \expandafter\DescribeMacro\expandafter{\csname#2\endcsname}%
+ \For\temp:=#3\do{\hyperdef{macro}{\temp}{}}\unpenalty
+ \ignorespaces
+}
+\newcommand\MainImpl[1]{%
+ \pdfbookmark[3]{\bschar\bschar#1}{mimpl-#1}%
+}
+\newcommand{\DescEnv}[1]{%
+ \ifhmode\unskip\fi
+ \mybookmark{#1}{envdef-#1}%
+ \DescribeEnv{#1}%
+ \hyperdef{env}{#1}{}\unpenalty
+ \ignorespaces
+}
+\newcommand{\MainEnvImpl}[1]{%
+ \mybookmark{#1}{eimpl-#1}%
+}
+
+% Create macros to hyperlink macro and environment names to their
+% documentation points.
+\newcommand{\mac}[1]{{\tt\hyperlink{macro.#1}{\textcolor{myblu}{\char92 #1}}}}
+\newcommand{\env}[1]{{\tt\hyperlink{env.#1}{\textcolor{myblu}{#1}}}}
+
+% Defining bookmarks for definitions of active characters is a little trickier
+% because many of these characters have special meanings either to TeX or to
+% PDF. The only reliable way is to insert an "\ooo" escape sequence into the
+% bookmark text, where ooo is the ascii number of the character expressed in
+% octal. To achieve this, we use `\string<symbol> to obtain the decimal
+% ascii number d of the symbol, then do some math (implemented in \octal)
+% to compute and tokenize each octal digit of d into the bookmark text.
+\newcount\cnta
+\newcount\cntb
+\newcommand\ooo{}
+\newcommand\octal{%
+ \cntb\cnta
+ \divide\cnta8
+ \multiply\cnta-8
+ \advance\cntb\cnta
+ \edef\ooo{\the\cntb\ooo}%
+ \divide\cnta-8
+}
+\newcommand{\DescChar}[2]{%
+ \ifhmode\unskip\fi
+ \expandafter\let\csname string#1\expandafter\endcsname
+ \expandafter=\string#2%
+ \cnta\expandafter`\string#2%
+ \def\ooo{}\octal\octal\octal
+ \mybookmark{\bschar\ooo}{#1def}%
+ {\def\SpecialUsageIndex##1{}%
+ \expandafter\DescribeMacro\string#2}%
+ \hyperdef{env}{#1}{}\unpenalty
+ \ignorespaces
+}
+\newcommand{\refchar}[1]{{\tt\hyperlink{env.#1}{\csname string#1\endcsname}}}
+
+% At the end of the implementation section we'll have a code line index of
+% macro definitions and usages. To make it look a bit less ragged than the
+% default index style and to conserve some space, we'll customize a few of
+% the parameters:
+
+\IndexPrologue{%
+ \subsection{Codeline Index}%
+ Underlined numbers refer to the code line where the corresponding entry
+ is defined; other numbers refer to the code lines where the entry
+ is used.}
+
+{\makeatletter
+
+ \gdef\IndexParms{%
+ \sfcode`,=1750
+ \parindent0pt
+ \columnsep15pt
+ \parskip0pt plus1pt
+ \rightskip0pt
+ \mathsurround0pt
+ \parfillskip0pt
+ \small
+ \microtypesetup{protrusion=false}%
+ \def\@idxitem{\par\hangindent15pt}%
+ \def\subitem{\@idxitem\hspace*{15pt}}%
+ \def\subsubitem{\@idxitem\hspace*{25pt}}%
+ \def\indexspace{\par\vspace{10pt plus 2pt minus 3pt}}}
+
+ \gdef\SpecialMainOptIndex#1{%
+ \@bsphack
+ \special@index{%
+ #1\actualchar{\string\ttfamily\space#1} (option)\encapchar main}%
+ \special@index{%
+ options:\levelchar
+ #1\actualchar{\string\ttfamily\space#1}\encapchar main}%
+ \@esphack}
+}
+
+% Create a conditional that typesets its first argument if we're including
+% the implementation section, otherwise typesets its second argument.
+\newcommand\ImplOrDesc[2]{%
+ \ifx\StopEventually\oldSE#1\else#2\fi
+}
+
+% Hyphenating the word "choruses" looks weird. No "ruses" please!
+\hyphenation{choruses white-space}
+
+% An environment for describing the implementation of a package option:
+\let\oldsmei\SpecialMainEnvIndex
+\newenvironment{option}[1]{%
+ \let\SpecialMainEnvIndex\SpecialMainOptIndex
+ \begin{environment}{#1}%
+ \let\SpecialMainEnvIndex\oldsmei
+}{%
+ \end{environment}%
+ \let\SpecialMainEnvIndex\oldsmei
+}
+
+% Describe the default setting for an option:
+\newcommand\optdef[1]{\noindent{\it(Default: #1)}\hspace{.5cm}}
+
+% Typeset a chord name:
+\newcommand{\chord}[1]{{\sffamily\slshape#1}}
+
+% Here are a few macros to produce nice syntax parameters:
+\newcommand\Meta[1]{{\color{mygra}\meta{#1}}}
+\newcommand\argp[1]{\Meta{arg#1}}
+\newcommand\Metarm[1]{\textrm{\Meta{#1}}}
+\newcommand\OR{\,$\mid$\,}
+\newcommand\SPC{\char`\ }
+
+% Now let's quell those annoying "Marginpar has moved" warning messages.
+{\makeatletter
+ \global\let\oldamp=\@addmarginpar
+ \global\let\oldlwnl=\@latex@warning@no@line
+ \gdef\@addmarginpar{%
+ \let\@latex@warning@no@line\@gobble
+ \oldamp
+ \let\@latex@warning@no@line\oldlwnl
+ }
+}
+
+% The \eat macro just gobbles its argument. I use it to appease my syntax
+% highlighter when it gets confused.
+\newcommand{\eat}[1]{}
+
+\begin{document}
+ \DocInput{songs.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{8935}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \changes{v1.0}{2001/12/01}{Initial version}
+% \changes{v1.1}{2005/04/03}{Change log introduced and first release of this documentation}
+% \changes{v1.17}{2005/09/24}{Transformed the source from a class to a package}
+% \changes{v1.18}{2005/09/29}{Verse numbering added}
+% \changes{v2.0}{2007/06/20}{Keyval syntax and chord-replay system added}
+%
+% \iffalse
+% Here we list all the macros that should not be indexed because they are:
+% (a) too common and therefore the index would be too large if we listed them,
+% (b) not useful in an index because they are predefined TeX macros, or
+% (c) not really macros but rather control sequence names given to \string.
+% \fi
+% \DoNotIndex{\@M,\@depth,\@empty,\@firstofone,\@firstoftwo,\@gobble,\@gobbletwo,\@height,\@m,\@minus,\@ne,\@plus,\@secondoftwo,\@width,\m@ne,\p@,\thr@@,\tw@,\voidb@x,\@xpt,\z@,\z@skip}
+% \DoNotIndex{\advance,\char,\count,\divide,\font,\fontdimen,\maxdimen,\multiply,\setcounter,\setlength,\settoheight,\settowidth,\stepcounter}
+% \DoNotIndex{\begin,\begingroup,\bgroup,\egroup,\end,\endgroup}
+% \DoNotIndex{\box,\copy,\dp,\hbox,\ht,\leavevmode,\lower,\null,\prevdepth,\raise,\rlap,\setbox,\unhbox,\unhcopy,\unpenalty,\unskip,\unvbox,\unvcopy,\vbox,\vtop,\wd}
+% \DoNotIndex{\csname,\def,\edef,\endcsname,\futurelet,\gdef,\global,\let,\long,\mathchardef,\newcommand,\renewcommand,\renewenvironment,\xdef}
+% \DoNotIndex{\@ifundefined,\@for,\do,\else,\fi,\ifcase,\ifcat,\ifdim,\iffalse,\ifhmode,\ifmmode,\ifinner,\ifnum,\ifodd,\ifvbox,\ifvmode,\ifvoid,\ifx,\loop,\or,\repeat,\undefined}
+% \DoNotIndex{\afterassignment,\aftergroup,\expandafter,\ignorespaces,\immediate,\noexpand,\protect,\relax,\space,\string,\the}
+% \DoNotIndex{\hfil,\hfilneg,\hskip,\hss,\indent,\kern,\nobreak,\noindent,\nointerlineskip,\offinterlineskip,\par,\penalty,\strut,\thinspace,\vadjust,\vfil,\vfilneg,\vphantom,\vskip}
+% \DoNotIndex{\@octets,\four,\three,\two,\UTFviii@,\UTFviii@zero@octets,\0,\1,\2,\3,\4,\5,\6,\7,\8,\9,\X,\O}
+%
+% \GetFileInfo{songs.dtx}
+%
+% \title{The \Songs{} package\thanks{This manual documents
+% \textsf{songs}~\fileversion, dated~\filedate,
+% \copyright~2018 Kevin W.~Hamlen, and
+% distributed under version~2 the GNU General Public License
+% as published by the Free Software Foundation.}}
+% \author{Kevin W. Hamlen}
+%
+% \maketitle
+%
+% \begin{abstract}
+% The \Songs{} package produces songbooks that contain lyrics and chords
+% (but not full sheet music).
+% It allows lyric books, chord books, overhead slides, and digital projector
+% slides to all be maintained and generated from a single \LaTeX{} source
+% document.
+% Automatic transposition, guitar tablature diagrams, handouts, and
+% a variety of specialized song indexes are supported.
+% \end{abstract}
+%
+% \section{Introduction}
+%
+% The \Songs{} \LaTeX{} package produces books of songs that contain lyrics and
+% (optionally) chords.
+% A single source document yields a lyric book for singers, a chord book for
+% musicians, and overhead or digital projector slides for corporate singing.
+%
+% The software is especially well suited for churches and religious
+% fellowships desiring to create their own books of worship songs.
+% Rather than purchasing a fixed hymnal of songs, the \Songs{} package allows
+% worship coordinators to maintain a constantly evolving repertoire of music
+% to which they can add and remove songs over time.
+% As the book content changes, the indexes, spacing, and other formatting
+% details automatically adjust to stay consistent.
+% Songs can also be quickly selected and arranged for specific events or
+% services through the use of scripture indexes, automatic transposition,
+% and handout and slide set creation features.
+%
+% \section{Terms of Use}
+%
+% \noindent
+% The \Songs{} package is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License
+% as published by the Free Software Foundation; either version~2
+% of the License, or (at your option) any later version.
+% A copy of the license can be found in \S\ref{sec:license}.
+%
+% \medskip
+%
+% \noindent
+% This program is distributed in the hope that it will be useful,
+% but {\sc without any warranty}; without even the implied warranty of
+% {\sc merchantability} or {\sc fitness for a particular purpose}. See the
+% GNU General Public License in \S\ref{sec:license} for details.
+% A copy of the license can also be obtained by writing to the
+% Free Software Foundation, Inc., 51 Franklin Street, 5th Floor,
+% Boston, MA 02110-1301, USA.
+%
+% \medskip
+%
+% \noindent
+% This software is copyright \copyright~2018 Kevin W.~Hamlen.
+% For contact information or the latest version, see the project webpage at:
+%
+% \vskip1.5ex
+% \begingroup\centering\noindent
+% \href{http://songs.sourceforge.net}{{\tt http://songs.sourceforge.net}}\par
+% \endgroup
+%
+% \section{Sample Document}
+%
+% For those who would like to start making song books quickly, the
+% following is a sample document that yields a simple song book with
+% one song.
+% Starting from this template, you can begin to add songs and customizations
+% to create a larger book.
+% Instructions for compiling this sample song book follow the listing.
+%
+% \begingroup\color{myblu}
+% \begin{verbatim}
+% \documentclass{article}
+% \usepackage[chorded]{songs}
+%
+% \noversenumbers
+%
+% \begin{document}
+%
+% \songsection{Worship Songs}
+%
+% \begin{songs}{}
+% \beginsong{Doxology}[by={Louis Bourgeois and Thomas Ken},
+% sr={Revelation 5:13},
+% cr={Public domain.}]
+% \beginverse
+% \[G]Praise God, \[D]from \[Em]Whom \[Bm]all \[Em]bless\[D]ings \[G]flow;
+% \[G]Praise Him, all \[D]crea\[Em]tures \[C]here \[G]be\[D]low;
+% \[Em]Praise \[D]Him \[G]a\[D]bove, \[G]ye \[C]heav'n\[D]ly \[Em]host;
+% \[G]Praise Fa\[Em]ther, \[D]Son, \[Am]and \[G/B G/C]Ho\[D]ly \[G]Ghost.
+% \[C]A\[G]men.
+% \endverse
+% \endsong
+% \end{songs}
+%
+% \end{document}
+% \end{verbatim}
+% \endgroup\nointerlineskip\vskip-6pt plus0pt minus0pt
+%
+% To compile this book, run \LaTeX{} (|pdflatex| is recommended):
+%
+% \begin{codeblock}
+% |pdflatex mybook.tex|
+% \end{codeblock}
+%
+% \noindent
+% (where |mybook.tex| is the name of the source document above).
+% The final document is named |mybook.pdf| if you use |pdflatex| or
+% |mybook.dvi| if you use regular |latex|.
+%
+% Note that compiling a document that includes indexes requires extra steps.
+% See \S\ref{sec:compiling} for details.
+%
+% \begin{figure}
+% \noindent\vbox{\begingroup\hsize=352pt
+% \versesep=12pt\columnsep=7pt\parindent=20pt
+% \def\colbotglue{0pt}\def\lastcolglue{0pt}
+% \baselineadj=-1pt\relax
+% \noversenumbers
+% \setlength\textwidth{352pt}
+% \setlength\textheight{498pt}
+% \songcolumns{2}
+% \vskip-3.5ex plus-1ex minus-.2ex
+% \nointerlineskip\null\nointerlineskip
+% \songsection*{Worship Songs}
+% \begin{songs}{}
+% \beginsong{Doxology}[
+% by={Louis Bourgeois and Thomas Ken},
+% sr={Revelation 5:13},
+% cr={Public domain.}]
+% \beginverse
+% \[G]Praise God, \[D]from \[Em]Whom \[Bm]all \[Em]bless\[D]ings \[G]flow;
+% \[G]Praise Him, all \[D]crea\[Em]tures \[C]here \[G]be\[D]low;
+% \[Em]Praise \[D]Him \[G]a\[D]bove, \[G]ye \[C]heav'n\[D]ly \[Em]host;
+% \[G]Praise Fa\[Em]ther, \[D]Son, \[Am]and \[G/B G/C]Ho\[D]ly \[G]Ghost.
+% \[C]A\[G]men.
+% \endverse
+% \endsong\eat\]
+% \parindent=15pt
+% \beginscripture{Psalm 18:2-6}
+% \Acolon The LORD is my rock and my fortress and my deliverer,
+% \Bcolon my God, my rock, in whom I take refuge,
+% \Bcolon my shield, and the horn of my salvation, my stronghold.
+% \Acolon I call upon the LORD, who is worthy to be praised,
+% \Bcolon and I am saved from my enemies.
+% \strophe
+% \Acolon The cords of death encompassed me;
+% \Bcolon the torrents of destruction assailed me;
+% \Acolon the cords of Sheol entangled me;
+% \Bcolon the snares of death confronted me.
+% \strophe
+% \Acolon In my distress I called upon the LORD;
+% \Bcolon to my God I cried for help.
+% \Acolon From his temple he heard my voice,
+% \Bcolon and my cry to him reached his ears.
+% \endscripture
+% \parindent=20pt
+% \beginsong{A Mighty Fortress Is Our God}[
+% by={Martin Luther},
+% cr={Public Domain.}]
+% \beginverse
+% A \[A]mighty \[C#m]Fortress \[B7]is our \[E]God,
+% A \[D]bulwark \[A]never \[E7]fail\[A]ing.
+% Our helper \[C#m]He, a\[B7]mid the \[E]flood
+% Of \[D]mortal \[A]ills pre\[E7]vail\[A]ing.
+% For still our \[B7sus4]an\[B7]cient \[E]foe
+% Doth \[A]seek to \[E/G#]work us \[F#m]woe;
+% His craft and \[B7]pow'r are \[E]great,
+% And, \[Bm]armed with cruel \[C#]hate,
+% On \[D]earth is \[A]not his \[E7]e\[A]qual.
+% \endverse
+% \beginverse
+% Did ^we in ^our own ^strength con^fide,
+% Our ^striving ^would be ^los^ing.
+% Were not the ^right Man ^on our ^side,
+% The ^Man of ^God's own ^choos^ing.
+% Dost ask who ^that ^may ^be?
+% Christ ^Jesus, ^it is ^He;
+% Lord Saba^oth His ^Name,
+% From ^age to age the ^same;
+% And ^He must ^win the ^bat^tle.
+% \endverse
+% \endsong\eat\]
+% \end{songs}
+% \endgroup}\par
+% \caption{Sample page from a chord book}\label{fig:sample}
+% \end{figure}
+% A copy of the first page of a sample song section is shown in
+% Figure~\ref{fig:sample}.
+% The page shown in that figure is from a chorded version of the book.
+% When generating a lyric version, the chords are omitted.
+% See \S\ref{sec:options} for information on how to generate different
+% versions of the same book.
+%
+% \section{Initialization and Options}\label{sec:options}
+%
+% Each \LaTeX{} document that uses the \Songs{} package should contain a
+% line like the following near the top of the document:
+%
+% \begin{codeblock}
+% |\usepackage[|\Meta{options}|]{songs}|
+% \end{codeblock}
+%
+% \noindent
+% Supported \Meta{options} include the following:
+%
+% \paragraph{Output Type.}
+% \DescEnv{lyric}
+% \DescEnv{chorded}
+% \DescEnv{slides}
+% \DescEnv{rawtext}
+% The \Songs{} package can produce four kinds of books: lyric books, chord
+% books, books of overhead slides, and raw text output.
+% You can specify which kind of book is to be produced by specifying one of
+% |lyric|, |chorded|, |slides|, or |rawtext| as an option.
+% The |slides| and |chorded| options can be used together to create chorded
+% slides.
+% If no output options are specified, |chorded| is the default.
+%
+% Lyric books omit all chords, whereas chord books include chords and
+% additional information for musicians (specified using \mac{musicnote}).
+% Books of overhead slides typeset one song per page in a large font, centered.
+%
+% Raw text output yields an ascii text file named \Meta{jobname}|.txt|
+% (where \Meta{jobname} is the root filename) containing lyrics without chords.
+% This can be useful for importing song books into another program, such as a
+% spell-checker.
+%
+% \DescMacro{chordson}
+% \DescMacro{chordsoff}
+% Chords can be turned on or off in the middle of the document
+% by using the |\chordson| or |\chordsoff| macros.
+%
+% \DescMacro{slides}
+% Slides mode can be activated in the middle of the document by using the
+% |\slides| macro.
+% For best results, this should typically only be done in the document
+% preamble or at the beginning of a fresh page.
+%
+% \paragraph{Measure Bars.}
+% \DescEnv{nomeasures}
+% \DescEnv{showmeasures}
+% \DescMacro{measureson}
+% \DescMacro{measuresoff}
+% The \Songs{} package includes a facility for placing measure bars in chord
+% books (see \S\ref{sec:measures}).
+% To omit these measure bars, use the |nomeasures| option;
+% to display them, use the |showmeasures| option (the default).
+% Measure bars can also be turned on or off in the middle of the document by
+% using the |\measureson| or |\measuresoff| macros.
+%
+% \paragraph{Transposition.}
+% \DescEnv{transposecapos}
+% The |transposecapos| option changes the effect of the \mac{capo} macro.
+% Normally, using |\capo{|\Meta{n}|}| within a song environment produces a
+% textual note in chord books that suggests the use of a guitar capo on fret
+% \Meta{n}.
+% However, when the |transposecapos| option is active, these textual notes
+% are omitted and instead the effect of |\capo{|\Meta{n}|}| is the
+% same as for \mac{transpose}|{|\Meta{n}|}|.
+% That is, chords between the \mac{capo} macro and the end of the song are
+% automatically transposed up by \Meta{n} half-steps.
+% This can be useful for adapting a chord book for guitarists to one that can
+% be used by pianists, who don't have the luxury of capos.
+% See \S\ref{sec:notes} and \S\ref{sec:transpose} for more information on the
+% \mac{capo} and \mac{transpose} macros.
+%
+% \paragraph{Indexes.}
+% \DescEnv{noindexes}
+% \DescMacro{indexeson}
+% \DescMacro{indexesoff}
+% The |noindexes| option suppresses the typesetting of any in-document indexes.
+% Display of indexes can also be turned on or off using the |\indexeson| and
+% |\indexesoff| macros.
+%
+% \DescEnv{nopdfindex}
+% PDF bookmark entries and hyperlinks can be suppressed with the |nopdfindex|
+% option.
+% For finer control of PDF indexes, see \S\ref{sec:idxcust}.
+%
+% \paragraph{Scripture Quotations.}
+% \DescEnv{noscripture}
+% \DescMacro{scriptureon}
+% \DescMacro{scriptureoff}
+% The |noscripture| option omits scripture quotations (see
+% \S\ref{sec:scripture}) from the output.
+% You can also turn scripture quotations on or off in the middle of the
+% document by using |\scriptureon| or |\scriptureoff|, respectively.
+%
+% \paragraph{Shaded Boxes.}
+% \DescEnv{noshading}
+% The |noshading| option causes all shaded boxes, such as those that surround
+% song numbers and textual notes, to be omitted.
+% You might want to use this option if printing such shaded boxes causes
+% problems for your printer or uses too much ink.
+%
+% \paragraph{Partial Song Sets.}
+% \DescMacro{includeonlysongs}
+% Often it is useful to be able to extract a subset of songs from the master
+% document---e.g.~to create a handout or set of overhead slides for a specific
+% worship service.
+% To do this, you can type |\includeonlysongs{|\Meta{songlist}|}| in the
+% document preamble (i.e., before the |\begin{document}| line), where
+% \Meta{songlist} is a comma-separated list of the song numbers to include.
+% For example,
+%
+% \begin{codeblock}
+% |\includeonlysongs{37,50,2}|
+% \end{codeblock}
+%
+% \noindent
+% creates a document consisting only of songs 37, 50, and 2, in that order.
+%
+% Partial books generated with |\includeonlysongs| omit all scripture
+% quotations (\S\ref{sec:scripture}), and ignore uses of
+% \mac{nextcol}, \mac{brk}, \mac{sclearpage}, and \mac{scleardpage}
+% between songs unless they are followed by a star (e.g., \mac{nextcol}|*|).
+% To force a column- or page-break at a specific point in a partial book,
+% add the word |nextcol|, |brk|, |sclearpage|, or |scleardpage| at the
+% corresponding point in the \Meta{songlist}.
+%
+% The |\includeonlysongs| macro only reorders songs within each
+% \env{songs} environment (see \S\ref{sec:songs}), not between different
+% \env{songs} environments.
+% It also cannot be used in conjunction with the \env{rawtext} option.
+%
+% \section{Songs}\label{sec:songs}
+%
+% \subsection{Beginning a Song}
+%
+% \paragraph{Song Sets.}
+% \DescEnv{songs}
+% Songs are contained within |songs| environments.
+% Each |songs| environment begins and ends with:
+%
+% \begin{codeblock}
+% |\begin{songs}{|\Meta{indexes}|}|
+% $\vdots$
+% |\end{songs}|
+% \end{codeblock}
+%
+% \noindent
+% \Meta{indexes} is a comma-separated list of index \Meta{id}'s
+% (see \S\ref{sec:indexes})---one identifier for each index that is to
+% include songs in this song set.
+% Between the |\begin{songs}| and |\end{songs}| lines of
+% a song section only songs (see below) or inter-song environments
+% (see \S\ref{sec:between}) may appear.
+% No text in a |songs| environment may appear outside of these environments.
+%
+% \paragraph{Songs.}
+% \DescMacro{beginsong}
+% \DescMacro{endsong}
+% A song begins and ends with:
+%
+% \begin{codeblock}
+% |\beginsong{|\Meta{titles}|}[|\Meta{otherinfo}|]|
+% $\vdots$
+% |\endsong|
+% \end{codeblock}
+%
+% \noindent
+% Songs should appear only within \env{songs} environments (see above)
+% unless you are supplying your own page-builder (see \S\ref{sec:layout}).
+%
+% In the \mac{beginsong} line, \Meta{titles} is one or more song titles
+% separated by |\\|.
+% If multiple titles are provided, the first is typeset normally
+% atop the song and the rest are each typeset in parentheses on
+% separate lines.
+%
+% The |[|\Meta{otherinfo}|]| part is an optional comma-separated list of
+% key-value pairs (keyvals) of the form \Meta{key}|=|\Meta{value}.
+% The possible keys and their values are:
+%
+% \medskip
+% \noindent\hfil\vbox{\halign{#\hfil&\kern2em{\it#}\hfil\cr
+% |by={|\Meta{authors}|}|&authors, composers, and other contributors\cr
+% |cr={|\Meta{copyright}|}|&copyright information\cr
+% |li={|\Meta{license}|}|&licensing information\cr
+% |sr={|\Meta{refs}|}|&related scripture references\cr
+% |index={|\Meta{lyrics}|}|&an extra index entry for a line of lyrics\cr
+% |ititle={|\Meta{title}|}|&an extra index entry for a hidden title\cr}}
+% {\pfs\par}\medskip
+%
+% \noindent
+% For example, a song that begins and ends with
+%
+% \begin{codeblock}
+% |\beginsong{Title1 \\ Title2}[by={Joe Smith}, sr={Job 3},|
+% | cr={\copyright~|\unskip\expandafter|\the\year|| XYZ.}, li={Used with permission.}]|
+% |\endsong|
+% \end{codeblock}
+%
+% \noindent looks like
+%
+% \begin{sample}
+% \setcounter{songnum}{1}%
+% \vskip1pt%
+% \beginsong{Title1 \\ Title2}[by={Joe Smith}, sr={Job 3},
+% cr={\copyright~\the\year{} XYZ.}, li={Used with permission.}]
+% \endsong
+% \end{sample}
+%
+% The four keyvals used in the above example are described in detail in the
+% remainder of this section;
+% the final two are documented in \S\ref{sec:ientry}.
+% You can also create your own keyvals (see \S\ref{sec:newkey}).
+%
+% \paragraph{Song Authors.}
+% \DescEnv{by=}
+% The |by={|\Meta{authors}|}| keyval lists one or more authors,
+% composers, translators, etc.
+% An entry is added to each author index associated with the current
+% \env{songs} environment for each contributor listed.
+% Contributors are expected to be separated by commas, semicolons, or the
+% word |and|.
+% For example:
+%
+% \begin{codeblock}
+% |by={Fred Smith, John Doe, and Billy Bob}|
+% \end{codeblock}
+%
+% \noindent
+% Words separated by a macro-space (\verb*@\ @\eat*) or tie (|~|)
+% instead of a regular space are treated as single words by the indexer.
+% For example, \verb*@The Vienna Boys' Choir@\eat* is indexed as
+% ``Choir, The Vienna Boys'\thinspace'' but
+% \verb*@The Vienna\ Boys'\ Choir@\eat* is indexed as
+% ``Vienna Boys' Choir, The''.
+%
+% \paragraph{Copyright Info.}
+% \DescEnv{cr=}
+% The |cr={|\Meta{copyright}|}| keyval specifies the copyright-holder of the
+% song, if any.
+% For example:
+%
+% \begin{codeblock}
+% |cr={\copyright~2000 ABC Songs, Inc.}|
+% \end{codeblock}
+%
+% \noindent
+% Copyright information is typeset in fine print at the bottom of the song.
+%
+% \paragraph{Licensing Info.}
+% \DescEnv{li=}
+% \DescMacro{setlicense}
+% Licensing information is provided by |li={|\Meta{license}|}|, where
+% \Meta{license} is any text.
+% Licensing information is displayed in fine print under the song just
+% after the copyright information (if any).
+% Alternatively, writing |\setlicense{|\Meta{license}|}| anywhere between
+% the \mac{beginsong} and \mac{endsong} lines is equivalent to using
+% |li={|\Meta{license}|}| in the \mac{beginsong} line.
+%
+% When many songs in a book are covered by a common license, it is
+% usually convenient to create a macro to abbreviate the licensing
+% information.
+% For example, if your organization has a music license from Christian
+% Copyright Licensing International with license number 1234567, you might
+% define a macro like
+%
+% \begin{codeblock}
+% |\newcommand{\CCLI}{(CCLI \#1234567)}|
+% \end{codeblock}
+%
+% \noindent
+% Then you could write |li=\CCLI| in the \mac{beginsong} line of each song
+% covered by CCLI.
+%
+% \paragraph{Scripture References.}
+% \DescEnv{sr=}
+% The \Songs{} package has extensive support for scripture citations and
+% indexes of scripture citations.
+% To cite scripture references for the song, use the keyval
+% |sr={|\Meta{refs}|}|, where \Meta{refs} is a list of scripture
+% references.
+% Index entries are added to all scripture indexes associated
+% with the current \env{songs} environment for each such reference.
+% The |songidx| index generation script (see \S\ref{sec:compiling}) expects
+% \Meta{refs} to be a list of references in which semicolons are used to
+% separate references to different books, and commas are used to separate
+% references to to different chapters and verses within the same book.
+% For example, one valid scripture citation is
+%
+% \begin{codeblock}
+% |sr={John 3:16,17, 4:1-5; Jude 3}|
+% \end{codeblock}
+%
+% The full formal syntax of a valid \Meta{refs} argument is given in
+% Figure~\ref{fig:srsyntax}.
+% \begin{figure}
+% \noindent\hfil\vbox{\advance\baselineskip2pt
+% \halign{\hfil{\tt#}\,$\longrightarrow$\,&{\tt#}\hfil\cr
+% \Metarm{refs}&\Metarm{nothing}\OR\Metarm{ref};\SPC\Metarm{ref};$\ldots$;\SPC\Metarm{ref}\cr
+% \Metarm{ref}&\Metarm{many-chptr-book}\SPC\Metarm{chapters}\OR\Metarm{one-chptr-book}\SPC\Metarm{verses}\cr
+% \Metarm{many-chptr-book}&Genesis\OR Exodus\OR Leviticus\OR Numbers\OR $\ldots$\cr
+% \Metarm{one-chptr-book}&Obadiah\OR Philemon\OR 2 John\OR 3 John\OR Jude\cr
+% \Metarm{chapters}&\Metarm{chref},\SPC\Metarm{chref},$\ldots$,\SPC\Metarm{chref}\cr
+% \Metarm{chref}&\Metarm{chapter}\OR\Metarm{chapter}-\Metarm{chapter}\OR\Metarm{chapter}:\Metarm{verses}\OR\cr
+% \omit&\quad\Metarm{chapter}:\Metarm{verse}-\Metarm{chapter}:\Metarm{verse}\cr
+% \Metarm{verses}&\Metarm{vref},\Metarm{vref},$\ldots$,\Metarm{vref}\cr
+% \Metarm{vref}&\Metarm{verse}\OR\Metarm{verse}-\Metarm{verse}\cr}}
+% \caption{Formal syntax rules for song scripture references}\label{fig:srsyntax}
+% \end{figure}
+% In those syntax rules, \Meta{chapter} and \Meta{verse} stand for arabic
+% numbers denoting a valid chapter number for the given book, and a valid
+% verse number for the given chapter, respectively.
+% Note that when referencing a book that has only one chapter,
+% one should list only its verses after the book name
+% (rather than |1:|\Meta{verses}).
+%
+% \subsection{Verses and Choruses}
+%
+% \paragraph{Starting A Verse Or Chorus.}
+% \DescMacro{beginverse}
+% \DescMacro{endverse}
+% \DescMacro{beginchorus}
+% \DescMacro{endchorus}
+% Between the \mac{beginsong} and \mac{endsong} lines of a song can
+% appear any number of verses and choruses.
+% A verse begins and ends with:
+%
+% \begin{codeblock}
+% |\beginverse|
+% $\vdots$
+% |\endverse|
+% \end{codeblock}
+%
+% \noindent and a chorus begins and ends with:
+%
+% \begin{codeblock}
+% |\beginchorus|
+% $\vdots$
+% |\endchorus|
+% \end{codeblock}
+%
+% \noindent
+% Verses are numbered (unless \mac{noversenumbers} has been used to
+% suppress verse numbering) whereas choruses have a vertical line placed to
+% their left.
+%
+% To create an unnumbered verse, begin the verse with |\beginverse*| instead.
+% This can be used for things that aren't really verses but should be
+% typeset like a verse (e.g.~intros, endings, and the like).
+% A verse that starts with |\beginverse*| should still end with |\endverse|
+% (not |\endverse*|).
+%
+% Within a verse or chorus you should enter one line of text for
+% each line of lyrics.
+% Each line of the source document produces a separate line in the resulting
+% document (like \LaTeX's |\obeylines| macro).
+% Lines that are too long to fit are wrapped with hanging indentation
+% of width |\parindent|.
+%
+% \subsection{Chords}\label{sec:chords}
+%
+% \DescMacro{[}
+% \DescChar{hash}{#}
+% \DescChar{amp}{&}
+% Between the \mac{beginverse} and \mac{endverse} lines, or between
+% the \mac{beginchorus} and \mac{endchorus} lines,
+% chords can be produced using the macro |\[|\Meta{chordname}|]|\eat\].
+% Chords only appear in chord books; they are omitted from lyric books.
+% The \Meta{chordname} may consist of arbitrary text.
+% To produce sharp and flat symbols, use |#| and |&| respectively.
+%
+% Any text that immediately follows the |\[]|\eat\] macro with no
+% intervening whitespace is assumed to be the word or syllable
+% that is to be sung as the chord is struck, and is therefore
+% typeset directly under the chord.
+% For example:
+%
+% \example|\[E&]peace and \[Am]joy|\produces{\[E&]peace and \[Am]joy}
+% \eat\]
+%
+% \noindent
+% If whitespace (a space or \Meta{return}) immediately follows,
+% then the chord name be typeset without any lyric text
+% below it, indicating that the chord is to be struck between
+% any surrounding words.
+% For example:
+%
+% \example|\[E&]peace and \[Am] joy|\produces{\[E&]peace and \[Am] joy}
+% \eat\]
+%
+% If the lyric text that immediately follows the chord contains
+% another chord, and if the width of the chord name exceeds the
+% width of the lyric text, then hyphenation is added automatically.
+% For example:
+%
+% \example|\[F#sus4]e\[A]ternal|\produces{\[F#sus4]e\[A]ternal}
+% \eat\]
+%
+% Sequences of chords that sit above a single word can be written
+% back-to-back with no intervening space, or as a single chord:
+%
+% \example|\[A]\[B]\[Em]joy|\produces{\[A]\[B]\[Em]joy}
+% \example|\[A B Em]joy|\produces{\[A B Em]joy}
+% \eat\]
+%
+% \noindent
+% The only difference between the two examples above is that the chords
+% in the first example can later be replayed separately (see
+% \S\ref{sec:replay}) whereas the chords in the second example can only be
+% replayed as a group.
+%
+% You can explicitly dictate how much of the text following a
+% chord macro is to appear under the chord name by using braces.
+% To exclude text that would normally be drawn under the chord,
+% use a pair of braces that includes the chord macro.
+% For example:
+%
+% \example|{\[G A]e}ternal|\produces{{\[G A]e}ternal}
+% \eat\]
+%
+% \noindent
+% (Without the braces, the syllables ``ternal'' would not be
+% pushed out away from the chord.)
+% This might be used to indicate that the chord transition occurs
+% on the first syllable rather than as the second syllable is
+% sung.
+%
+% Contrastingly, braces that do not include the chord itself can
+% be used to include text under a chord that would otherwise be
+% excluded.
+% For example:
+%
+% \example|\[Gmaj7sus4]{th' eternal}|\produces{\[Gmaj7sus4]{th' eternal}}
+% \eat\]
+%
+% \noindent
+% Without the braces, the word ``eternal'' would be pushed out away
+% from the chord so that the chord would appear only over
+% the partial word ``th'\thinspace''.
+%
+% \paragraph{Chords Without Lyrics.}
+% \DescMacro{nolyrics}
+% Sometimes you may want to write a line of chords with no lyrics in it at all,
+% such as for an instrumental intro or solo.
+% To make the chords in such a line sit on the baseline instead of raised above
+% it, use the |\nolyrics| macro.
+% For example:
+%
+% \example|{\nolyrics Intro: \[G] \[A] \[D]}|\produces{\nolyrics Intro: \[G] \[A] \[D]}
+% \eat\]
+%
+% \noindent
+% Note the enclosing braces that determine how long the effect should last.
+% Multiple lines can be included in the braces.
+% Instrumental solos should typically not appear in lyric books, so such
+% lines should usually also be surrounded by \mac{ifchorded} and |\fi|
+% (see \S\ref{sec:conditionals}).
+%
+% \paragraph{Symbols Under Chords.}
+% \DescMacro{DeclareLyricChar}
+% If you are typesetting songs in a language whose alphabet contains symbols
+% that \LaTeX{} treats as punctuation, you can use the |\DeclareLyricChar|
+% macro to instruct the \Songs{} package to treat the symbol as
+% non-chord-ending, so that it is included under chords by default just
+% like an alphabetic character.
+%
+% \begin{codeblock}
+% |\DeclareLyricChar{|\Meta{token}|}|
+% \end{codeblock}
+%
+% \noindent
+% Here, \Meta{token} must be a single \TeX{} macro control sequence,
+% active character, letter (something \TeX{} assigns catcode 11), or
+% punctuation symbol (something \TeX{} assigns catcode 12).
+% For example, by default,
+%
+% \example|\[Fmaj7]s\dag range|\produces{\[Fmaj7]s\dag range}
+% \eat\]
+%
+% \noindent
+% because |\dag| is not recognized as an alphabetic symbol;
+% but if you first type,
+%
+% \begin{codeblock}
+% |\DeclareLyricChar{\dag}|
+% \end{codeblock}
+%
+% \noindent
+% then instead you will get:
+%
+% \DeclareLyricChar{\dag}
+% \example|\[Fmaj7]s\dag range|\produces{\[Fmaj7]s\dag range}
+% \eat\]
+%
+% \noindent
+% \DescMacro{DeclareNonLyric}
+% Likewise, you can type
+%
+% \begin{codeblock}
+% |\DeclareNonLyric{|\Meta{token}|}|
+% \end{codeblock}
+%
+% \noindent
+% to reverse the above effect and force a token to be lyric-ending.
+% Such tokens are pushed out away from long chord names so that they
+% never fall under a chord, and hyphenation is added to the resulting gap.
+%
+% \DescMacro{DeclareNoHyphen}
+% To declare a token to be lyric-ending but without the added hyphenation,
+% use |\DeclareNoHyphen{|\Meta{token}|}| instead.
+% Such tokens are pushed out away from long chord names so that they never
+% fall under the chord, but hyphenation is not added to the resulting gap.
+%
+% \paragraph{Extending Chords Over Adjacent Words.}
+% \DescMacro{MultiwordChords}
+% The |\MultiwordChords| macro forces multiple words to be squeezed under one
+% chord by default.
+% Normally a long chord atop a short lyric pushes subsequent
+% lyrics away to make room for the chord:
+%
+% \example|\[Gmaj7sus4]my life|\produces{\[Gmaj7sus4]my life}
+% \eat\]
+%
+% \noindent
+% But if you first type |\MultiwordChords|, then instead you get the more
+% compact:
+%
+% \begingroup\MultiwordChords
+% \example|\[Gmaj7sus4]my life|\produces{\[Gmaj7sus4]my life}
+% \eat\]
+% \endgroup
+%
+% \noindent
+% Authors should exercise caution when using |\MultiwordChords| because
+% including many words under a single chord can often produce output that
+% is ambiguous or misleading to musicians.
+% For example,
+%
+% \begingroup\MultiwordChords
+% \example|\[F G Am]me free|\produces{\[F G Am]me free}\par
+% \eat\]
+% \endgroup
+%
+% \noindent
+% This might be misleading to musicians if all three chords are intended
+% to be played while singing the word ``me.''
+% Liberal use of braces is therefore required to make |\MultiwordChords|
+% produce good results, which is why it isn't the default.
+%
+% \paragraph{Accidentals Outside Chords.}
+% \DescMacro{shrp}
+% \DescMacro{flt}
+% Sharp and flat symbols can be produced with |#| and |&| when they appear
+% in chord macros, but if you wish to produce those symbols in
+% other parts of the document, you must use the |\shrp| and |\flt| macros.
+% For example, to define a macro that produces a \chord{C\shrp} chord, use:
+%
+% \begin{codeblock}
+% |\newcommand{\Csharp}{C\shrp}|
+% \end{codeblock}
+%
+% \subsection{Replaying Chords and Choruses}\label{sec:replay}
+%
+% \DescChar{hat}{^}
+% Many songs consist of multiple verses that use the same chords.
+% The \Songs{} package simplifies this common case by providing a means to
+% replay the chord sequence of a previous verse without having to retype
+% all the chords.
+% To replay a chord from a previous verse, type a hat symbol (|^|) anywhere
+% you would otherwise use a chord macro (|\[]|\eat\]).
+% For example,
+%
+% \begin{codeblock}
+% \mac{beginverse}
+% |\[G]This is the \[C]first \[G]verse.|\eat\]
+% \mac{endverse}
+% \mac{beginverse}
+% |The ^second verse ^ has the same ^chords.|
+% \mac{endverse}
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{chorded}\memorize
+% \[G]This is the \[C]first \[G]verse.\eat\]
+% \end{chorded}
+% \begin{chorded}
+% The ^second verse ^ has the same ^chords.
+% \end{chorded}
+%
+% Normal chords can appear amidst replayed chords without disrupting the
+% sequence of chords being replayed.
+% Thus, a third verse could say,
+%
+% \begin{codeblock}
+% \mac{beginverse}
+% |The ^third verse ^has a \[Cm]new ^chord.|\eat\]
+% \mac{endverse}
+% \end{codeblock}
+%
+% \noindent to produce
+%
+% \begin{chorded}
+% The ^third verse ^has a \[Cm]new ^chord.\eat\]
+% \end{chorded}
+%
+% Replaying can be used in combination with automatic transposition to produce
+% modulated verses.
+% See \S\ref{sec:transpose} for an example.
+%
+% \DescMacro{memorize}
+% By default, chords are replayed from the current song's first verse, but
+% you can replay the chords of a different verse or chorus by saying
+% |\memorize| at the beginning of any verse or chorus whose chords you want
+% to later replay.
+% Subsequent verses or choruses that use \refchar{hat} replay chords
+% from the most recently memorized verse or chorus.
+%
+% \paragraph{Selective Memorization.}
+% It is also possible to inject unmemorized chords into a memorized verse
+% so that they are not later replayed.
+% To suppress memorization of a chord, begin the chord's name with a hat
+% symbol.
+% For example,
+%
+% \begin{codeblock}
+% \mac{beginverse}\mac{memorize}
+% |The \[G]third \[C]chord will \[^Cm]not be re\[G]played.|\eat\]
+% \mac{endverse}
+% \mac{beginverse}
+% |When ^replaying, the ^unmemorized chord is ^skipped.|
+% \mac{endverse}
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{chorded}\memorize
+% The \[G]third \[C]chord will \[^Cm]not be re\[G]played.\eat\]
+% \vskip5pt%
+% When ^replaying, the ^unmemorized chord is ^skipped.
+% \end{chorded}
+%
+% \noindent
+% This is useful when the first verse of a song has something unique,
+% like an intro that won't be repeated in subsequent verses, but has
+% other chords that you wish to replay.
+%
+% \paragraph{Memorizing Multiple Chord Sequences.}
+% By default, the \Songs{} package only memorizes one sequence of chords
+% at a time and \refchar{hat} replays chords from that most recently
+% memorized sequence.
+% However, you can memorize and replay multiple independent sequences
+% using the macros described in the following paragraphs.
+%
+% \DescMacro{newchords}
+% Memorized or replayed chord sequences are stored in chord-replay registers.
+% To declare a new chord-replay register, type
+%
+% \begin{codeblock}
+% |\newchords{|\Meta{regname}|}|
+% \end{codeblock}
+%
+% \noindent
+% where \Meta{regname} is any unique alphabetic name.
+%
+% Once you've declared a register, you can memorize into that register
+% by providing the \Meta{regname} as an optional argument to
+% \mac{memorize}:
+%
+% \begin{codeblock}
+% \mac{memorize}|[|\Meta{regname}|]|
+% \end{codeblock}
+%
+% \noindent
+% Memorizing into a non-empty register replaces the contents of that
+% register with the new chord sequence.
+%
+% \DescMacro{replay}
+% To replay chords from a particular register, type
+%
+% \begin{codeblock}
+% |\replay[|\Meta{regname}|]|
+% \end{codeblock}
+%
+% \noindent
+% Subsequent uses of \refchar{hat} reproduce chords from the sequence
+% stored in register \Meta{regname}.
+%
+% Register contents are global, so you can memorize a chord sequence from one
+% song and replay it in others.
+% You can also use |\replay| multiple times in the same verse or chorus to
+% replay a sequence more than once.
+%
+% \paragraph{Replaying Choruses.}
+% \DescMacro{repchoruses}
+% When making overhead slides, it is often convenient to repeat the song's
+% chorus after the first verse on each page, so that the projector-operator
+% need not flip back to the first slide each time the chorus is to be sung.
+% You can say |\repchoruses| to automate this process.
+% This causes the first chorus in each subsequent song to be automatically
+% repeated after the first verse on each subsequent page of the song (unless
+% that verse is already immediately followed by a chorus).
+% If the first chorus is part of a set of two or more consecutive choruses,
+% then the whole set of choruses is repeated.
+% (A set of choruses is assumed to consist of things like pre-choruses that
+% should always be repeated along with the chorus.)
+% Choruses are not automatically inserted immediately after unnumbered
+% verses (i.e., verses that begin with \mac{beginverse}|*|).
+% Unnumbered verses are assumed to be bridges or endings that aren't
+% followed by a chorus.
+%
+% \DescMacro{norepchoruses}
+% Writing |\norepchoruses| turns off chorus repetition for subsequent songs.
+%
+% If you need finer control over where replayed choruses appear, use the
+% conditional macros covered in \S\ref{sec:conditionals} instead of
+% |\repchoruses|.
+% For example, to manually insert a chorus into only slide books at a
+% particular point (without affecting other versions of your book),
+% you could write:
+%
+% \begin{codeblock}
+% \mac{ifslides}
+% \mac{beginchorus}
+% $\vdots$
+% \mac{endchorus}
+% |\fi|
+% \end{codeblock}
+%
+% \noindent
+% and copy and paste the desired chorus into the middle.
+%
+% \subsection{Line and Column Breaks}
+%
+% \paragraph{Line Breaking.}
+% \DescMacro{brk}
+% To cause a long line of lyrics to be broken in a particular place, put the
+% |\brk| macro at that point in the line.
+% This does not affect lines short enough to fit without breaking.
+% For example,
+%
+% \begin{codeblock}
+% |\beginverse|
+% {\tt\frenchspacing This is a |\brk| short line.
+% But this is a particularly long line of lyrics |\brk| that will need to be wrapped.
+% } |\endverse|
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{lyrics}
+% This is a \brk short line.
+% But this is a particularly long line of lyrics \brk that will need to be wrapped.
+% \end{lyrics}
+%
+% \paragraph{Column Breaks Within Songs.}
+% To suggest a column break within a verse or chorus too long to fit in a
+% single column, use |\brk| on a line by itself.
+% If there are no |\brk| lines in a long verse, it is broken
+% somewhere that a line does not wrap.
+% (A wrapped line is never divided by a column break.)
+% If there are no |\brk| lines in a long chorus, it overflows the column,
+% yielding an overfull vbox warning.
+%
+% \paragraph{Column Breaks Between Songs.}
+% \DescMacro{nextcol}
+% \DescMacro{sclearpage}
+% \DescMacro{scleardpage}
+% To force a column break between songs, use |\nextcol|, |\brk|, |\sclearpage|,
+% or |\scleardpage| between songs.
+% The |\nextcol| macro ends the column by leaving blank space at the bottom.
+% The |\brk| macro ends the current column in lyric books by stretching
+% the preceeding text so that the column ends flush with the bottom
+% of the page.
+% (In non-lyric books |\brk| is identical to |\nextcol|.)
+% The |\sclearpage| macro is like |\nextcol| except that it shifts to the next
+% blank page if the current page is nonempty.
+% The |\scleardpage| macro is like |\sclearpage| except that it shifts to the
+% next blank even-numbered page in two-sided documents.
+% Column breaks usually need to be in different places in different book types.
+% To achieve this, use a conditional block from \S\ref{sec:conditionals}.
+% For example,
+%
+% \begin{codeblock}
+% \mac{ifchorded}|\else|\mac{ifslides}|\else\brk\fi\fi|
+% \end{codeblock}
+%
+% \noindent
+% forces a column break only in lyric books but does not affect chord books
+% or books of overhead slides.
+%
+% When a partial list of songs is being extracted with \mac{includeonlysongs},
+% |\brk|, |\nextcol|, |\clearpage|, and |\cleardpage| macros between songs
+% must be followed by a star to have any effect.
+% To force a column-break at a specific point in a partial book, add the
+% word |nextcol|, |brk|, |clearpage|, or |cleardpage| at the corresponding
+% point in the argument to \mac{includeonlysongs}.
+%
+% \subsection{Echoes and Repeats}
+%
+% \paragraph{Echo Parts.}
+% \DescMacro{echo}
+% To typeset an echo part, use |\echo{|\Meta{lyrics and chords}|}|.
+% Echo parts are parenthesized and italicized.
+% For example,
+%
+% \example|Alle\[G]luia! \echo{Alle\[A]luia!}|\produces{Alle\[G]luia! \echo{Alle\[A]luia!}}
+% \eat\]
+%
+% \paragraph{Repeated Lines.}
+% \DescMacro{rep}
+% To indicate that a line should be sung multiple times by all singers, put
+% |\rep{|\Meta{n}|}| at the end of the line.
+% For example,
+%
+% \example|Alleluia! \rep{4}|\produces{Alleluia! \rep{4}}
+%
+% \DescMacro{lrep}
+% \DescMacro{rrep}
+% To indicate exactly where repeated parts begin and end, use |\lrep| and
+% |\rrep| to create begin- and end-repeat signs.
+% For example,
+%
+% \example|\lrep \[G]Alleluia!\rrep \rep{4}|\produces{\lrep \[G]Alleluia!\rrep \rep{4}}
+% \eat\]
+%
+% \subsection{Measure Bars}\label{sec:measures}
+%
+% \DescMacro{measurebar}
+% \DescChar{pipe}{|}
+% Measure bars can be added to chord books in order to help musicians
+% keep time when playing unfamiliar songs.
+% To insert a measure bar, type either |\measurebar| or type the
+% vertical pipe symbol (``\verb@|@'').
+% For example,
+%
+% \example\verb@Alle|\[G]luia@\produces{Alle\meter{}{}\measurebar\[G]luia}
+% \eat\]
+%
+% \noindent
+% In order for measure bars to be displayed, the \env{showmeasures}
+% option must be enabled.
+% Measure bars are only displayed by default in chord books.
+%
+% \DescMacro{meter}
+% The first measure bar in a song has meter numbers placed above
+% it to indicate the time signature of the piece.
+% By default, these numbers are 4/4, denoting four quarter notes
+% per measure.
+% To change the default, type |\meter{|\Meta{n}|}{|\Meta{d}|}|
+% somewhere after the \mac{beginsong} line of the song but before the
+% first measure bar, to declare a time signature of \Meta{n} \Meta{d}th
+% notes per measure.
+%
+% \DescMacro{mbar}
+% You can also change meters mid-song either by using |\meter| in the
+% middle of the song or by typing |\mbar{|\Meta{n}|}{|\Meta{d}|}|
+% to produce a measure bar with a time signature of \Meta{n}/\Meta{d}.
+% For example,
+%
+% \begin{codeblock}
+% |\meter{6}{8}|
+% |\beginverse|
+% \verb@|Sing to the |heavens, ye \mbar{4}{4}saints of |old!@
+% |\endverse|
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{chorded}
+% \meter{6}{8}%
+% \measurebar Sing to the \measurebar heavens, ye \mbar{4}{4}saints of \measurebar old!
+% \end{chorded}
+%
+% \subsection{Textual Notes}\label{sec:notes}
+%
+% \DescMacro{textnote}
+% \DescMacro{musicnote}
+% Aside from verses and choruses, songs can also contain textual notes
+% that provide instructions to singers and musicians.
+% To create a textual note that is displayed in both lyric books
+% and chord books, use:
+%
+% \begin{codeblock}
+% |\textnote{|\Meta{text}|}|
+% \end{codeblock}
+%
+% \noindent
+% To create a textual note that is displayed only in chord books, use:
+%
+% \begin{codeblock}
+% |\musicnote{|\Meta{text}|}|
+% \end{codeblock}
+%
+% \noindent
+% Both of these create a shaded box containing \Meta{text}.
+% For example,
+%
+% \begin{codeblock}
+% |\textnote{Sing as a two-part round.}|
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{lyrics}
+% \textnote{Sing as a two-part round.}
+% \end{lyrics}
+%
+% \noindent
+% Textual notes can be placed anywhere within a song, either within
+% verses and choruses or between them.
+%
+% \paragraph{Guitar Capos.}
+% \DescMacro{capo}
+% One special kind of textual note suggests to guitarists a fret on which
+% they should put their capos.
+% Macro |\capo{|\Meta{n}|}| should be used for this purpose.
+% It normally has the same effect as \mac{musicnote}|{capo |\Meta{n}|}|;
+% however, if the \env{transposecapos} option is active then it
+% instead has the effect of \mac{transpose}|{|\Meta{n}|}|.
+% See \S\ref{sec:transpose} for more information on automatic chord
+% transposition.
+%
+% \subsection{Chords in Ligatures}
+%
+% This subsection covers an advanced topic and can probably be
+% skipped by those creating song books for non-professional use.
+%
+% The \mac{[\eat]} macro is the normal means by which chords should be inserted
+% into a song; however, a special case occurs when a chord falls within a
+% ligature.
+% Ligatures are combinations of letters or symbols that \TeX{} normally
+% typesets as a single font character so as to produce cleaner-looking
+% output.
+% The only ligatures in English are: ff, fi, fl, ffi, and ffl.
+% Other languages have additional ligatures like \ae{} and \oe.
+% Notice that in each of these cases, the letters are ``squished''
+% together to form a single composite symbol.
+%
+% \DescMacro{ch}
+% When a chord macro falls inside a ligature, \LaTeX{} fails to compact
+% the ligature into a single font character even in non-chorded versions of
+% the book.
+% To avoid this minor typographical error, use the |\ch| macro to typeset
+% the chord:
+%
+% \begin{codeblock}
+% |\ch{|\Meta{chord}|}{|\Meta{pre}|}{|\Meta{post}|}{|\Meta{full}|}|
+% \end{codeblock}
+%
+% \noindent
+% where \Meta{chord} is the chord text, \Meta{pre} is the text to
+% appear before the hyphen if the ligature is broken by auto-hyphenation,
+% \Meta{post} is the text to appear after the hyphen if the ligature
+% is broken by auto-hyphenation, and \Meta{full} is the full ligature
+% if it is not broken by hyphenation.
+% For example, to correctly typeset |\[Gsus4]dif\[G]ficult|\eat\],
+% in which the \chord{G} chord falls in the middle of the ``ffi''
+% ligature, one should use:
+%
+% \example|di\ch{G}{f}{fi}{ffi}cult|\produces{di\ch{G}{f}{fi}{ffi}cult}
+%
+% \noindent
+% This causes the ``ffi'' ligature to appear intact yet still correctly
+% places the \chord{G} chord over the second f.
+% To use the |\ch| macro with a replayed chord name (see \S\ref{sec:replay}),
+% use |^| as the \Meta{chord}.
+%
+% \DescMacro{mch}
+% The |\mch| macro is exactly like the \mac{ch} macro except that it
+% also places a measure bar into the ligature along with the chord.
+% For example,
+%
+% \example|di\mch{G}{f}{fi}{ffi}cult|\produces{di\mch{G}{f}{fi}{ffi}cult}
+%
+% \noindent
+% places both a measure bar and a \chord{G} chord after the first ``f''
+% in ``difficult'', yet correctly produces an unbroken ``ffi'' ligature
+% in copies of the book in which measure bars are not displayed.
+%
+% In the unusual case that a meter change is required within a
+% ligature, this can be achieved with a construction like:
+%
+% \example|\meter{6}{8}di\mch{G}{f}{fi}{ffi}cult|\produces{\meter{6}{8}di\mch{G}{f}{fi}{ffi}cult}
+%
+% \noindent
+% The \mac{meter} macro sets the new time signature, which appears
+% above the next measure bar---in this case the measure bar
+% produced by the |\mch| macro.
+%
+% Chords and measure bars produced with \refchar{hat} or
+% \refchar{pipe} are safe to use in ligatures.
+% Thus, |dif|\refchar{pipe}\refchar{hat}|ficult| requires
+% no special treatment; it leaves the ``ffi'' ligature intact when measure
+% bars are not being displayed.
+%
+% \section{Guitar Tablatures}\label{sec:tablatures}
+%
+% \DescMacro{gtab}
+% Guitar tablature diagrams can be created by using the construct
+%
+% \begin{codeblock}
+% |\gtab{|\Meta{chord}|}{|\Meta{fret}|:|\Meta{strings}|:|\Meta{fingering}|}|
+% \end{codeblock}
+%
+% \noindent
+% where the \Meta{fret} and \Meta{fingering} parts are both optional
+% (and you may omit any colon that borders an omitted argument).
+%
+% \Meta{chord} is a chord name to be placed above the diagram.
+%
+% \Meta{fret} is an optional digit from 2 to 9 placed to the
+% left of the diagram.
+%
+% \Meta{strings} should be a series of symbols, one for each string
+% of the guitar from lowest pitch to highest.
+% Each symbol should be one of:
+% |X| if that string is not to be played,
+% |0| (zero or the letter O) if that string is to be played open, or
+% one of |1| through |9| if that string is to be played on the given
+% numbered fret.
+%
+% \Meta{fingering} is an optional series of digits, one for each
+% string of the guitar from lowest pitch to highest.
+% Each digit should be one of:
+% |0| if no fingering information is to be displayed for that string (e.g., if
+% the string is not being played or is being played open), or
+% one of |1| through |4| to indicate that the given numbered finger is to be
+% used to hold down that string.
+%
+% Here are some examples to illustrate:
+%
+% \example|\gtab{A}{X02220:001230}|\produces{\vcenterbox{\gtab{A}{{\hphantom{4}}:X02220:001230}}}
+% \example|\gtab{C#sus4}{4:XX3341}|\produces{\vcenterbox{\gtab{C\shrp sus4}{4:XX3341}}}
+% \example|\gtab{B&}{X13331}|\produces{\vcenterbox{\gtab{B\flt}{{\hphantom{4}}:X13331:}}}
+%
+% To create a barre chord in which one finger is extended across multiple
+% strings, use parentheses |()| or brackets |[]| in the \Meta{strings}
+% argument to group the barred strings.
+% Each such group will draw a barre on the lowest numbered fret it contains.
+% For example:
+%
+% \example|\gtab{C7}{X(3535X):013140}|\produces{\vcenterbox{\gtab{C7}{{\hphantom{4}}:X(3535X):013140}}}
+%
+% \DescMacro{minfrets}
+% By default, tablature diagrams always consist of at least 4 fret rows
+% (more if the \Meta{strings} argument contains a number larger than 4).
+% To change the minimum number of fret rows, change the value of |\minfrets|.
+% For example, typing
+%
+% \begin{codeblock}
+% |\minfrets=1|
+% \end{codeblock}
+%
+% \noindent
+% causes tablature diagrams to have only as many rows are required to
+% accommodate the largest digit appearing in the \Meta{strings} argument.
+%
+% \paragraph{Tablatures Within Macros}
+% Macros that produce tablatures must not bury the colons that separate the
+% \Meta{fret}, \Meta{strings}, and \Meta{fingering} arguments within other
+% macros, and it's safest to always include both colons to avoid ambiguities
+% related to optional argument parsing.
+% For example,
+%
+% \begin{codeblock}
+% |\newcommand{\mystrings}{X4412X}|
+% |\newcommand{\myfingers}{X3412X}|
+% |\newcommand{\mychord}{|\mac{gtab}|{C|\mac{shrp}|}{:\mystrings:\myfingers}}|
+% \end{codeblock}
+%
+% \noindent
+% works as expected.
+% But omitting the colon before |\mystrings| in the definition of |\mychord|
+% confuses \mac{gtab} into thinking |\mystrings| is the \Meta{fret}
+% argument, and writing code like |\gtab{C\shrp}{\allargs}| with |\allargs|
+% defined to something with colons results in an error, because it confuses
+% \mac{gtab} into thinking that |\allargs| is only the \Meta{strings} argument.
+%
+% \section{Automatic Transposition}\label{sec:transpose}
+%
+% \DescMacro{transpose}
+% You can automatically transpose some or all of the chords in a song up by
+% \Meta{n} half-steps by adding the line
+%
+% \begin{codeblock}
+% |\transpose{|\Meta{n}|}|
+% \end{codeblock}
+%
+% \noindent
+% somewhere between the song's \mac{beginsong} line and the first chord to
+% be transposed.
+% For example, if a song's first chord is |\[D]|\eat\], and the line
+% |\transpose{2}| appears before it, then the chord appears as an
+% \chord{E} in the resulting document.
+% Specifying a negative number for \Meta{n} transposes subsequent chords
+% down instead of up.
+%
+% The |\transpose| macro affects all chords appearing after it until the
+% \mac{endsong} line.
+% If two |\transpose| macros appear in the same song, their effects are
+% cumulative.
+%
+% When the \env{transposecapos} option is active, the \mac{capo}
+% macro acts like |\transpose|.
+% See \S\ref{sec:notes} for more information.
+%
+% \paragraph{Enharmonics.}
+% \DescMacro{preferflats}
+% \DescMacro{prefersharps}
+% When using \mac{transpose} to automatically transpose the chords of a song,
+% the \Songs{} package code chooses between enharmonically equivalent
+% names for ``black key'' notes based on the first chord of the song.
+% For example, if |\transpose{1}| is used, and if the first chord of the
+% song is an \chord{E}, then all \chord{A} chords that appear in
+% the song are transcribed as \chord{B\flt} chords rather than
+% \chord{A\shrp} chords, since the key of \chord{F}-major (\chord{E}
+% transposed up by one half-step) has a flatted key signature.
+% Usually this guess produces correct results, but if not, you can use
+% either |\preferflats| or |\prefersharps| after the \mac{transpose} line
+% to force all transcription to use flatted names or sharped names
+% respectively, when resolving enharmonic equivalents.
+%
+% \paragraph{Modulated Verses.}
+% Automatic transposition can be used in conjunction with chord-replaying
+% (see \S\ref{sec:chords}) to produce modulated verses.
+% For example,
+%
+% \begin{codeblock}
+% \mac{beginverse}\mac{memorize}
+% |\[F#]This is a \[B/F#]memorized \[F#]verse. \[E&7]|\eat\]
+% \mac{endverse}
+% \mac{transpose}|{2}|
+% \mac{beginverse}
+% |^This verse is ^modulated up two ^half-steps.|
+% \mac{endverse}
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{chorded}\memorize
+% \[F#]This is a \[B/F#]memorized \[F#]verse. \[E&7]\eat\]
+% \vskip5pt\replay\transpose{2}%
+% ^This verse is ^modulated up two ^half-steps.
+% \transpose{-2}%
+% \end{chorded}
+%
+% \paragraph{Both Keys.}
+% \DescMacro{trchordformat}
+% By default, when chords are automatically transposed using \mac{transpose},
+% only the transposed chords are printed.
+% However, in some cases you may wish to print the old chords and the
+% transposed chords together so that musicians playing transposing and
+% non-transposing instruments can play from the same piece of music.
+% This can be achieved by redefining the |\trchordformat| macro, which
+% receives two arguments---the original chord name and the transposed chord
+% name, respectively.
+% For example, to print the old chord above the new chord above each lyric,
+% define
+%
+% \begin{codeblock}
+% |\renewcommand{\trchordformat}[2]{\vbox{\hbox{#1}\hbox{#2}}}|
+% \end{codeblock}
+%
+% \paragraph{Changing Note Names.}
+% \DescMacro{solfedge}
+% \DescMacro{alphascale}
+% In many countries it is common to use the solfedge names for the notes of
+% the scale (\chord{LA, SI, DO, RE, MI, FA, SOL\/}) instead of the
+% alphabetic names (\chord{A, B, C, D, E, F, G\/}).
+% By default, the transposition logic only understands alphabetic names, but
+% you can tell it to look for solfedge names by typing |\solfedge|.
+% To return to alphabetic names, type |\alphascale|.
+%
+% \DescMacro{notenames}
+% You can use other note names as well.
+% To define your own note names, type
+%
+% \begin{codeblock}
+% |\notenames{|\Meta{nameA}|}{|\Meta{nameB}|}|$\ldots$|{|\Meta{nameG}|}|
+% \end{codeblock}
+%
+% \noindent
+% where each of \Meta{nameA} through \Meta{nameG} must consist entirely of
+% a sequence of one or more \emph{uppercase} letters.
+% For example, some solfedge musicians use \chord{TI} instead of \chord{SI}
+% for the second note of the scale.
+% To automatically transpose such music, use:
+%
+% \begin{codeblock}
+% |\notenames{LA}{TI}{DO}{RE}{MI}{FA}{SOL}|
+% \end{codeblock}
+%
+% \DescMacro{notenamesin}
+% \DescMacro{notenamesout}
+% The \Songs{} package can also automatically convert one set of note names
+% to another.
+% For example, suppose you have a large song book in which chords have been
+% typed using alphabetic note names, but you wish to produce a book that
+% uses the equivalent solfedge names.
+% You could achieve this by using the |\notenamesin| macro to tell the
+% \Songs{} package which note names you typed in the input file, and then
+% using |\notenamesout| to tell the \Songs{} package how you want it to
+% typeset each note name in the output file.
+% The final code looks like this:
+%
+% \begin{codeblock}
+% |\notenamesin{A}{B}{C}{D}{E}{F}{G}|
+% |\notenamesout{LA}{SI}{DO}{RE}{MI}{FA}{SOL}|
+% \end{codeblock}
+%
+% \noindent
+% The syntaxes of |\notenamesin| and |\notenamesout| are identical to that
+% of \mac{notenames} (see above), except that the arguments of |\notenamesout|
+% can consist of any \LaTeX{} code that is legal in horizontal mode, not just
+% uppercase letters.
+%
+% To stop converting between note names, use \mac{alphascale}, \mac{solfedge},
+% or \mac{notenames} to reset all note names back to identical input and
+% output scales.
+%
+% \paragraph{Transposing Chords In Macros.}
+% \DescMacro{transposehere}
+% The automatic transposition logic does not find chord names that are hidden
+% inside macro bodies.
+% For example, if you abbreviate a chord by typing,
+%
+% \begin{codeblock}
+% |\newcommand{\mychord}{F|\mac{shrp}| sus4/C|\mac{shrp}|}|
+% \mac{transpose}|{4}|
+% |\[\mychord]|\eat\]
+% \end{codeblock}
+%
+% \noindent
+% then the \mac{transpose} macro fails to transpose it; the
+% resulting chord is still an \chord{F\shrp sus4/C\shrp} chord.
+% To fix the problem, you can use |\transposehere| in your macros to
+% explicitly invoke the transposition logic on chord names embedded in
+% macro bodies.
+% The above example could be corrected by instead defining:
+%
+% \begin{codeblock}
+% |\newcommand{\mychord}{\transposehere{F|\mac{shrp}| sus4/C|\mac{shrp}|}}|
+% \end{codeblock}
+%
+% \DescMacro{notrans}
+% Transposition can be suppressed within material that would otherwise be
+% transposed by using the |\notrans| macro.
+% For example, writing
+%
+% \begin{codeblock}
+% \mac{transposehere}|{G = \notrans{G}}|
+% \end{codeblock}
+%
+% \noindent
+% would typeset a transposed \chord{G} followed by a non-transposed
+% \chord{G} chord.
+% This does not suppress note name conversion (see \mac{notenames}).
+% To suppress both transposition and note name conversion, just use
+% braces (e.g., |{G}| instead of |\notrans{G}|).
+%
+% \paragraph{Transposing Guitar Tablatures.}
+% \DescMacro{gtabtrans}
+% The songs package cannot automatically transpose tablature diagrams
+% (see \S\ref{sec:tablatures}).
+% Therefore, when automatic transposition is taking place, only the chord
+% names of \mac{gtab} macros are displayed (and transposed); the diagrams
+% are omitted.
+% To change this default, redefine the |\gtabtrans| macro, whose two
+% arguments are the two arguments to \mac{gtab}.
+% For example, to display original tablatures without transposing them even
+% when transposition has been turned on, write
+%
+% \begin{codeblock}
+% |\renewcommand{\gtabtrans}[2]{|\mac{gtab}|{|\mac{notrans}|{#1}}{#2}}|
+% \end{codeblock}
+%
+% \noindent
+% To transpose the chord name but not the diagram under it, replace
+% \mac{notrans}|{#1}| with simply |#1| in the above.
+% To restore the default behavior, write
+%
+% \begin{codeblock}
+% |\renewcommand{\gtabtrans}[2]{|\mac{transposehere}|{#1}}|
+% \end{codeblock}
+%
+% \section{Between Songs}\label{sec:between}
+%
+% Never put any material directly into the top level of a \env{songs}
+% environment.
+% Doing so will disrupt the page-builder, usually producing strange page
+% breaks and blank pages.
+% To safely put material between songs, use one of the environments
+% described in this section.
+%
+% \subsection{Intersong Displays}\label{sec:intersong}
+%
+% \DescEnv{intersong}
+% To put column-width material between the songs in a \env{songs} environment,
+% use an |intersong| environment:
+%
+% \begin{codeblock}
+% |\begin{intersong}|
+% $\vdots$
+% |\end{intersong}|
+% \end{codeblock}
+%
+% \noindent
+% Material contributed in an |intersong| environment is subject to the same
+% column-breaking rules as songs (see \S\ref{sec:layout}), but all other
+% formatting is up to you.
+% By default, \LaTeX{} inserts interline glue below the last line of an
+% |intersong| environment.
+% To suppress this, end the |intersong| content with |\par\nointerlineskip|.
+%
+% \DescEnv{intersong*}
+% To instead put page-width material above a song, use an |intersong*|
+% environment:
+%
+% \begin{codeblock}
+% |\begin{intersong*}|
+% $\vdots$
+% |\end{intersong*}|
+% \end{codeblock}
+%
+% \noindent
+% This starts a new page if the current page already has column-width
+% material in it.
+%
+% \DescEnv{songgroup}
+% By default, all intersong displays are omitted when generating a partial
+% book with \mac{includeonlysongs}.
+% You can force them to be included whenever a particular song is included
+% by using a |songgroup| environment:
+%
+% \begin{codeblock}
+% |\begin{songgroup}|
+% $\vdots$
+% |\end{songgroup}|
+% \end{codeblock}
+%
+% \noindent
+% Each |songgroup| environment may include any number of \env{intersong},
+% \env{intersong*}, or scripture quotations (see \S\ref{sec:scripture}),
+% but must include exactly one song.
+% When using \mac{includeonlysongs}, the entire group is included in the
+% book if the enclosed song is included; otherwise the entire group is
+% omitted.
+%
+% \subsection{Scripture Quotations}\label{sec:scripture}
+%
+% \paragraph{Starting a Scripture Quotation.}
+% \DescMacro{beginscripture}
+% \DescMacro{endscripture}
+% A special form of intersong block typesets a scripture quotation.
+% Scripture quotations begin and end with
+%
+% \begin{codeblock}
+% |\beginscripture{|\Meta{ref}|}|
+% $\vdots$
+% |\endscripture|
+% \end{codeblock}
+%
+% \noindent
+% where \Meta{ref} is a scripture reference that is
+% typeset at the end of the quotation.
+% The \Meta{ref} argument should conform to the same syntax
+% rules as for the \Meta{ref} arguments passed to \mac{beginsong}
+% macros (see \S\ref{sec:songs}).
+%
+% The text of the scripture quotation between the |\beginscripture| and
+% |\endscripture| lines are parsed in normal paragraph mode.
+% For example:
+%
+% \begin{codeblock}
+% |\beginscripture{James 5:13}|
+% {\tt\frenchspacing%
+% Is any one of you in trouble? He should pray. Is anyone happy? Let him sing songs of praise.
+% } |\endscripture|
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{sample}
+% \beginscripture{James 5:13}
+% Is any one of you in trouble? He should pray. Is anyone happy? Let him sing songs of praise.
+% \endscripture
+% \end{sample}
+%
+% \paragraph{Tuplets.}
+% \DescMacro{Acolon}
+% \DescMacro{Bcolon}
+% To typeset biblical poetry the way it appears in most bibles, begin each
+% line with either |\Acolon| or |\Bcolon|.
+% A-colons are typeset flush with the left margin, while B-colons are
+% indented.
+% Any lines too long to fit are wrapped with double-width hanging indentation.
+% For example,
+%
+% \begin{codeblock}
+% |\beginscripture{Psalm 1:1}|
+% {\tt\frenchspacing%
+% |\Acolon| Blessed is the man
+% |\Bcolon| who does not walk in the counsel of the wicked
+% |\Acolon| or stand in the way of sinners
+% |\Bcolon| or sit in the seat of mockers.
+% } |\endscripture|
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{sample}
+% \beginscripture{Psalm 1:1}
+% \Acolon Blessed is the man
+% \Bcolon who does not walk in the counsel of the wicked
+% \Acolon or stand in the way of sinners
+% \Bcolon or sit in the seat of mockers.
+% \endscripture
+% \end{sample}
+%
+% \paragraph{Stanzas.}
+% \DescMacro{strophe}
+% Biblical poetry is often grouped into stanzas or ``strophes'',
+% each of which is separated from the next by a small vertical
+% space.
+% You can create that vertical space by typing |\strophe|.
+% For example,
+%
+% \begin{codeblock}
+% |\beginscripture{Psalm 88:2-3}|
+% {\tt\frenchspacing%
+% |\Acolon| May my prayer come before you;
+% |\Bcolon| turn your ear to my cry.
+% |\strophe|
+% |\Acolon| For my soul is full of trouble
+% |\Bcolon| and my life draws near the grave.
+% } |\endscripture|
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{sample}
+% \beginscripture{Psalm 88:2-3}
+% \Acolon May my prayer come before you;\par
+% \Bcolon turn your ear to my cry.\par
+% \strophe
+% \Acolon For my soul is full of trouble\par
+% \Bcolon and my life draws near the grave.
+% \endscripture
+% \end{sample}
+%
+% \paragraph{Indented Blocks.}
+% \DescMacro{scripindent}
+% \DescMacro{scripoutdent}
+% Some bible passages, such as those that mix prose and poetry, contain
+% indented blocks of text.
+% You can increase the indentation level within a scripture quotation
+% by using |\scripindent| and decrease it by using |\scripoutdent|.
+% For example,
+%
+% \begin{codeblock}
+% |\beginscripture{Hebrews 10:17-18}|
+% {\tt\frenchspacing%
+% Then he adds:
+% |\scripindent|
+% |\Acolon ``|Their sins and lawless acts
+% |\Bcolon| I will remember no more.|''|
+% |\scripoutdent|
+% And where these have been forgiven, there is no longer any sacrifice for sin.
+% } |\endscripture|
+% \end{codeblock}
+%
+% \noindent produces
+%
+% \begin{sample}
+% \beginscripture{Hebrews 10:17-18}
+% Then he adds:\par
+% \scripindent
+% \Acolon ``Their sins and lawless acts\par
+% \Bcolon I will remember no more.''\par
+% \scripoutdent
+% And where these have been forgiven, there is no longer any sacrifice for sin.
+% \endscripture
+% \end{sample}
+%
+% \section{Chapters and Sections}\label{sec:sectioning}
+%
+% \DescMacro{songsection}
+% \DescMacro{songchapter}
+% Song books can be divided into chapters and sections using all the usual
+% macros provided by \LaTeX{} (e.g., |\chapter|, |\section|, etc.) and by
+% other macro packages.
+% In addition, the \Songs{} package provides two helpful built-in sectioning
+% macros:
+%
+% \begin{codeblock}
+% |\songchapter{|\Meta{title}|}|
+% |\songsection{|\Meta{title}|}|
+% \end{codeblock}
+%
+% \noindent
+% which act like \LaTeX's |\chapter| and |\section| commands except that they
+% center the \Meta{title} text in sans serif font and omit the chapter/section
+% number.
+% The |\songchapter| macro only works in document classes that support
+% |\chapter| (e.g., the |book| class).
+%
+% \section{Indexes}
+%
+% \subsection{Index Creation}\label{sec:indexes}
+%
+% \DescMacro{newindex}
+% \DescMacro{newauthorindex}
+% \DescMacro{newscripindex}
+% The \Songs{} package supports three kinds of indexes: indexes by title and/or
+% notable lyrics, indexes by author, and indexes by scripture reference.
+% To generate an index, first declare the index in the document preamble
+% (i.e., before the |\begin{document}| line) with one of the following:
+%
+% \begin{codeblock}
+% |\newindex{|\Meta{id}|}{|\Meta{filename}|}|
+% |\newauthorindex{|\Meta{id}|}{|\Meta{filename}|}|
+% |\newscripindex{|\Meta{id}|}{|\Meta{filename}|}|
+% \end{codeblock}
+%
+% \noindent
+% The \Meta{id} should be an alphabetic identifier that will be used to
+% identify the index in other macros that reference it.
+% The \Meta{filename} should be a string that, when appended with an
+% extension, constitutes a valid filename on the system.
+% Auxiliary files named \Meta{filename}|.sxd| and \Meta{filename}|.sbx|
+% are generated during the automatic index generation process.
+% For example:
+%
+% \begin{codeblock}
+% |\newindex{mainindex}{idxfile}|
+% \end{codeblock}
+%
+% \noindent
+% creates a title index named ``|mainindex|'' whose data is
+% stored in files named |idxfile.sxd| and |idxfile.sbx|.
+%
+% \DescMacro{showindex}
+% To display the index in the document, use:
+%
+% \begin{codeblock}
+% |\showindex[|\Meta{columns}|]{|\Meta{title}|}{|\Meta{id}|}|
+% \end{codeblock}
+%
+% \noindent
+% where \Meta{id} is the same identifier used in the \mac{newindex},
+% \mac{newauthorindex}, or \mac{newscripindex} command, and where
+% the \Meta{title} is the title of the index, which should consist only of
+% simple text (no font or formatting macros, since those cannot be used in
+% pdf bookmark indexes).
+% The |[|\Meta{columns}|]| part is optional; if specified it dictates the
+% number of columns if the index can't fit in a single column.
+% For example, for a 2-column title index, write:
+%
+% \begin{codeblock}
+% |\showindex[2]{Index of Song Titles}{mainindex}|
+% \end{codeblock}
+%
+% \subsection{Index Entries}\label{sec:ientry}
+%
+% Every song automatically gets entries in the current \env{songs}
+% environment's list of title index(es) (see \S\ref{sec:songs}).
+% However, you can also add extra index entries for a song to any index.
+%
+% \paragraph{Indexing Lyrics.}
+% \DescEnv{index=}
+% For example, title indexes often have entries for memorable lines
+% of lyrics in a song in addition to the song's title.
+% You can add an index entry for the current song to the section's
+% title index(es) by adding |index={|\Meta{lyrics}|}| to the song's
+% \mac{beginsong} line.
+% For example,
+%
+% \begin{codeblock}
+% \mac{beginsong}|{Doxology}|
+% | [index={Praise God from Whom all blessings flow}]|
+% \end{codeblock}
+%
+% \noindent
+% causes the song to be indexed both as ``\textit{Doxology}'' and as
+% ``Praise God from Whom all blessings flow'' in the section's title index(es).
+% You can use |index=| multiple times in a \mac{beginsong} line to produce
+% multiple additional index entries.
+% Index entries produced with |index={|\Meta{lyrics}|}| are
+% typeset in an upright font instead of in italics to distinguish
+% them from song titles.
+%
+% \paragraph{Indexing Extra Song Titles.}
+% \DescEnv{ititle=}
+% To add a regular index entry typeset in italics to the title
+% index(es), use:
+%
+% \begin{codeblock}
+% |ititle={|\Meta{title}|}|
+% \end{codeblock}
+%
+% \noindent
+% in the \mac{beginsong} line instead.
+% Like \env{index=} keyvals, |ititle=| can be used multiple times to produce
+% multiple additional index entries.
+%
+% \DescMacro{indexentry}
+% \DescMacro{indextitleentry}
+% You can also create index entries by saying
+% |\indexentry[|\Meta{indexes}|]{|\Meta{lyrics}|}| (which creates an
+% entry like \env{index=}) or
+% |\indextitleentry[|\Meta{indexes}|]{|\Meta{title}|}| (which
+% creates an entry like \env{ititle=}).
+% These two macros can be used anywhere between the song's \mac{beginsong}
+% and \mac{endsong} lines, and can be used multiple times to produce
+% multiple entries.
+% If specified, \Meta{indexes} is a comma-separated list of the identifiers
+% of indexes to which the entry should be added.
+% Otherwise the new entry is added to all of the title indexes for the current
+% \env{songs} environment.
+%
+% \subsection{Compiling}\label{sec:compiling}
+%
+% As with a typical \LaTeX{} document, compiling a song book document with
+% indexes requires three steps.
+% First, use \LaTeX{} (|pdflatex| is recommended) to generate auxiliary files
+% from the |.tex| file:
+%
+% \begin{codeblock}
+% |pdflatex mybook.tex|
+% \end{codeblock}
+%
+% Second, use the |songidx.lua| script to generate an index for each index that
+% you declared with \mac{newindex}, \mac{newauthorindex}, or
+% \mac{newscripindex}.
+% The script can be launched using Lua\TeX, using the following syntax:
+%
+% \begin{codeblock}
+% |texlua songidx.lua |\textcolor{black}{[}|-b| \Meta{canon}|.can|\textcolor{black}{]} \Meta{filename}|.sxd| \Meta{filename}|.sbx|
+% \end{codeblock}
+%
+% \noindent
+% where \Meta{filename} is the same \Meta{filename} that was used in the
+% \mac{newindex}, \mac{newauthorindex}, or \mac{newscripindex} macro.
+% If the index was declared with \mac{newscripindex}, then the |-b| option
+% is used to specify which version of the bible you wish to use as a basis
+% for sorting your scripture index.
+% The \Meta{canon} part can be any of the |.can| files provided with
+% the |songidx| distribution.
+% If you are using a Protestant, Catholic, or Greek Orthodox Christian bible
+% with book names in English, then the |bible.can| canon file should work
+% well.
+% For other bibles, you should create your own |.can| file by copying and
+% modifying one of the existing |.can| files.
+%
+% For example, if your song book |.tex| file contains the lines
+%
+% \begin{codeblock}
+% \mac{newindex}|{titleidx}{titlfile}|
+% \mac{newauthorindex}|{authidx}{authfile}|
+% \mac{newscripindex}|{scripidx}{scrpfile}|
+% \end{codeblock}
+%
+% \noindent
+% then to generate indexes sorted according to a Christian English bible,
+% execute:
+%
+% \begin{codeblock}
+% |texlua songidx.lua titlfile.sxd titlfile.sbx|
+% |texlua songidx.lua authfile.sxd authfile.sbx|
+% |texlua songidx.lua -b bible.can scrpfile.sxd scrpfile.sbx|
+% \end{codeblock}
+%
+% Once the indexes are generated, generate the final book by invoking
+% \LaTeX{} one more time:
+%
+% \begin{codeblock}
+% |pdflatex mybook.tex|
+% \end{codeblock}
+%
+% \section{Customizing the Book}
+%
+% \subsection{Song and Verse Numbering}\label{sec:numbering}
+%
+% \paragraph{Song Numbering.}
+% \DescEnv{songnum}
+% The |songnum| counter defines the next song's number.
+% It is set to 1 at the beginning of a \env{songs} environment and is
+% increased by 1 after each \mac{endsong}.
+% It can be redefined anywhere except within a song.
+% For example,
+%
+% \begin{codeblock}
+% |\setcounter{songnum}{3}|
+% \end{codeblock}
+%
+% \noindent sets the next song's number to be 3.
+%
+% \DescMacro{thesongnum}
+% You can change the song numbering style for a song section by redefining
+% |\thesongnum|.
+% For example, to cause songs to be numbered A1, A2, etc., in the current
+% song section, type
+%
+% \begin{codeblock}
+% |\renewcommand{\thesongnum}{A\arabic{songnum}}|
+% \end{codeblock}
+%
+% \noindent
+% The expansion of |\thesongnum| must always produce plain text with no
+% font formatting or unexpandable macro tokens, since its text is
+% exported to auxiliary index generation files where it is sorted.
+%
+% \DescMacro{printsongnum}
+% To change the formatting of song numbers as they appear at the beginning
+% of each song, redefine the |\printsongnum| macro,
+% which expects the text yielded by \mac{thesongnum} as its only argument.
+% For example, to typeset song numbers in italics atop each song, define
+%
+% \begin{codeblock}
+% |\renewcommand{\printsongnum}[1]{\it\LARGE#1}|
+% \end{codeblock}
+%
+% \DescMacro{songnumwidth}
+% The |\songnumwidth| length defines the width of the shaded boxes that contain
+% song numbers at the beginning of each song.
+% For example, to make each such box 2 centimeters wide, you could define
+%
+% \begin{codeblock}
+% |\setlength{\songnumwidth}{2cm}|
+% \end{codeblock}
+%
+% \noindent
+% If |\songnumwidth| is set to zero, song numbers are not shown at all.
+%
+% \DescMacro{nosongnumbers}
+% To turn off song numbering entirely, type |\nosongnumbers|.
+% This inhibits the display of the song number atop each song
+% (but song numbers are still be displayed elsewhere, such as in indexes).
+% The same effect can be achieved by setting \mac{songnumwidth} to zero.
+%
+% \paragraph{Verse Numbering.}
+% \DescEnv{versenum}
+% The |versenum| counter defines the next verse's number.
+% It is set to 1 after each \mac{beginsong} line and is increased by 1 after
+% each \mac{endverse} (except if the verse begins with \mac{beginverse}|*|).
+% The |versenum| counter can be redefined anywhere within a song.
+% For example,
+%
+% \begin{codeblock}
+% |\setcounter{versenum}{3}|
+% \end{codeblock}
+%
+% \noindent sets the next verse's number to be 3.
+%
+% \DescMacro{theversenum}
+% You can change the verse numbering style by redefining |\theversenum|.
+% For example, to cause verses to be numbered in uppercase roman numerals,
+% define
+%
+% \begin{codeblock}
+% |\renewcommand{\theversenum}{\Roman{versenum}}|
+% \end{codeblock}
+%
+% \DescMacro{printversenum}
+% To change the formatting of verse numbers as they appear at the beginning
+% of each verse, redefine the |\printversenum| macro,
+% which expects the text yielded by \mac{theversenum} as its only argument.
+% For example, to typeset verse numbers in italics, define
+%
+% \begin{codeblock}
+% |\renewcommand{\printversenum}[1]{\it\LARGE#1.\ }|
+% \end{codeblock}
+%
+% \DescMacro{versenumwidth}
+% The |\versenumwidth| length defines the horizontal space reserved for verse
+% numbers to the left of each verse text.
+% Verse text is shifted right by this amount.
+% For example, to reserve half a centimeter of space for verse numbers, define
+%
+% \begin{codeblock}
+% |\setlength{\versenumwidth}{0.5cm}|
+% \end{codeblock}
+%
+% Verse numbers whose widths exceed |\versenumwidth| indent the first
+% line of the verse an additional amount to make room, but subsequent lines
+% of the verse are only indented by |\versenumwidth|.
+%
+% \DescMacro{noversenumbers}
+% To turn off verse numbering entirely, use |\noversenumbers|.
+% This is equivalent to saying
+%
+% \begin{codeblock}
+% |\renewcommand{|\mac{printversenum}|}[1]{}|
+% |\setlength{\versenumwidth}{0pt}|
+% \end{codeblock}
+%
+% \DescMacro{placeversenum}
+% The horizontal placement of verse numbers within the first line of each
+% verse is controlled by the |\placeversenum| macro.
+% By default, each verse number is placed flush-left.
+% \ImplOrDesc
+% {Authors interested in changing the placement of verse numbers should
+% consult \S\ref{sec:impparams} of the implementation section for more
+% information on this macro.}
+% {For more information on this macro, recompile this documentation with
+% the implementation section included.}
+%
+% \subsection{Song Appearance}
+%
+% \paragraph{Font Selection.}
+% \DescMacro{lyricfont}
+% By default, lyrics are typeset using the document-default font
+% (|\normalfont|) and with the document-default point size (|\normalsize|).
+% You can change these defaults by redefining |\lyricfont|.
+% For example, to cause lyrics to be typeset in small sans serif font,
+% you could define
+%
+% \begin{codeblock}
+% |\renewcommand{\lyricfont}{\sffamily\small}|
+% \end{codeblock}
+%
+% \DescMacro{stitlefont}
+% Song titles are typeset in a sans-serif, slanted font by default
+% (sans-serif, upright if producing slides), with minimal line spacing.
+% You can change this default by redefining |\stitlefont|.
+% For example, to cause titles to be typeset in a roman font with lines
+% spaced 20 points apart, you could define
+%
+% \begin{codeblock}
+% |\renewcommand{\stitlefont}{|
+% | \rmfont\Large\baselineskip=20pt\lineskiplimit=0pt|
+% |}|
+% \end{codeblock}
+%
+% \DescMacro{versefont}
+% \DescMacro{chorusfont}
+% \DescMacro{meterfont}
+% \DescMacro{echofont}
+% \DescMacro{notefont}
+% You can apply additional font changes to verses, choruses, meter numbers,
+% echo parts produced with \mac{echo}, and textual notes produced with
+% \mac{textnote} and \mac{musicnote}, by redefining |\versefont|,
+% |\chorusfont|, |\meterfont|, |\echofont|, and |\notefont|, respectively.
+% For example, to typeset choruses in italics, you could define
+%
+% \begin{codeblock}
+% |\renewcommand{\chorusfont}{\it}|
+% \end{codeblock}
+%
+% \DescMacro{notebgcolor}
+% \DescMacro{snumbgcolor}
+% The colors of shaded boxes containing textual notes and song numbers
+% can be changed by redefining the |\notebgcolor| and |\snumbgcolor|
+% macros.
+% For example:
+%
+% \begin{codeblock}
+% |\renewcommand{\notebgcolor}{red}|
+% \end{codeblock}
+%
+% \DescMacro{printchord}
+% By default, chords are typeset in sans serif oblique (slanted) font.
+% You can customize chord appearance by redefining |\printchord|, which
+% accepts the chord text as its argument.
+% For example, to cause chords to be printed in roman boldface font,
+% you could define
+%
+% \begin{codeblock}
+% |\renewcommand{\printchord}[1]{\rmfamily\bf#1}|
+% \end{codeblock}
+%
+% \paragraph{Accidental Symbols.}
+% \DescMacro{sharpsymbol}
+% \DescMacro{flatsymbol}
+% By default, sharp and flat symbols are typeset using \LaTeX's
+% |\#| ($\#$) and |\flat| ($\flat$) macros.
+% Users can change this by redefining |\sharpsymbol| and |\flatsymbol|.
+% For example, to use |\sharp| ($\sharp$) instead of $\#$, one could
+% redefine |\sharpsymbol| as follows.
+%
+% \begin{codeblock}
+% |\renewcommand{\sharpsymbol}{\ensuremath{^\sharp}}|
+% \end{codeblock}
+%
+% \paragraph{Verse and Chorus Titles.}
+% \DescMacro{everyverse}
+% \DescMacro{everychorus}
+% The |\everyverse| macro is executed at the beginning of each verse, and
+% |\everychorus| is executed at the beginning of each chorus.
+% Thus, to begin each chorus with the word ``Chorus:'' one could type,
+%
+% \begin{codeblock}
+% |\renewcommand{\everychorus}{|\mac{textnote}|{Chorus:}}|
+% \end{codeblock}
+%
+% \paragraph{Spacing Options.}
+% \DescMacro{versesep}
+% The vertical distance between song verses and song choruses is defined by
+% the skip register |\versesep|.
+% For example, to put 12 points of space between each pair of verses and
+% choruses, with a flexibility of plus or minus 2 points, you could define
+%
+% \begin{codeblock}
+% |\versesep=12pt plus 2pt minus 2pt|
+% \end{codeblock}
+%
+% \DescMacro{afterpreludeskip}
+% \DescMacro{beforepostludeskip}
+% The vertical distance between the song's body and its prelude and postlude
+% material is controlled by skips |\afterpreludeskip| and
+% |\beforepostludeskip|.
+% This glue can be made stretchable for centering effects.
+% For example, to cause each song body to be centered on the page with one
+% song per page, you could write:
+%
+% \begin{codeblock}
+% \mac{songcolumns}|{1}|
+% \mac{spenalty}|=-10000|
+% |\afterpreludeskip=2pt plus 1fil|
+% |\beforepostludeskip=2pt plus 1fil|
+% \end{codeblock}
+%
+% \DescMacro{baselineadj}
+% The vertical distance between the baselines of consecutive lines of
+% lyrics is computed by the \Songs{} package based on several factors
+% including the lyric font size, the chord font size (if in \env{chorded}
+% mode), and whether \env{slides} mode is currently active.
+% You can adjust the results of this computation by redefining skip
+% register |\baselineadj|.
+% For example, to reduce the natural distance between baselines by 1 point
+% but allow an additional 1 point of stretching when attempting to balance
+% columns, you could define
+%
+% \begin{codeblock}
+% |\baselineadj=-1pt plus 1pt minus 0pt|
+% \end{codeblock}
+%
+% \DescMacro{clineparams}
+% To change the vertical distance between chords and the lyrics below them,
+% redefine the |\clineparams| macro with a definition that adjusts the
+% \LaTeX{} parameters |\baselineskip|, |\lineskiplimit|, and |\lineskip|.
+% For example, to cause the baselines of chords and their lyrics to be
+% 12 points apart with at least 1 point of space between the bottom of the
+% chord and the top of the lyric, you could write:
+%
+% \begin{codeblock}
+% |\renewcommand{\clineparams}{|
+% | \baselineskip=12pt|
+% | \lineskiplimit=1pt|
+% | \lineskip=1pt|
+% |}|
+% \end{codeblock}
+%
+% \DescMacro{cbarwidth}
+% The width of the vertical line that appears to the left of choruses is
+% controlled by the |\cbarwidth| length.
+% To eliminate the line entirely (and the spacing around it), you can set
+% |\cbarwidth| to |0pt|:
+%
+% \begin{codeblock}
+% |\setlength{\cbarwidth}{0pt}|
+% \end{codeblock}
+%
+% \DescMacro{sbarheight}
+% The height of the horizontal line that appears between each pair of songs
+% is controlled by the |\sbarheight| length.
+% To eliminate the line entirely (and the spacing around it), you can set
+% |\sbarheight| to |0pt|:
+%
+% \begin{codeblock}
+% |\setlength{\sbarheight}{0pt}|
+% \end{codeblock}
+%
+% \paragraph{Song Top and Bottom Material.}
+% You can adjust the header and footer material that precedes and concludes
+% each song by redefining |\extendprelude| and |\extendpostlude|.
+%
+% \DescMacro{extendprelude}
+% \DescMacro{showauthors}
+% \DescMacro{showrefs}
+% By default, |\extendprelude| displays the song's authors and scripture
+% references using the macros |\showauthors| and |\showrefs|.
+% The following definition changes it to also print copyright info:
+%
+% \begin{codeblock}
+% |\renewcommand{\extendprelude}{|
+% | |\mac{showrefs}\mac{showauthors}
+% | {\bfseries|\mac{songcopyright}|\par}|
+% |}|
+% \end{codeblock}
+%
+% \DescMacro{extendpostlude}
+% By default, |\extendpostlude| prints the song's copyright and licensing
+% information as a single paragraph using \mac{songcopyright} and
+% \mac{songlicense}.
+% The following definition changes it to also print the words
+% ``Used with permission'' at the end of every song's footer information:
+%
+% \begin{codeblock}
+% |\renewcommand{\extendpostlude}{|
+% | |\mac{songcopyright}|\ |\mac{songlicense}|\unskip|
+% | \ Used with permission.|
+% |}|
+% \end{codeblock}
+%
+% In general, any macro documented in \S\ref{sec:songinfo} can be used
+% in |\extendprelude| and |\extendpostlude| to print song information, such
+% as \mac{songauthors}, \mac{songrefs}, \mac{songcopyright}, and
+% \mac{songlicense}.
+% For convenience, the \mac{showauthors} and \mac{showrefs} macros display
+% author and scripture reference information as a pre-formatted paragraph
+% the way it appears in the default song header blocks.
+%
+% See \S\ref{sec:newkey} for how to define new \mac{beginsong} keyvals and
+% use them in |\extendprelude|.
+%
+% \DescMacro{makeprelude}
+% \DescMacro{makepostlude}
+% For complete control over the appearance of the header and footer material
+% that precedes and concludes each song, you can redefine the macros
+% |\makeprelude| and |\makepostlude|.
+% When typesetting a song, the \Songs{} package code invokes both of these
+% macros once (after processing all the material between the \mac{beginsong}
+% and \mac{endsong} lines), placing the results within vboxes.
+% The resulting vboxes are placed atop and below the song content.
+% By default, |\makeprelude| displays the song's titles, authors, and scripture
+% references to the right of a shaded box containing the song's number; and
+% |\makepostlude| displays the song's copyright and licensing information in
+% fine print.
+%
+% As a simple example, the following causes each song to start with its
+% number and title(s), centered, in a large, boldface font, and then centers
+% the rest of the prelude material (e.g., references and authors) below that
+% (using \mac{extendprelude}).
+%
+% \begin{codeblock}
+% |\renewcommand\makeprelude{%|
+% | |\mac{resettitles}
+% | \centering|
+% | {\Large\bfseries|\mac{thesongnum}|. |\mac{songtitle}|\par|
+% | |\mac{nexttitle}\mac{foreachtitle}|{(|\mac{songtitle}|)\par}}%|
+% | |\mac{extendprelude}
+% |}|
+% \end{codeblock}
+%
+% \paragraph{Page- and Column-breaking.}
+% \DescMacro{vvpenalty}
+% \DescMacro{ccpenalty}
+% \DescMacro{vcpenalty}
+% \DescMacro{cvpenalty}
+% \DescMacro{brkpenalty}
+% Page-breaking and column-breaking within songs that are too large to fit
+% in a single column/page is influenced by the values of several penalties.
+% Penalties of value |\interlinepenalty| are inserted between consecutive
+% lines of each verse and chorus;
+% penalties of value |\vvpenalty|, |\ccpenalty|, |\vcpenalty|, and |\cvpenalty|
+% are inserted into each song between consecutive verses, between consecutive
+% choruses, after a verse followed by a chorus, and after a chorus followed by
+% a verse, respectively;
+% and penalties of value |\brkpenalty| are inserted wherever \mac{brk} is
+% used on a line by itself.
+% The higher the penalty, the less likely \TeX{} is to place a
+% page- or column-break at that site.
+% If any are set to $-10000$ or lower, breaks are forced there.
+% By default, |\interlinepenalty| is set to 1000 and the rest are set to 200
+% so that breaks between verses and choruses are preferred over breaks within
+% choruses and verses, but are not forced.
+%
+% \DescMacro{sepverses}
+% Saying |\sepverses| sets all of the above penalties to $-10000$ except for
+% |\ccpenalty| which is set to 100.
+% This is useful in \env{slides} mode because it forces each verse and
+% chorus to be typeset on a separate slide, except for consecutive choruses,
+% which remain together when possible.
+% (This default reflects an expectation that consecutive choruses typically
+% consist of a pre-chorus and chorus that are always sung together.)
+%
+% These defaults can be changed by changing the relevant penalty register
+% directly.
+% For example, to force a page- or column-break between consecutive choruses,
+% type
+%
+% \begin{codeblock}
+% |\ccpenalty=-10000|
+% \end{codeblock}
+%
+% \paragraph{Text Justification.}
+% \DescMacro{versejustify}
+% \DescMacro{chorusjustify}
+% \DescMacro{justifyleft}
+% \DescMacro{justifycenter}
+% To left-justify or center the lines of verses or choruses, redefine
+% |\versejustify| or |\chorusjustify| to |\justifyleft| or |\justifycenter|,
+% respectively.
+% For example, to cause choruses to be centered, one could type:
+%
+% \begin{codeblock}
+% |\renewcommand{|\mac{chorusjustify}|}{\justifycenter}|
+% \end{codeblock}
+%
+% \DescMacro{notejustify}
+% Justification of textual notes too long to fit on a single line
+% is controlled by the |\notejustify| macro.
+% By default, it sets up an environment that fully justifies the note
+% (i.e., all but the last line of each paragraph extends all the way from
+% the left to the right margin).
+% \ImplOrDesc
+% {Authors interested in changing this behavior should consult
+% \S\ref{sec:impparams} of the implementation section for more
+% information about this macro.}
+% {For more information, recompile this documentation with the
+% implementation section included.}
+%
+% \DescMacro{placenote}
+% A textual note that is shorter than a single line is placed flush-left by
+% default, or is centered when in slides mode.
+% This placement of textual notes is controlled by |\placenote|.
+% \ImplOrDesc
+% {Authors interested in changing this behavior should consult
+% \S\ref{sec:impparams} of the implementation section for more
+% information about this macro.}
+% {For more information, recompile this documentation with the
+% implementation section included.}
+%
+% \subsection{Scripture Appearance}
+%
+% \DescMacro{scripturefont}
+% By default, scripture quotations are typeset in Zaph Chancery font
+% with the document-default point size (|\normalsize|).
+% You can change these defaults by redefining |\scripturefont|.
+% For example, to cause scripture quotations to be typeset in sans serif
+% italics, define:
+%
+% \begin{codeblock}
+% |\renewcommand{\scripturefont}{\sffamily\it}|
+% \end{codeblock}
+%
+% \DescMacro{printscrcite}
+% By default, the citation at the end of a scripture quotation is
+% typeset in sans serif font at the document-default point size
+% (|\normalsize|).
+% You can customize the appearance of the citation by redefining
+% |\printscrcite|, which accepts the citation text as its argument.
+% For example, to cause citations to be printed in roman italics font, define:
+%
+% \begin{codeblock}
+% |\renewcommand{\printscrcite}[1]{\rmfamily\it#1}|
+% \end{codeblock}
+%
+% \subsection{Conditional Blocks}\label{sec:conditionals}
+%
+% Conditional macros allow certain material to be included in some books but
+% not others.
+% For example, a musician's chord book might include extra verses with
+% alternate chordings.
+%
+% \DescMacroGroup{if}{if...}{ifchorded,iflyric,ifslides,ifpartiallist,ifsongindexes,ifmeasures,ifrawtext,iftranscapos,ifnolyrics,ifpagepreludes,ifvnumbered}
+% A conditional block begins with a macro named |\if|\Meta{type}, where
+% \Meta{type} is one of the types listed in the first column of
+% Table~\ref{tab:conditionals}.
+% \begin{table}
+% \newcommand\tablerule{\noalign{\hrule}}
+% \newlength\oldbaselineskip \oldbaselineskip\baselineskip
+% \newlength\oldlineskip \oldlineskip\lineskip
+% \newdimen\oldlineskiplimit \oldlineskiplimit\lineskiplimit
+% \newcommand\oninterlineskip{%
+% \baselineskip\oldbaselineskip
+% \lineskip\oldlineskip
+% \lineskiplimit\oldlineskiplimit}
+% \vbox{\offinterlineskip\hrule
+% \halign{&\vrule#&\strut\quad#\hfil\quad&\vrule#&\quad\vtop{\oninterlineskip\hsize3.5in\leftskip0.25in\parindent-0.25in\indent\vrule height\ht\strutbox width0pt depth0pt#\vrule height0pt width0pt depth\dp\strutbox\par}\quad\cr
+% height2pt&\omit&&\omit&\cr
+% &\hfil{\large\strut Type}&&\hfil{\large\strut Processed only if\kern1pt$\ldots$}&\cr\tablerule
+% height2pt&\omit&&\omit&\cr
+% &|chorded|&&the \env{chorded} option is active&\cr\tablerule
+% &|lyric|&&the \env{chorded} option is not active&\cr\tablerule
+% &|slides|&&the \env{slides} option is active&\cr\tablerule
+% &|partiallist|&&the \mac{includeonlysongs} macro is being used to extract
+% a partial list of songs&\cr\tablerule
+% &|songindexes|&&the \env{noindexes} option is not active&\cr\tablerule
+% &|measures|&&the \env{nomeasures} option is not active&\cr\tablerule
+% &|rawtext|&&the \env{rawtext} option is active&\cr\tablerule
+% &|transcapos|&&the \env{transposecapos} option is active&\cr\tablerule
+% &|nolyrics|&&the \mac{nolyrics} macro is in effect&\cr\tablerule
+% &|pagepreludes|&&the \mac{pagepreludes} macro is in effect&\cr\tablerule
+% &|vnumbered|&&the current verse is numbered (i.e., it was started
+% with \mac{beginverse} instead of \mac{beginverse}|*|)&\cr}
+% \hrule}
+% \caption{Conditional macros}\label{tab:conditionals}
+% \end{table}
+% The conditional block concludes with the macro |\fi|.
+% Between the |\if|\Meta{type} and the |\fi| may also appear an |\else|.
+% For example, in the construction
+%
+% \begin{codeblock}
+% |\ifchorded|
+% \quad\Meta{A}
+% |\else|
+% \quad\Meta{B}
+% |\fi|
+% \end{codeblock}
+%
+% \noindent
+% material \Meta{A} is only included if the \env{chorded} option is active,
+% and material \Meta{B} is only included if the \env{chorded} option is not
+% active.
+%
+% \subsection{Page Layout}\label{sec:layout}
+%
+% \DescMacro{songcolumns}
+% The number of columns per page can be set with |\songcolumns|.
+% For example, to create 3 columns per page, write
+%
+% \begin{codeblock}
+% |\songcolumns{3}|
+% \end{codeblock}
+%
+% \noindent
+% The number of columns should only be changed outside of \env{songs}
+% environments.
+%
+% Setting the number of columns to zero disables the page-building algorithm
+% entirely.
+% This can be useful if you want to use an external package, such as
+% |multicol| or \LaTeX's built-in |\twocolumn| macro, to build pages.
+% For example, the following sets up an environment that is suitable for
+% a lyric book that uses |\twocolumn|:
+%
+% \begin{codeblock}
+% |\songcolumns{0}|
+% |\flushbottom|
+% |\twocolumn[\LARGE\centering My Songs]|
+% |\begin{|\env{songs}|}{}|
+% $\vdots$
+% |\end{|\env{songs}|}|
+% \end{codeblock}
+%
+% \noindent
+% When disabling the page-builder, please note the following potential
+% issues:
+%
+% \begin{itemize}
+% \item The \mac{repchoruses} feature does not work when the page-builder
+% is disabled because the page-builder is responsible for inserting
+% repeated choruses as new columns are formed.
+% \item External page-building packages tend to allow column- and
+% page-breaks within songs because they have no mechanism for moving an
+% entire song to the next column or page to avoid such a break
+% (see \mac{songpos} below).
+% \item Indexes produced with \mac{showindex} are typeset to the width of
+% the enclosing environment.
+% Thus, you should be sure to reset \LaTeX{} back to one column (via
+% |\onecolumn|) before executing \mac{showindex}.
+% \end{itemize}
+%
+% \DescMacro{pagepreludes}
+% Song preludes (i.e., the material atop each song, including the title) are
+% typeset by default at column width.
+% Writing |\pagepreludes| typesets subsequent preludes at page width atop
+% fresh pages, with the rest of the song in multiple columns beneath its title.
+% (To prohibit separation of songs from their preludes, it also sets
+% \mac{songpos} to 0.)
+%
+% \DescMacro{columnsep}
+% The horizontal distance between consecutive columns is controlled by
+% the |\columnsep| dimension.
+% For example, to separate columns by 1 centimeter of space, write
+%
+% \begin{codeblock}
+% |\columnsep=1cm|
+% \end{codeblock}
+%
+% \DescMacro{colbotglue}
+% When \LaTeX{} ends each column it inserts glue equal to |\colbotglue|.
+% In lyric books this macro is set to |0pt| so that each column ends flush with
+% the bottom of the page.
+% In other books that have ragged bottoms, it is set to stretchable
+% glue so that columns end at whatever vertical position is convenient.
+% The recommended setting for typsetting columns with ragged bottoms is:
+%
+% \begin{codeblock}
+% |\renewcommand{\colbotglue}{0pt plus .5\textheight minus 0pt}|
+% \end{codeblock}
+%
+% \DescMacro{lastcolglue}
+% The last column in a \env{songs} environment gets |\lastcolglue| appended
+% to it instead.
+% By default it is infinitely stretchable so that the last column ends
+% at its natural height.
+% By setting it to |0pt|, you can force the last column to be flush with
+% the bottom of the page:
+%
+% \begin{codeblock}
+% |\renewcommand{\lastcolglue}{0pt}|
+% \end{codeblock}
+%
+% \DescMacro{songpos}
+% The \Songs{} package uses a song-positioning algorithm that
+% moves songs to the next column or page in order to avoid column- or
+% page-breaks within songs.
+% The algorithm has four levels of aggressiveness, numbered from 0 to 3.
+% You can change the aggressiveness level by typing
+%
+% \begin{codeblock}
+% |\songpos{|\Meta{level}|}|
+% \end{codeblock}
+%
+% \noindent
+% The default level is 3, which avoids column-breaks, page-breaks,
+% and page-turns within songs whenever possible.
+% (Page-turns are page-breaks after odd-numbered pages in two-sided documents,
+% or after all pages in one-sided documents.)
+% Level 2 avoids page-breaks and page-turns but allows column-breaks within
+% songs.
+% Level 1 avoids only page-turns within songs.
+% Level 0 turns off the song-positioning algorithm entirely.
+% This causes songs to be positioned wherever \TeX{} thinks is best
+% based on penalty settings (see \mac{vvpenalty} and \mac{spenalty}).
+%
+% \DescMacro{spenalty}
+% The value of |\spenalty| controls the undesirability of column breaks
+% at song boundaries.
+% Usually it should be set to a value between 0 and \mac{vvpenalty} so that
+% breaks between songs are preferable to breaks between verses within a song.
+% By default it is set to 100.
+% When it is $-10000$ or less, breaks between songs are required, so that
+% each song always begins a fresh column.
+%
+% \subsection{Indexes}\label{sec:idxcust}
+%
+% \subsubsection{Index Appearance}
+%
+% \paragraph{Index Titles.}
+% To customize the appearance of index titles, redefine the \mac{songsection}
+% and/or \mac{songchapter} macros from \S\ref{sec:sectioning}.
+% For example, to use \LaTeX's built-in |\section| and |\chapter| macros
+% instead, you could write:
+%
+% \begin{codeblock}
+% |\renewcommand{|\mac{songchapter}|}{\chapter}|
+% |\renewcommand{|\mac{songsection}|}{\section}|
+% \end{codeblock}
+%
+% \paragraph{Layout and page divisions.}
+% \DescMacro{sepindexestrue}
+% \DescMacro{sepindexesfalse}
+% Indexes are by default typeset on separate pages, and when an index is
+% sufficiently small, it is centered on the page in one column.
+% To disable these defaults, write |\sepindexesfalse|.
+% This causes indexes to avoid using unnecessary vertical space or
+% starting unnecessary new pages.
+% To re-enable the defaults, use |\sepindexestrue|.
+%
+% \DescMacro{idxheadwidth}
+% The |\idxheadwidth| length defines the width of the shaded boxes that
+% begin each alphabetic block of a large title index.
+% Setting it to 0pt suppresses the boxes entirely.
+% For example, to set the width of those boxes to 1 centimeter, you could
+% define
+%
+% \begin{codeblock}
+% |\setlength{\idxheadwidth}{1cm}|
+% \end{codeblock}
+%
+% \paragraph{Fonts and colors.}
+% \DescMacro{idxrefsfont}
+% To control the formatting of the list of references on the right-hand side
+% of index entries, redefine |\idxrefsfont|.
+% For example, to typeset each list in boldface, write
+%
+% \begin{codeblock}
+% |\renewcommand{\idxrefsfont}{\bfseries}|
+% \end{codeblock}
+%
+% \DescMacro{idxtitlefont}
+% \DescMacro{idxlyricfont}
+% Title indexes contain entries for song titles and also entries for notable
+% lines of lyrics.
+% The fonts for these entries are controlled by |\idxtitlefont| and
+% |\idxlyricfont|, respectively.
+% For example, to show title entries in boldface sans-serif and lyric entries
+% in regular roman font, one could define:
+%
+% \begin{codeblock}
+% |\renewcommand{\idxtitlefont}{\sffamily\bfseries}|
+% |\renewcommand{\idxlyricfont}{\rmfamily\mdseries}|
+% \end{codeblock}
+%
+% \DescMacro{idxheadfont}
+% To change the font used to typeset the capital letters that start each
+% alphabetic section of a large title index, redefine |\idxheadfont|.
+% For example, to typeset those letters in italics instead of boldface, type
+%
+% \begin{codeblock}
+% |\renewcommand{\idxheadfont}{\sffamily\it\LARGE}|
+% \end{codeblock}
+%
+% \DescMacro{idxbgcolor}
+% To change the background color of the shaded boxes that contain the
+% capital letters that start each alphabetic sectino of a large title
+% index, redefine |\idxbgcolor|.
+% For example:
+%
+% \begin{codeblock}
+% |\renewcommand{\idxbgcolor}{red}|
+% \end{codeblock}
+%
+% \DescMacro{idxauthfont}
+% The font used to typeset entries of an author index is controlled by
+% |\idxauthfont|.
+% For example, to typeset such entries in italics instead of boldface, type
+%
+% \begin{codeblock}
+% |\renewcommand{\idxauthfont}{\small\it}|
+% \end{codeblock}
+%
+% \DescMacro{idxscripfont}
+% The font used to typeset entries of a scripture index is controlled by
+% |\idxscripfont|.
+% For example, to typeset such entries in boldface instead of italics, type
+%
+% \begin{codeblock}
+% |\renewcommand{\idxscripfont}{\sffamily\small\bfseries}|
+% \end{codeblock}
+%
+% \DescMacro{idxbook}
+% To control the formatting of the lines that start each new book of the
+% bible in a scripture index, redefine |\idxbook|, which accepts the book
+% name as its single argument.
+% For example, to typeset each book name in a box, one could define
+%
+% \begin{codeblock}
+% |\renewcommand{\idxbook}[1]{\framebox{\small\bfseries#1}}|
+% \end{codeblock}
+%
+% \DescMacro{idxcont}
+% In a scripture index, when a column break separates a block of entries
+% devoted to a book of the bible, the new column is titled
+% ``\Meta{bookname} (continued)'' by default.
+% You can change this default by redefining the |\idxcont| macro, which
+% receives the \Meta{bookname} as its single argument.
+% For example, to typeset an index in German, one might define
+%
+% \begin{codeblock}
+% |\renewcommand{\idxcont}[1]{\small\textbf{#1} (fortgefahren)}|
+% \end{codeblock}
+%
+% \subsubsection{Entry References}
+%
+% \DescMacro{indexsongsas}
+% By default, the right-hand side of each index entry contains a list of
+% one or more song numbers.
+% To instead list page numbers, use the |\indexsongsas| macro:
+%
+% \begin{codeblock}
+% |\indexsongsas{|\Meta{id}|}{\thepage}|
+% \end{codeblock}
+%
+% \noindent
+% where \Meta{id} is the same identifier used in the \mac{newindex},
+% \mac{newauthorindex}, or \mac{newscripindex} macro that created the index.
+% The second argument must always be something that expands into raw text
+% without any formatting, since this text gets output to auxiliary files that
+% are lexographically sorted by the index-generation program.
+% To go back to indexing songs by song number, use \mac{thesongnum} in place
+% of |\thepage| in the above.
+%
+% \subsubsection{PDF Bookmarks and Links}
+%
+% \DescMacro{songtarget}
+% \DescMacro{songlink}
+% Each \mac{beginsong} environment adds a PDF bookmark (if generating a PDF)
+% and hyperlink target (if using the |hyperref| package) for the
+% song by invoking |\songtarget| with two arguments:
+% (1) a suggested PDF bookmark level, and (2) a link target name.
+% Links in indexes to these targets are created by |\songlink|, which
+% also gets two arguments:
+% (1) the link target name (same as the second argument to \mac{songtarget}),
+% and (2) the text to be linked.
+%
+% Redefine these macros to customize or suppress these bookmarks, targets,
+% and links.
+% For example, to enable both bookmarks and links (the default behavior) use:
+%
+% \begin{codeblock}
+% |\renewcommand{\songtarget}[2]|
+% | {\pdfbookmark[#1]{|\mac{thesongnum}|. |\mac{songtitle}|}{#2}}|
+% |\renewcommand{\songlink}[2]{\hyperlink{#1}{#2}}|
+% \end{codeblock}
+%
+% \noindent
+% To enable links but not bookmarks, use:
+%
+% \begin{codeblock}
+% |\renewcommand{\songtarget}[2]{\hypertarget{#2}{\relax}}|
+% |\renewcommand{\songlink}[2]{\hyperlink{#1}{#2}}|
+% \end{codeblock}
+%
+% \noindent
+% To disable both bookmarks and links, use:
+%
+% \begin{codeblock}
+% |\renewcommand{\songtarget}[2]{}|
+% |\renewcommand{\songlink}[2]{#2}|
+% \end{codeblock}
+%
+% \subsubsection{Sort Order}
+%
+% The alphabetic ordering of entries in title and author indexes is dictated
+% by the computer system on which the \Songs{} software is installed.
+% Different languages and regions have different sorting conventions, so the
+% |songidx| Lua script delegates decisions about order to your operating system.
+% If the default ordering proves inadequate, you can modify it by changing your
+% operating system's \emph{locale} (see your system's local help files).
+% Alternatively, you can explicitly tell the |songidx| program which locale to
+% use in one of three ways:
+%
+% \begin{itemize}
+% \item \emph{Windows:}
+% Edit the |generate.bat| file in the |Sample| folder (or your working folder)
+% with any plain text editor (e.g., Vim or Notepad).
+% Near the top, find the line that says |SET locale=|.
+% After the |=|, type any valid locale name.
+% For a list of valid locale names on Windows, please see the ``Language name
+% abbreviation'' column of Microsoft's online National Language Support (NLS)
+% API Reference:
+%
+% {\centering\url{http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx}\par}
+%
+% \item \emph{Unix:}
+% Create an environment variable named |SONGIDX_LOCALE| and set it equal to
+% the desired locale name.
+% The command |locale -a| lists all valid locale names on most Unix systems.
+%
+% \item \emph{Command-line:}
+% If you are executing the |songidx| script manually, use the |-l| option to
+% specify the locale:
+%
+% \begin{codeblock}
+% |texlua songidx -l sv_SE myindex.sxd myindex.sbx|
+% \end{codeblock}
+%
+% \end{itemize}
+%
+% \subsubsection{Special Words In Song Info}
+%
+% The following macros control how certain keywords are treated when parsing
+% and sorting index entries.
+% They only affect indexes that have already been declared, so put them
+% strictly after all your index creation commands (see \S\ref{sec:indexes}).
+%
+% \DescMacro{titleprefixword}
+% In English, when a title begins with ``The'' or ``A'', it is traditional to
+% move these words to the end of the title and sort the entry by the following
+% word.
+% So for example, ``The Song Title'' is typically indexed as
+% ``Song Title, The''.
+% To change this default behavior, you can use |\titleprefixword| in the
+% document preamble to identify each word to be moved to the end whenever
+% it appears as the first word of a title index entry.
+% For example, to cause the word ``I'' to be moved to the end of title index
+% entries, one could say,
+%
+% \begin{codeblock}
+% |\titleprefixword{I}|
+% \end{codeblock}
+%
+% \noindent
+% The first use of |\titleprefixword| overrides the defaults, so if you also
+% want to continue to move ``The'' and ``A'' to the end of entries, you must
+% also say |\titleprefixword{The}| and |\titleprefixword{A}| explicitly.
+% This macro may only be used in the document preamble but may be used
+% multiple times to declare multiple prefix words.
+%
+% \DescMacro{authsepword}
+% When parsing author index entries, the word ``and'' is recognized by the
+% |songidx| script as a conjunctive that separates author names.
+% To override this default and specify a different conjunctive, use the
+% |\authsepword| macro one or more times in the document preamble.
+% For example, to instead treat ``und'' as a conjunctive, you could say,
+%
+% \begin{codeblock}
+% |\authsepword{und}|
+% \end{codeblock}
+%
+% \noindent
+% The first use of |\authsepword| and each of the following macros overrides
+% the default, so if you also want to continue to treat ``and'' as a
+% conjunctive, you must also say |\authsepword{and}| explicitly.
+%
+% \DescMacro{authbyword}
+% When parsing author index entries, the word ``by'' is recognized as a
+% keyword signaling that the index entry should only include material
+% in the current list item that follows the word ``by''.
+% So for example, ``Music by J.S. Bach'' is indexed as ``Bach, J.S.''
+% rather than ``Bach, Music by J.S.''
+% To recognize a different word instead of ``by'', you can use |\authbyword|
+% in the document preamble.
+% For example, to recognize ``durch'' instead, you could say
+%
+% \begin{codeblock}
+% |\authbyword{durch}|
+% \end{codeblock}
+%
+% \DescMacro{authignoreword}
+% When parsing author index entries, if a list item contains the word
+% ``unknown'', that item is ignored and is not indexed.
+% This prevents items like ``Composer unknown'' from being indexed as names.
+% To cause the indexer to recognize and ignore a different word, you can
+% use the |\authignoreword| macro in the document preamble.
+% For example, to ignore author index entries containing the word
+% ``unbekannt'', you could say,
+%
+% \begin{codeblock}
+% |\authignoreword{unbekannt}|
+% \end{codeblock}
+%
+% \subsection{Page Headers and Footers}
+%
+% In \LaTeX, page headers and footers are defined using a system of
+% invisible \emph{marks} that get inserted into the document at the
+% beginning of each logical unit of the document (e.g., each section, song,
+% verse, and chorus).
+% The headers and footers are then defined so as to refer to the first
+% and/or last invisible mark that ends up on each page once the document
+% is divided into pages.
+% This section describes the marks made available by the \Songs{} package.
+% For more detailed information about the marks already provided by
+% \LaTeX{} and how to use them, consult any \LaTeX{} user manual.
+%
+% \DescMacro{songmark}
+% \DescMacro{versemark}
+% \DescMacro{chorusmark}
+% To add song information to page headings and footers, redefine |\songmark|,
+% |\versemark|, or |\chorusmark| to add the necessary \TeX{} marks to the
+% current page whenever a new song, verse, or chorus begins.
+% These macros expect no arguments; to access the current song's
+% information including titles, use the macros documented in
+% \S\ref{sec:songinfo}.
+% To access the current song's number or the current verse's number, use
+% \mac{thesongnum} or \mac{theversenum} (see \S\ref{sec:numbering}).
+% For example, to include the song number in the page headings produced by
+% \LaTeX's |\pagestyle{myheadings}| feature, you could redefine |\songmark|
+% as follows:
+%
+% \begin{codeblock}
+% |\renewcommand{\songmark}{\markboth{|\mac{thesongnum}|}{|\mac{thesongnum}|}}|
+% \end{codeblock}
+%
+% \subsection{Defining New Beginsong Keyvals}\label{sec:newkey}
+%
+% \DescMacro{newsongkey}
+% The \mac{beginsong} macro supports several optional keyval parameters for
+% declaring song information, including \env{by=}, \env{sr=}, and \env{cr=}.
+% Users can define their own additional keyvals as well.
+% To do so, use the |\newsongkey| macro, which has the syntax
+%
+% \begin{codeblock}
+% |\newsongkey{|\Meta{keyname}|}{|\Meta{initcode}|}[|\Meta{default}|]{|\Meta{setcode}|}|
+% \end{codeblock}
+%
+% \noindent
+% Here, \Meta{keyname} is the name of the new key for the keyval,
+% \Meta{initcode} is \LaTeX{} code that is executed at the start of each
+% \mac{beginsong} line before the \mac{beginsong} arguments are processed,
+% \Meta{default} (if specified) is the default value used for the keyval when
+% \Meta{keyname} appears in \mac{beginsong} without a value,
+% and \Meta{setcode} is macro code that is executed whenever
+% \Meta{key} is parsed as part of the \mac{beginsong} keyval arguments.
+% In \Meta{setcode}, |#1| expands to the value given by the user for the
+% keyval (or to \Meta{default} if no value was given).
+%
+% For example, to define a new song key called |arr| which stores its
+% value in a macro called |\arranger|, one could write:
+%
+% \begin{codeblock}
+% |\newcommand{\arranger}{}|
+% |\newsongkey{arr}{\def\arranger{}}|
+% | {\def\arranger{Arranged by #1\par}}|
+% \end{codeblock}
+%
+% \noindent
+% Then one could redefine \mac{extendprelude} to print the arranger below the
+% other song header information:
+%
+% \begin{codeblock}
+% |\renewcommand{\extendprelude}{|
+% | |\mac{showrefs}\mac{showauthors}
+% | {\bfseries\arranger}|
+% |}|
+% \end{codeblock}
+%
+% \noindent
+% A \mac{beginsong} line could then specify the song's arranger as follows:
+%
+% \begin{codeblock}
+% \mac{beginsong}|{The Title}[arr={R. Ranger}]|
+% $\vdots$
+% \mac{endsong}
+% \end{codeblock}
+%
+% \noindent This produces
+%
+% \begin{sample}
+% \setcounter{songnum}{1}%
+% \vskip1pt%
+% \newcommand\arranger{}%
+% \newsongkey{arr}{\def\arranger{}}%
+% {\def\arranger{Arranged by #1\par}}%
+% \renewcommand{\extendprelude}{
+% \showrefs\showauthors
+% {\bfseries\arranger}
+% }%
+% \beginsong{The Title}[arr={R. Ranger}]
+% \endsong
+% \renewcommand{\extendprelude}{}%
+% \end{sample}
+%
+% For more detailed information about keyvals and how they work, consult the
+% documentation for David Carlisle's |keyval| package, which comes standard
+% with most \LaTeXe{} installations.
+%
+% \subsection{Font Kerning Corrections}
+%
+% \paragraph{Chord Overstriking.}
+% In order to conserve space and keep songs readable, the \Songs{} package
+% pushes chords down very close to the lyrics with which they are paired.
+% Unfortunately, this can sometimes cause low-hanging characters in chord
+% names to overstrike the lyrics they sit above.
+% For example,
+%
+% \example|\[(Gsus4/D)]Overstrike|\produces{\[(Gsus4/D)]Overstrike}
+% \eat\]
+%
+% \noindent
+% Note that the parentheses and slash symbols in the chord name have
+% invaded the lyric that sits beneath them.
+%
+% \DescMacro{chordlocals}
+% The best solution to this problem is to use a font for chord names that
+% minimizes low-hanging symbols; but if you lack such a font, then the
+% following trick works pretty well.
+% Somewhere in the preamble of your document, you can write the following
+% \LaTeX{} code:
+%
+% \begin{codeblock}
+% |\renewcommand{\chordlocals}{\catcode`(\active|
+% | \catcode`)\active|
+% | \catcode`/\active}|
+% |\newcommand{\smraise}[1]{\raise2pt\hbox{\small#1}}|
+% |\newcommand{\myslash}{\smraise/}|
+% |\newcommand{\myopenparen}{\smraise(|\eat)|}|
+% |\newcommand{\mycloseparen}{\smraise)}|
+% |{\chordlocals|
+% | \global\let(\myopenparen|
+% | \global\let)\mycloseparen|
+% | \global\let/\myslash}|
+% \end{codeblock}
+%
+% \noindent
+% This sets the |/|, |(|, and |)| symbols as active characters whenever they
+% appear within chord names.
+% \ImplOrDesc
+% {(See \S\ref{sec:chordlocals} for documentation of the
+% \texttt{\string\chordlocals} hook.)}
+% {(Recompile this documentation to include the implementation section
+% for more information about the \texttt{\string\chordlocals} macro.)}
+% Each active character is defined so that it produces a smaller, raised
+% version of the original symbol.
+% The result is as follows:
+%
+% \renewcommand{\chordlocals}{\catcode`(\active
+% \catcode`)\active
+% \catcode`/\active}
+% \newcommand{\smraise}[1]{\raise2pt\hbox{\small#1}}
+% \newcommand{\myslash}{\smraise/}
+% \newcommand{\myopenparen}{\smraise(}
+% \newcommand{\mycloseparen}{\smraise)}
+% {\chordlocals
+% \global\let(\myopenparen
+% \global\let)\mycloseparen
+% \global\let/\myslash}
+%
+% \example|\[(Gsus4/D)]Overstrike (fixed)|\produces{\[(Gsus4/D)]Overstrike (fixed)}
+% \eat\]
+%
+% \renewcommand\chordlocals{}
+%
+% \noindent
+% As you can see, the low-hanging symbols have been elevated so that they
+% sit above the baseline, correcting the overstrike problem.
+%
+% \paragraph{Scripture Font Quotation Marks.}
+% \DescMacro{shiftdblquotes}
+% The \Songs{} package compensates for a kerning problem in the Zaph Chancery
+% font (used to typeset scripture quotations) by redefining the |``| and |''|
+% token sequences to be active characters that yield double-quotes shifted
+% 1.1 points and 2 points left, respectively, of their normal positions.
+% If you use a different font size for scripture quotations, then you can use
+% the |\shiftdblquotes| macro when redefining \mac{scripturefont} to change
+% this kerning correction.
+% For example,
+%
+% \begin{codeblock}
+% |\renewcommand{|\mac{scripturefont}|}{|
+% | \usefont{OT1}{pzc}{mb}{it}|
+% | \shiftdblquotes{-1pt}{-2pt}{-3pt}{-4pt}|
+% |}|
+% \end{codeblock}
+%
+% \noindent
+% removes 1 point of space to the left and 2 points of space to the
+% right of left-double-quote characters, and 3 points to the left and 4 points
+% to the right of right-double-quotes, within scripture quotations.
+%
+% \section{Informational Macros}\label{sec:songinfo}
+%
+% The macros described in this section can be used to retrieve information
+% about the current song.
+% This can be used when redefining \mac{extendprelude}, \mac{extendpostlude},
+% \mac{makeprelude}, \mac{makepostlude}, \mac{songmark}, \mac{versemark}, or
+% \mac{chorusmark}, or any other macros that might typeset this information.
+%
+% \DescMacro{songauthors}
+% To get the current song's list of authors (if any) use |\songauthors|.
+% This yields the value of the \env{by=} key used in the \mac{beginsong}
+% line.
+%
+% \DescMacro{songrefs}
+% To get the current song's list of scripture references (if any) use
+% |\songrefs|.
+% This yields the value of the \env{sr=} key used in the \mac{beginsong}
+% line, but modified with hyphens changed to en-dashes and spaces falling
+% within a list of verse numbers changed to thin spaces for better
+% typesetting.
+% In addition, various penalties have been added to inhibit line breaks
+% in strange places and encourage line breaks in others.
+%
+% \DescMacro{songcopyright}
+% To get the current song's copyright info (if any), use |\songcopyright|.
+% This yields the value of the \env{cr=} key used in the \mac{beginsong} line.
+%
+% \DescMacro{songlicense}
+% To get the current song's licensing information (if any), use
+% |\songlicense|.
+% This yields the value of the \env{li=} key used in the \mac{beginsong}
+% line, or whatever text was declared with \mac{setlicense}.
+%
+% \DescMacro{songtitle}
+% The |\songtitle| macro yields the current song's title.
+% By default this is the first title provided in the \mac{beginsong} line.
+% The \mac{nexttitle} and \mac{foreachtitle} macros (see below) cause it
+% to be set to the current song's other titles, if any.
+%
+% \DescMacro{resettitles}
+% To get the current song's primary title (i.e., the first title specified
+% in the song's \mac{beginsong} line), execute |\resettitles|.
+% This sets the |\songtitle| macro to be the song's primary title.
+%
+% \DescMacro{nexttitle}
+% To get the song's next title, execute |\nexttitle|, which
+% sets |\songtitle| to be the next title in the song's list of titles
+% (or sets |\songtitle| to |\relax| if there are no more titles).
+%
+% \DescMacro{foreachtitle}
+% The |\foreachtitle| macro accepts \LaTeX{} code as its single
+% argument and executes it once for each (remaining) song title.
+% Within the provided code, use |\songtitle| to get the current title.
+% For example, the following code generates a comma-separated list of all
+% of the current song's titles:
+%
+% \begin{codeblock}
+% \mac{resettitles}
+% \mac{songtitle}
+% \mac{nexttitle}
+% |\foreachtitle{, |\mac{songtitle}|}|
+% \end{codeblock}
+%
+% \DescMacro{songlist}
+% When \mac{includeonlysongs} is used to extract a partial list of songs, the
+% |\songlist| macro expands to the comma-separated list of songs that is being
+% extracted.
+% Redefining |\songlist| within the document preamble alters the list of
+% songs to be extracted.
+% Redefining it after the preamble may have unpredictable results.
+%
+% \section{Other Resources}
+%
+% There are a number of other \LaTeX{} packages available for typesetting
+% songs, tablature diagrams, or song books.
+% Probably the best of these is the \Rath{} package by Christopher Rath
+% (\href{http://rath.ca/Misc/Songbook/}{{\tt http://rath.ca/Misc/Songbook/}}).
+% Most of the differences between other packages and this one are intentional;
+% the following is a summary of where I've adopted various differing design
+% decisions and why.
+%
+% \bigskip
+%
+% \paragraph{Ease of Song Entry.}
+% Much of the \Songs{} package programming is devoted to easing the burden of
+% typing chords.
+% With most \LaTeX{} song book packages the user types chords using a standard
+% \LaTeX{} macro syntax like |\chord{|\Meta{chord}|}{|\Meta{lyric}|}|.
+% The \Songs{} package uses a less conventional
+% |\[|\Meta{chord}|]|\Meta{lyric}\eat\] syntax for several
+% reasons detailed below.
+%
+% First, macros in the standard \LaTeX{} syntax require more key-presses
+% than macros in the \Songs{} package's syntax.
+% This can become become very taxing when typing up a large book.
+% Chords often appear as frequently as one per syllable, especially in hymns,
+% so keeping the syntax as brief as possible is desirable.
+%
+% Second, the standard \LaTeX{} macro syntax requires the user to estimate how
+% much of the \Meta{lyric} will lie below the chord (because the \Meta{lyric}
+% part must be enclosed in braces) whereas the \Songs{} package's syntax does
+% not.
+% Estimating this accurately can be quite difficult, since in many cases the
+% \Meta{lyric} part must include punctuation or multiple words to get proper
+% results.
+% The \Songs{} package automates this for the user, significantly easing the
+% task of chord-entry.
+%
+% Third, unlike the standard \LaTeX{} chord syntax, the \Songs{} package's
+% syntax handles all hyphenation of chorded lyrics fully automatically.
+% Extra hyphenation must be introduced in chord books wherever a chord
+% is wider than the syllable it sits above.
+% With the standard \LaTeX{} chord syntax such hyphenation must be
+% introduced manually by the user (usually via a special hyphenation macro),
+% but the \Songs{} package does this automatically.
+%
+% Fourth and finally, some other packages allow the user to use ``|b|''
+% in a \Meta{chord} to produce a flat symbol, whereas the \Songs{} package
+% requires an ``|&|'' instead.
+% Using ``|b|'' is more intuitive but prevents the
+% use of ``|b|'' for any other purpose within a \Meta{chord}, such as to
+% produce a literal ``b'' or to type another macro name like |\hbox| that
+% contains a ``b''.
+% Consequently, the \Songs{} package uses the less obvious ``|&|'' symbol to
+% produce flat symbols.
+%
+% \paragraph{Song Structure.}
+% The \Songs{} package provides a relatively small number of macros for
+% typesetting high-level song structure, including verses, choruses,
+% textual comments, and conditional macros that indicate that certain sections
+% should go in chord books but not lyric books.
+% These can be combined to typeset more sophisticated structures such as
+% intros, bridges, brackets, endings, and the like.
+% This is done in lieu of providing a specific macro for each of these
+% structures since it results in greater flexibility and fewer macros for
+% users to learn.
+%
+% \paragraph{Multiple columns.}
+% The \Songs{} package was designed from the ground up to produce song books
+% with many songs per page, arranged in multiple columns.
+% As a result, it includes elaborate support for many features not found in
+% most other packages, such as automatic column balancing, completely
+% customizable song header and song footer blocks, and facilities for adding
+% beautiful scripture quotations to fill in gaps between songs.
+%
+% \paragraph{Indexes.}
+% Another major feature of the \Songs{} package is its support for a variety
+% of different index types, most notably indexes arranged by scripture
+% reference.
+% Scripture indexes can be invaluable for planning services around particular
+% sermons or topics.
+% The \Songs{} package allows book authors to specify the names and preferred
+% ordering of books of the bible, and automatically handles complex issues
+% like overlapping verse ranges to produce an easy-to-read, compact, and
+% well-ordered index.
+% Other supported indexes include those sorted by author, by title, and by
+% notable lines of lyrics.
+%
+% \paragraph{Automatic Transposition.}
+% The \Songs{} package has a facility for automatically transposing songs, and
+% even generating chord books that print the chords in multiple keys (e.g., so
+% that a pianist and guitarist using a capo can play together from the same
+% book).
+%
+% \bigskip
+%
+% The \Songs{} package was developed entirely independently of all other
+% \LaTeX{} song book packages.
+% I originally developed the set of \LaTeX{} macros that eventually became
+% the \Songs{} package in order to typeset a song book for the Graduate
+% Christian Fellowship (GCF) at Cornell University, and the Cornell
+% International Christian Fellowship (CICF).
+% Once I had fine-tuned my package to be sufficiently versatile, I decided
+% to release it for public use.
+% At that time I noticed the \Rath{} package and others, and wrote this
+% summary of the most prominent differences.
+%
+% For information on more song-typesetting resources for \LaTeX, I recommend
+% consulting the documentation provided with the \Rath{} package.
+% It includes an excellent list of other resources that might be of interest
+% to creators of song books.
+%
+% \section{GNU General Public License}\label{sec:license}
+%
+% \begingroup\small
+%
+% \begin{center}
+% {\large\sc Terms and Conditions For \\ Copying, Distribution and Modification}
+% \end{center}
+%
+% \begin{enumerate}\addtocounter{enumi}{-1}
+%
+% \item
+%
+% This License applies to any program or other work which contains a notice
+% placed by the copyright holder saying it may be distributed under the
+% terms of this General Public License. The ``Program'', below, refers to
+% any such program or work, and a ``work based on the Program'' means either
+% the Program or any derivative work under copyright law: that is to say, a
+% work containing the Program or a portion of it, either verbatim or with
+% modifications and/or translated into another language. (Hereinafter,
+% translation is included without limitation in the term ``modification''.)
+% Each licensee is addressed as ``you''.
+%
+% Activities other than copying, distribution and modification are not
+% covered by this License; they are outside its scope. The act of
+% running the Program is not restricted, and the output from the Program
+% is covered only if its contents constitute a work based on the
+% Program (independent of having been made by running the Program).
+% Whether that is true depends on what the Program does.
+%
+% \item You may copy and distribute verbatim copies of the Program's source
+% code as you receive it, in any medium, provided that you conspicuously
+% and appropriately publish on each copy an appropriate copyright notice
+% and disclaimer of warranty; keep intact all the notices that refer to
+% this License and to the absence of any warranty; and give any other
+% recipients of the Program a copy of this License along with the Program.
+%
+% You may charge a fee for the physical act of transferring a copy, and you
+% may at your option offer warranty protection in exchange for a fee.
+%
+% \item
+%
+% You may modify your copy or copies of the Program or any portion
+% of it, thus forming a work based on the Program, and copy and
+% distribute such modifications or work under the terms of Section~1
+% above, provided that you also meet all of these conditions:
+%
+% \begin{enumerate}
+%
+% \item
+%
+% You must cause the modified files to carry prominent notices stating that
+% you changed the files and the date of any change.
+%
+% \item
+%
+% You must cause any work that you distribute or publish, that in
+% whole or in part contains or is derived from the Program or any
+% part thereof, to be licensed as a whole at no charge to all third
+% parties under the terms of this License.
+%
+% \item
+% If the modified program normally reads commands interactively
+% when run, you must cause it, when started running for such
+% interactive use in the most ordinary way, to print or display an
+% announcement including an appropriate copyright notice and a
+% notice that there is no warranty (or else, saying that you provide
+% a warranty) and that users may redistribute the program under
+% these conditions, and telling the user how to view a copy of this
+% License. (Exception: if the Program itself is interactive but
+% does not normally print such an announcement, your work based on
+% the Program is not required to print an announcement.)
+%
+% \end{enumerate}
+%
+% These requirements apply to the modified work as a whole. If
+% identifiable sections of that work are not derived from the Program,
+% and can be reasonably considered independent and separate works in
+% themselves, then this License, and its terms, do not apply to those
+% sections when you distribute them as separate works. But when you
+% distribute the same sections as part of a whole which is a work based
+% on the Program, the distribution of the whole must be on the terms of
+% this License, whose permissions for other licensees extend to the
+% entire whole, and thus to each and every part regardless of who wrote it.
+%
+% Thus, it is not the intent of this section to claim rights or contest
+% your rights to work written entirely by you; rather, the intent is to
+% exercise the right to control the distribution of derivative or
+% collective works based on the Program.
+%
+% In addition, mere aggregation of another work not based on the Program
+% with the Program (or with a work based on the Program) on a volume of
+% a storage or distribution medium does not bring the other work under
+% the scope of this License.
+%
+% \item
+% You may copy and distribute the Program (or a work based on it,
+% under Section~2) in object code or executable form under the terms of
+% Sections~1 and~2 above provided that you also do one of the following:
+%
+% \begin{enumerate}
+%
+% \item
+%
+% Accompany it with the complete corresponding machine-readable
+% source code, which must be distributed under the terms of Sections~1
+% and~2 above on a medium customarily used for software interchange; or,
+%
+% \item
+%
+% Accompany it with a written offer, valid for at least three
+% years, to give any third party, for a charge no more than your
+% cost of physically performing source distribution, a complete
+% machine-readable copy of the corresponding source code, to be
+% distributed under the terms of Sections~1 and~2 above on a medium
+% customarily used for software interchange; or,
+%
+% \item
+%
+% Accompany it with the information you received as to the offer
+% to distribute corresponding source code. (This alternative is
+% allowed only for noncommercial distribution and only if you
+% received the program in object code or executable form with such
+% an offer, in accord with Subsection~b above.)
+%
+% \end{enumerate}
+%
+% The source code for a work means the preferred form of the work for
+% making modifications to it. For an executable work, complete source
+% code means all the source code for all modules it contains, plus any
+% associated interface definition files, plus the scripts used to
+% control compilation and installation of the executable. However, as a
+% special exception, the source code distributed need not include
+% anything that is normally distributed (in either source or binary
+% form) with the major components (compiler, kernel, and so on) of the
+% operating system on which the executable runs, unless that component
+% itself accompanies the executable.
+%
+% If distribution of executable or object code is made by offering
+% access to copy from a designated place, then offering equivalent
+% access to copy the source code from the same place counts as
+% distribution of the source code, even though third parties are not
+% compelled to copy the source along with the object code.
+%
+% \item
+% You may not copy, modify, sublicense, or distribute the Program
+% except as expressly provided under this License. Any attempt
+% otherwise to copy, modify, sublicense or distribute the Program is
+% void, and will automatically terminate your rights under this License.
+% However, parties who have received copies, or rights, from you under
+% this License will not have their licenses terminated so long as such
+% parties remain in full compliance.
+%
+% \item
+% You are not required to accept this License, since you have not
+% signed it. However, nothing else grants you permission to modify or
+% distribute the Program or its derivative works. These actions are
+% prohibited by law if you do not accept this License. Therefore, by
+% modifying or distributing the Program (or any work based on the
+% Program), you indicate your acceptance of this License to do so, and
+% all its terms and conditions for copying, distributing or modifying
+% the Program or works based on it.
+%
+% \item
+% Each time you redistribute the Program (or any work based on the
+% Program), the recipient automatically receives a license from the
+% original licensor to copy, distribute or modify the Program subject to
+% these terms and conditions. You may not impose any further
+% restrictions on the recipients' exercise of the rights granted herein.
+% You are not responsible for enforcing compliance by third parties to
+% this License.
+%
+% \item
+% If, as a consequence of a court judgment or allegation of patent
+% infringement or for any other reason (not limited to patent issues),
+% conditions are imposed on you (whether by court order, agreement or
+% otherwise) that contradict the conditions of this License, they do not
+% excuse you from the conditions of this License. If you cannot
+% distribute so as to satisfy simultaneously your obligations under this
+% License and any other pertinent obligations, then as a consequence you
+% may not distribute the Program at all. For example, if a patent
+% license would not permit royalty-free redistribution of the Program by
+% all those who receive copies directly or indirectly through you, then
+% the only way you could satisfy both it and this License would be to
+% refrain entirely from distribution of the Program.
+%
+% If any portion of this section is held invalid or unenforceable under
+% any particular circumstance, the balance of the section is intended to
+% apply and the section as a whole is intended to apply in other
+% circumstances.
+%
+% It is not the purpose of this section to induce you to infringe any
+% patents or other property right claims or to contest validity of any
+% such claims; this section has the sole purpose of protecting the
+% integrity of the free software distribution system, which is
+% implemented by public license practices. Many people have made
+% generous contributions to the wide range of software distributed
+% through that system in reliance on consistent application of that
+% system; it is up to the author/donor to decide if he or she is willing
+% to distribute software through any other system and a licensee cannot
+% impose that choice.
+%
+% This section is intended to make thoroughly clear what is believed to
+% be a consequence of the rest of this License.
+%
+% \item
+% If the distribution and/or use of the Program is restricted in
+% certain countries either by patents or by copyrighted interfaces, the
+% original copyright holder who places the Program under this License
+% may add an explicit geographical distribution limitation excluding
+% those countries, so that distribution is permitted only in or among
+% countries not thus excluded. In such case, this License incorporates
+% the limitation as if written in the body of this License.
+%
+% \item
+% The Free Software Foundation may publish revised and/or new versions
+% of the General Public License from time to time. Such new versions will
+% be similar in spirit to the present version, but may differ in detail to
+% address new problems or concerns.
+%
+% Each version is given a distinguishing version number. If the Program
+% specifies a version number of this License which applies to it and ``any
+% later version'', you have the option of following the terms and conditions
+% either of that version or of any later version published by the Free
+% Software Foundation. If the Program does not specify a version number of
+% this License, you may choose any version ever published by the Free Software
+% Foundation.
+%
+% \item
+% If you wish to incorporate parts of the Program into other free
+% programs whose distribution conditions are different, write to the author
+% to ask for permission. For software which is copyrighted by the Free
+% Software Foundation, write to the Free Software Foundation; we sometimes
+% make exceptions for this. Our decision will be guided by the two goals
+% of preserving the free status of all derivatives of our free software and
+% of promoting the sharing and reuse of software generally.
+%
+% \begin{center}
+% {\large\sc No Warranty}
+% \end{center}
+%
+% \item
+% {\sc Because the program is licensed free of charge, there is no warranty
+% for the program, to the extent permitted by applicable law. Except when
+% otherwise stated in writing the copyright holders and/or other parties
+% provide the program ``as is'' without warranty of any kind, either expressed
+% or implied, including, but not limited to, the implied warranties of
+% merchantability and fitness for a particular purpose. The entire risk as
+% to the quality and performance of the program is with you. Should the
+% program prove defective, you assume the cost of all necessary servicing,
+% repair or correction.}
+%
+% \item
+% {\sc In no event unless required by applicable law or agreed to in writing
+% will any copyright holder, or any other party who may modify and/or
+% redistribute the program as permitted above, be liable to you for damages,
+% including any general, special, incidental or consequential damages arising
+% out of the use or inability to use the program (including but not limited
+% to loss of data or data being rendered inaccurate or losses sustained by
+% you or third parties or a failure of the program to operate with any other
+% programs), even if such holder or other party has been advised of the
+% possibility of such damages.}
+%
+% \end{enumerate}
+%
+% \endgroup
+%
+% \StopEventually{\PrintIndex}
+%
+% \clearpage
+% \section{Implementation}
+%
+% The following provides the verbatim implementation of the \Songs{} \LaTeX{}
+% package, along with commentary on how it works.
+% In general, macro names that contain a |@| symbol are not intended to be
+% directly accessible by the outside world; they are for purely internal use.
+% All other macros are intended to be used or redefined by document authors.
+%
+% Most of the macros likely to be of real interest to song book authors can
+% be found in \S\ref{sec:impparams}.
+% To find the implementation of any particular macro, the index at the end
+% of this document should prove helpful.
+%
+% The unwary \TeX er may wonder at the rather large size of the
+% implementation.
+% The volume and complexity of the code stems mainly from the following
+% challenging features:
+% \begin{itemize}
+% \item Putting chords above lyrics fully automatically requires building an
+% entire lyric-parser in \LaTeX{} (see \S\ref{sec:lyricscan}).
+% \item Avoiding page-turns within songs without prohibiting column-breaks
+% requires building a completely new page-breaking algorithm
+% (see \S\ref{sec:pagebuilder}).
+% \item The package must be able to generate a daunting number of document
+% variants from a common source: lyric-only books, chorded books, digital
+% slides, transparency slides, selected song subsets, transposed songs, and
+% combinations of the above.
+% This is like putting six or more packages into one.
+% \item Song book indexes are far more complex than those for a prose book.
+% See \S\ref{sec:indexgen} for some of the difficulties involved.
+% \end{itemize}
+%
+% \subsection{Initialization}
+%
+% The code in this section detects any \TeX{} versioning or configuration
+% settings that are relevant to the rest of the song book code.
+%
+% \begin{macro}{\ifSB@etex}
+% Numerous enhancements are possible when using an $\varepsilon$-\TeX{}
+% compatible version of \LaTeX.
+% We start by checking to see whether $\varepsilon$-\TeX{} primitives are
+% available.
+% \begin{macrocode}
+\newif\ifSB@etex
+\ifx\eTeXversion\undefined\else
+ \ifx\eTeXversion\relax\else
+ \SB@etextrue
+ \ifx\e@alloc\@undefined
+ \IfFileExists{etex.sty}{\RequirePackage{etex}}{}
+ \fi
+ \fi
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@pdf}
+% Detect whether we're generating a pdf file, since this affects the
+% treatment of hyperlinks and bookmark indexes.
+% \begin{macrocode}
+\newif\ifSB@pdf\SB@pdffalse
+\IfFileExists{ifpdf.sty}{\RequirePackage{ifpdf}\ifpdf\SB@pdftrue\fi}{
+ \ifx\pdfoutput\undefined\else
+ \ifx\pdfoutput\relax\else
+ \ifnum\pdfoutput<\@ne\else
+ \SB@pdftrue
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@preamble}
+% Some macros have different effects depending on when they're used in the
+% preamble or in the document body, so we need a conditional that remembers
+% whether we're still in the preamble.
+% It gets initialized to true and later changed to false once the body begins.
+% \begin{macrocode}
+\newif\ifSB@preamble
+\SB@preambletrue
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@test}
+% \begin{macro}{\ifSB@testii}
+% \begin{macro}{\SB@temp}
+% \begin{macro}{\SB@tempii}
+% \begin{macro}{\SB@tempiii}
+% \begin{macro}{\SB@tempiv}
+% \begin{macro}{\SB@tempv}
+% Reserve some control sequence names for scratch use.
+% \begin{macrocode}
+\newif\ifSB@test
+\newif\ifSB@testii
+\newcommand\SB@temp{}
+\newcommand\SB@tempii{}
+\newcommand\SB@tempiii{}
+\newcommand\SB@tempiv{}
+\newcommand\SB@tempv{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@newcount}
+% \begin{macro}{\SB@newdimen}
+% \begin{macro}{\SB@newbox}
+% \begin{macro}{\SB@newtoks}
+% \begin{macro}{\SB@newwrite}
+% Create macros for safely allocating count, dimen, box, token, and write
+% registers with detection for name-clashes.
+% For some reason, the default allocation macros provided by the \LaTeX{}
+% kernel do not detect name-clashes(!), which means that packages that use them
+% might accidentally overwrite our registers, causing all sorts of problems.
+% But at least we can do our best to avoid overwriting their registers.
+% \begin{macrocode}
+\newcommand\SB@newcount[1]{\@ifdefinable#1{\newcount#1}}
+\newcommand\SB@newdimen[1]{\@ifdefinable#1{\newdimen#1}}
+\newcommand\SB@newbox[1]{\@ifdefinable#1{\newbox#1}}
+\newcommand\SB@newtoks[1]{\@ifdefinable#1{\newtoks#1}}
+\newcommand\SB@newwrite[1]{\@ifdefinable#1{\newwrite#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@dimen}
+% \begin{macro}{\SB@dimenii}
+% \begin{macro}{\SB@dimeniii}
+% \begin{macro}{\SB@dimeniv}
+% \begin{macro}{\SB@box}
+% \begin{macro}{\SB@boxii}
+% \begin{macro}{\SB@boxiii}
+% \begin{macro}{\SB@toks}
+% \begin{macro}{\SB@cnt}
+% \begin{macro}{\SB@cntii}
+% \begin{macro}{\SB@skip}
+% Reserve some temp registers for various purposes.
+% \begin{macrocode}
+\SB@newdimen\SB@dimen
+\SB@newdimen\SB@dimenii
+\SB@newdimen\SB@dimeniii
+\SB@newdimen\SB@dimeniv
+\SB@newbox\SB@box
+\SB@newbox\SB@boxii
+\SB@newbox\SB@boxiii
+\SB@newtoks\SB@toks
+\SB@newcount\SB@cnt
+\SB@newcount\SB@cntii
+\newlength\SB@skip
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@envbox}
+% Also reserve a slightly less volatile box register for per-environment use.
+% In scripture environments it holds the scripture citation.
+% In indexes it holds the index title text.
+% \begin{macrocode}
+\SB@newbox\SB@envbox
+% \end{macrocode}
+% \end{macro}
+%
+% Load David Carlisle's |keyval| package for processing
+% \Meta{key}=\Meta{value} style macro arguments.
+% \begin{macrocode}
+\RequirePackage{keyval}
+% \end{macrocode}
+%
+% \begin{macro}{\SB@app}
+% Utility macro: Append some text to the definition of another macro.
+% \begin{macrocode}
+\newcommand\SB@app[3]{%
+ \expandafter#1\expandafter#2\expandafter{#2#3}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Default Parameters}\label{sec:impparams}
+%
+% This section defines macros and lengths that will typically be executed or
+% redefined by the user in the document preamble to initialize the document.
+% (Not all of these are restricted to preamble usage, however. Many can be used
+% throughout the document to switch styles for different sections or different
+% songs.)
+%
+% \begin{macro}{\lyricfont}\MainImpl{lyricfont}
+% Define the font style to use for formatting song lyrics.
+% \begin{macrocode}
+\newcommand\lyricfont{\normalfont\normalsize}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\stitlefont}\MainImpl{stitlefont}
+% Define the font style to use for formatting song titles.
+% \begin{macrocode}
+\newcommand\stitlefont{%
+ \sffamily\ifslides\Huge\else\slshape\Large\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\versefont}\MainImpl{versefont}
+% \begin{macro}{\chorusfont}\MainImpl{chorusfont}
+% \begin{macro}{\notefont}\MainImpl{notefont}
+% \begin{macro}{\meterfont}\MainImpl{meterfont}
+% \changes{v2.1}{2007/08/02}{Added}
+% By default, verses, choruses, and textual notes just allow the |\lyricfont|
+% style to continue.
+% Meter numbers are in tiny, sans-serif, upright font.
+% Echo parts toggle slanted and upright fonts.
+% \begin{macrocode}
+\newcommand\versefont{}
+\newcommand\chorusfont{}
+\newcommand\notefont{}
+\newcommand\meterfont{\tiny\sffamily\upshape}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\echofont}\MainImpl{echofont}
+% \changes{v2.18}{2014/06/28}{Added}
+% Echo parts toggle between oblique and upright shapes like |\emph|, but we
+% use |\slshape| instead of |\itshape| because it tends to look nicer with the
+% larger fonts used in slides mode.
+% \begin{macrocode}
+\newcommand\echofont{%
+ \ifdim\fontdimen\@ne\font>\z@\upshape\else\slshape\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\scripturefont}\MainImpl{scripturefont}
+% \changes{v1.13}{2005/05/12}{Added kerning correction for double-quote ligatures}
+% Define the font style to use for formatting scripture quotations
+% (defaults to Zapf Chancery).
+% \begin{macrocode}
+\newcommand\scripturefont{%
+ \usefont{OT1}{pzc}{mb}{it}%
+ \shiftdblquotes{-1.1\p@}\z@{-2\p@}\z@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\printscrcite}\MainImpl{printscrcite}
+% Define the printing style for the citation at the end of a scripture
+% quotation.
+% \begin{macrocode}
+\newcommand\printscrcite[1]{\sffamily\small#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\snumbgcolor}\MainImpl{snumbgcolor}
+% \begin{macro}{\notebgcolor}\MainImpl{notebgcolor}
+% \begin{macro}{\idxbgcolor}\MainImpl{idxbgcolor}
+% Define the background color used for shaded boxes containing
+% song numbers, textual notes, and index section headers, respectively.
+% To turn off all shading for a box type, use |\def|\Meta{macroname}|{}|.
+% \begin{macrocode}
+\newcommand\snumbgcolor{SongbookShade}
+\newcommand\notebgcolor{SongbookShade}
+\newcommand\idxbgcolor{SongbookShade}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\versejustify}\MainImpl{versejustify}
+% \begin{macro}{\chorusjustify}\MainImpl{chorusjustify}
+% \changes{v2.1}{2007/08/02}{Added}
+% Verses and choruses are both left-justified with hanging indentation equal
+% to |\parindent|.
+% \begin{macrocode}
+\newcommand\versejustify{\justifyleft}
+\newcommand\chorusjustify{\justifyleft}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\notejustify}\MainImpl{notejustify}
+% \changes{v2.1}{2007/08/02}{Added}
+% Textual notes are fully justified when they are too long to fit in
+% a single line.
+% \begin{macrocode}
+\newcommand\notejustify{%
+ \advance\baselineskip\p@\relax%
+ \leftskip\z@skip\rightskip\z@skip%
+ \parfillskip\@flushglue\parindent\z@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\placenote}\MainImpl{placenote}
+% \changes{v2.1}{2007/08/02}{Added}
+% Textual notes are placed flush-left.
+% The single argument to this macro is horizontal material that comprises the
+% note.
+% Usually it will consist of various hboxes and specials that were produced
+% by |\colorbox|.
+% \begin{macrocode}
+\newcommand\placenote[1]{%
+ \leftskip\z@skip\rightskip\@flushglue\SB@cbarshift%
+ \noindent#1\par%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% These counters define the current song number and verse number.
+% They can be redefined by the user at any time.
+% \begin{macrocode}
+\newcounter{songnum}
+\newcounter{versenum}
+% \end{macrocode}
+%
+% \begin{macro}{\thesongnum}\MainImpl{thesongnum}
+% \begin{macro}{\songnumstyle}
+% By default, the song numbering style will simply be an arabic number.
+% Redefine |\thesongnum| to change it.
+% (The |\songnumstyle| macro is obsolete and exists only for backward
+% compatibility.)
+% \begin{macrocode}
+\renewcommand\thesongnum{\songnumstyle{songnum}}
+\newcommand\songnumstyle{}
+\let\songnumstyle\arabic
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\theversenum}\MainImpl{theversenum}
+% \begin{macro}{\versenumstyle}
+% By default, the verse numbering style will simply be an arabic number.
+% Redefine |\theversenum| to change it.
+% (The |\versenumstyle| macro is obsolete and exists only for backward
+% compatibility.)
+% \begin{macrocode}
+\renewcommand\theversenum{\versenumstyle{versenum}}
+\newcommand\versenumstyle{}
+\let\versenumstyle\arabic
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\printsongnum}\MainImpl{printsongnum}
+% Define the printing style for the large, boxed song numbers starting each
+% song.
+% \begin{macrocode}
+\newcommand\printsongnum[1]{\sffamily\bfseries\LARGE#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\printversenum}\MainImpl{printversenum}
+% Define the printing style for the verse numbers to the left of each verse.
+% \begin{macrocode}
+\newcommand\printversenum[1]{\lyricfont#1.\ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\placeversenum}\MainImpl{placeversenum}
+% \changes{v2.1}{2007/08/02}{Added}
+% Verse numbers are placed flush-left.
+% This is achieved by inserting horizontal glue that reverses both the
+% |\leftskip| and the |\parindent|.
+% The single argument to this macro is an hbox containing the verse number.
+% \begin{macrocode}
+\newcommand\placeversenum[1]{%
+ \hskip-\leftskip\hskip-\parindent\relax%
+ \box#1%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\everyverse}\MainImpl{everyverse}
+% \begin{macro}{\everychorus}\MainImpl{everychorus}
+% \changes{v2.1}{2007/08/02}{Added}
+% The following hooks allow users to insert material at the head of each
+% verse or chorus.
+% \begin{macrocode}
+\newcommand\everyverse{}
+\newcommand\everychorus{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\printchord}\MainImpl{printchord}
+% Define the printing style for chords.
+% \begin{macrocode}
+\newcommand\printchord[1]{\sffamily\slshape\large#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\chordlocals}\MainImpl{chordlocals}
+% \label{sec:chordlocals}
+% This hook is expanded at the start of the scoping group that surrounds
+% every chord name.
+% Thus, it can be used to set any catcodes or definitions that should be
+% local to chord names.
+% \begin{macrocode}
+\newcommand\chordlocals{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\versesep}\MainImpl{versesep}
+% Specify the vertical distance between song verses.
+% This gets set to a sentinel value by default; if the user doesn't redefine
+% it by the end of the document preamble, it gets redefined to something
+% sensible based on other settings.
+% \begin{macrocode}
+\newlength\versesep
+\versesep123456789sp\relax
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\afterpreludeskip}\MainImpl{afterpreludeskip}
+% \begin{macro}{\beforepostludeskip}\MainImpl{beforepostludeskip}
+% Users can specify the amount of vertical space that separates song prelude
+% and postlude material from the body of the song by adjusting the following
+% two macros.
+% \begin{macrocode}
+\newlength\afterpreludeskip
+\afterpreludeskip=2\p@\@plus4\p@
+\newlength\beforepostludeskip
+\beforepostludeskip=2\p@\@plus4\p@
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\baselineadj}\MainImpl{baselineadj}
+% Define an adjustment factor for the vertical distance between consecutive
+% lyric baselines.
+% Setting this to zero accepts the default baseline distance computed by the
+% songs package.
+% \begin{macrocode}
+\newlength\baselineadj
+\baselineadj\z@skip
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clineparams}\MainImpl{clineparams}
+% The spacing between chords and the lyrics below them can be adjusted
+% by changing the values of |\baselineskip|, |\lineskiplimit|, and
+% |\lineskip| within the following macro.
+% By default, |\baselineskip| is set to 2 points smaller than the height
+% of the current (lyric) font, and |\lineskiplimit| and |\lineskip| are
+% set so that chords intrude at most 2 points into the lyric below them.
+% This helps to keep chords tight with lyrics.
+% \begin{macrocode}
+\newcommand\clineparams{%
+ \baselineskip\f@size\p@%
+ \advance\baselineskip-2\p@%
+ \lineskiplimit-2\p@%
+ \lineskip-2\p@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\parindent}
+% The |\parindent| length controls how far broken lyric lines are
+% indented from the left margin.
+% \begin{macrocode}
+\parindent.25in
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxheadwidth}\MainImpl{idxheadwidth}
+% Specify the width of the head-boxes in a large index.
+% \begin{macrocode}
+\newlength\idxheadwidth
+\setlength\idxheadwidth{1.5cm}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\songnumwidth}\MainImpl{songnumwidth}
+% Set the width of the song number boxes that begin each song.
+% We guess a suitable width by typesetting the text ``999.''
+% \begin{macrocode}
+\newlength\songnumwidth
+\settowidth\songnumwidth{\printsongnum{999.}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\versenumwidth}\MainImpl{versenumwidth}
+% Set the width that is reserved for normal-sized verse numbers.
+% (Verse numbers wider than this will indent the first line of lyrics.)
+% \begin{macrocode}
+\newlength\versenumwidth
+\settowidth\versenumwidth{\printversenum{9\kern1em}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cbarwidth}
+% This dictates the width of the vertical line placed to the left of
+% choruses.
+% Setting it to |0pt| eliminates the line entirely.
+% \begin{macrocode}
+\newlength\cbarwidth
+\setlength\cbarwidth\p@
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sbarheight}
+% This dictates the height of the horizontal line placed between each pair
+% of songs.
+% Setting it to |0pt| eliminates the line entirely.
+% \begin{macrocode}
+\newlength\sbarheight
+\setlength\sbarheight\p@
+% \end{macrocode}
+% \end{macro}
+%
+% Column- and page-breaks should typically not occur within a verse or chorus
+% unless they are unavoidable.
+% Thus, we set the |\interlinepenalty| to a high number (1000).
+% \begin{macrocode}
+\interlinepenalty\@m
+% \end{macrocode}
+%
+% \begin{macro}{\vvpenalty}\MainImpl{vvpenalty}
+% \begin{macro}{\ccpenalty}\MainImpl{ccpenalty}
+% \begin{macro}{\vcpenalty}\MainImpl{vcpenalty}
+% \begin{macro}{\cvpenalty}\MainImpl{cvpenalty}
+% \begin{macro}{\brkpenalty}\MainImpl{brkpenalty}
+% \changes{v2.1}{2007/08/02}{Added.}
+% The following count registers define the line-breaking penalties inserted
+% between verses, between choruses, after a verse followed by a chorus, after
+% a chorus followed by a verse, and at |\brk| macros, respectively.
+%
+% The default value of 200 was chosen based on the following logic:
+% Chord books should not yield underfull vbox warnings no matter how short
+% their columns are.
+% However, we still want to put as much material in each column as possible
+% while avoiding intra-song column-breaks when they can be avoided.
+% Chorded mode therefore sets |\colbotglue| with glue whose stretchability
+% is half of the |\textheight|.
+% Such glue will stretch at most twice its stretchability, yielding a
+% badness of 800 in the worst case.
+% The default |\vbadness| setting starts issuing warnings at badness 1000,
+% so we set the penalties below to $1000-800=200$.
+% \begin{macrocode}
+\SB@newcount\vvpenalty\vvpenalty200
+\SB@newcount\ccpenalty\ccpenalty200
+\SB@newcount\vcpenalty\vcpenalty200
+\SB@newcount\cvpenalty\cvpenalty200
+\SB@newcount\brkpenalty\brkpenalty200
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\spenalty}\MainImpl{spenalty}
+% \changes{v2.1}{2007/08/02}{Added.}
+% The following penalty gets inserted between songs.
+% Setting it to a proper value is a somewhat delicate balancing act.
+% It should typically be something between 0 and the default penalties above,
+% so for now it defaults to 100.
+% To start each song on a fresh column/page, set it to $-10000$ or below.
+% \begin{macrocode}
+\SB@newcount\spenalty\spenalty100
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\songmark}\MainImpl{songmark}
+% \changes{v1.17}{2005/09/24}{Added.}
+% \begin{macro}{\versemark}\MainImpl{versemark}
+% \begin{macro}{\chorusmark}\MainImpl{chorusmark}
+% \changes{v2.1}{2007/08/02}{Added.}
+% The user can redefine the following macros to add \TeX{} marks for each
+% song, each verse, or each chorus.
+% Such marks are used by \LaTeX{} to define page headers and footers.
+% \begin{macrocode}
+\newcommand\songmark{}
+\newcommand\versemark{}
+\newcommand\chorusmark{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\extendprelude}\MainImpl{extendprelude}
+% \begin{macro}{\extendpostlude}\MainImpl{extendpostlude}
+% \changes{v2.0}{2007/06/18}{Added.}
+% To just add some fields to the existing |\makeprelude| or |\makepostlude|
+% without having to redefine them entirely, users can redefine
+% |\extendprelude| or |\extendpostlude|.
+% By default, the prelude has the scripture references followed by the
+% authors, and the postlude has the copyright info followed by the licensing
+% info.
+% \begin{macrocode}
+\newcommand\extendprelude{\showrefs\showauthors}
+\newcommand\extendpostlude{\songcopyright\ \songlicense\unskip}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\idxheadfont}\MainImpl{idxheadfont}
+% \changes{v2.8}{2009/02/22}{Added.}
+% Users can redefine |\idxheadfont| to affect the font in which each capital
+% letter that heads a section of a title index is rendered.
+% \begin{macrocode}
+\newcommand\idxheadfont{\sffamily\bfseries\LARGE}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxtitlefont}\MainImpl{idxtitlefont}
+% \changes{v2.8}{2009/02/22}{Added.}
+% Users can redefine |\idxtitlefont| to affect the font in which song title
+% index entries are rendered.
+% \begin{macrocode}
+\newcommand\idxtitlefont{\sffamily\slshape}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxlyricfont}\MainImpl{idxlyricfont}
+% \changes{v2.8}{2009/02/22}{Added.}
+% Users can redefine |\idxlyricfont| to affect the font in which notable lines
+% of lyrics are rendered in a title index.
+% \begin{macrocode}
+\newcommand\idxlyricfont{\rmfamily}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxscripfont}\MainImpl{idxscripfont}
+% \changes{v2.8}{2009/02/22}{Added.}
+% Users can redefine |\idxscripfont| to affect the font in which scripture
+% references are rendered in a scripture index.
+% \begin{macrocode}
+\newcommand\idxscripfont{\sffamily\small\slshape}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxauthfont}\MainImpl{idxauthfont}
+% \changes{v2.8}{2009/02/22}{Added.}
+% Users can redefine |\idxauthfont| to affect the font in which contributor
+% names are rendered in an author index.
+% \begin{macrocode}
+\newcommand\idxauthfont{\small\bfseries}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxrefsfont}\MainImpl{idxrefsfont}
+% \changes{v2.8}{2009/02/22}{Added.}
+% Users can redefine |\idxrefsfont| to affect the font in which the list of
+% song references on the right-hand-side of an index entry is typeset.
+% \begin{macrocode}
+\newcommand\idxrefsfont{\normalfont\normalsize}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxbook}\MainImpl{idxbook}
+% \changes{v2.8}{2009/02/22}{Added.}
+% Users can redefine |\idxbook| to dictate the book name header in a
+% scripture index that begins each book of the bible.
+% \begin{macrocode}
+\newcommand\idxbook[1]{\small\bfseries#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\idxcont}\MainImpl{idxcont}
+% \changes{v2.0}{2007/06/18}{Added.}
+% Users can redefine |\idxcont| to dictate the column header in a scripture
+% index after a column break falls within a book of the bible.
+% \begin{macrocode}
+\newcommand\idxcont[1]{\small\textbf{#1} (continued)}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\colbotglue}
+% Glue of size |\colbotglue| is inserted at the bottom of each column.
+% We use a macro instead of a glue register so that this can be redefined
+% in terms of variable quantities such as |\textheight|.
+% \begin{macrocode}
+\newcommand\colbotglue{}
+\let\colbotglue\z@skip
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\lastcolglue}
+% Glue of size |\lastcolglue| is inserted at the bottom of the last column.
+% \begin{macrocode}
+\newcommand\lastcolglue{}
+\let\lastcolglue\@flushglue
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\minfrets}
+% Define the minimum number of fret rows that should appear in tablature
+% diagrams.
+% \begin{macrocode}
+\SB@newcount\minfrets\minfrets4
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@colwidth}
+% Define a length to store the computed width of each column in a
+% multi-column song page.
+% The user shouldn't set this one directly, but some users might want to
+% refer to it in calculations.
+% \begin{macrocode}
+\SB@newdimen\SB@colwidth
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Package Options}
+%
+% This section defines code associated with the various option
+% settings that can be specified on the |\usepackage| line.
+% Many of these options can also be turned on or off subsequent to the
+% |\usepackage| line, so macros for doing that are also located here.
+% The options are not actually processed until \S\ref{sec:optproc} because
+% some of the macros defined here refer to macros that have not yet been
+% defined.
+%
+% \begin{option}{slides}\MainEnvImpl{slides}
+% \begin{macro}{\slides}\MainImpl{slides}
+% \optdef{off}
+% Turning this option on generates a book of overhead slides---one for each
+% song.
+% It really just amounts to changing various parameter settings.
+% Elsewhere in the code we also consult |\ifslides| to determine a few default
+% parameter settings and to use a different song preamble structure.
+% All the parameter changes below are local to the current scope; so to
+% undo slides mode, just put |\slides| within a group and end the group
+% wherever you want the slides settings to end.
+% \begin{macrocode}
+\DeclareOption{slides}{\slides}
+\newcommand\slides{%
+ \slidestrue%
+ \def\lyricfont{\normalfont\huge}%
+ \def\chorusfont{\slshape}%
+ \def\versejustify{\justifycenter}%
+ \let\chorusjustify\versejustify
+ \def\placenote##1{\justifycenter\noindent##1\par}%
+ \scriptureoff%
+ \onesongcolumn%
+ \ifSB@preamble\ifSB@chordedspec\else\SB@chordsoff\fi\fi%
+ \spenalty-\@M%
+ \let\colbotglue\@flushglue%
+ \setlength\cbarwidth\z@%
+ \setlength\sbarheight\z@%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{option}
+%
+% \begin{macro}{\justifyleft}
+% \changes{v2.1}{2007/08/02}{Added}
+% The |\justifyleft| macro sets up an environment in which lyrics are
+% left-justified with hanging indentation equal to |\parindent|.
+% It reserves spaces for verse numbers if used in a verse, and reserves
+% space for the vertical bar left of choruses if used in a chorus.
+% \begin{macrocode}
+\newcommand\justifyleft{%
+ \leftskip\parindent%
+ \ifSB@inverse\advance\leftskip\versenumwidth\fi%
+ \SB@cbarshift%
+ \parindent-\parindent%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\justifycenter}
+% \changes{v2.1}{2007/08/02}{Added}
+% The |\justifycenter| macro sets up an environment in which lyrics are
+% centered on each line.
+% Verse numbers continue to be placed flush-left, but |\placeversenum|
+% is temporarily redefined to keep the rest of the line containing a
+% verse number centered.
+% \begin{macrocode}
+\newcommand\justifycenter{%
+ \centering\SB@cbarshift\rightskip\leftskip%
+ \def\placeversenum##1{%
+ \hskip-\leftskip\hskip-\parindent\relax%
+ \hangindent-\wd##1\hangafter\m@ne%
+ \box##1\hfil%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{option}{unouter}\MainEnvImpl{unouter}
+% \begin{macro}{\SB@outer}
+% \optdef{off}
+% Several macros provided by the \Songs{} package are, by default, declared
+% |\outer| to aid in debugging.
+% However, unusual documents may need to use these macros within larger
+% constructs.
+% To do so, use the |unouter| option to prevent any of the macros supplied
+% by this package from being declared |\outer|.
+% \begin{macrocode}
+\newcommand\SB@outer{\outer}
+\DeclareOption{unouter}{\let\SB@outer\relax}
+% \end{macrocode}
+% \end{macro}
+% \end{option}
+%
+% \begin{option}{rawtext}\MainEnvImpl{rawtext}
+% \optdef{off}
+% Instead of generating a document, this dumps a text version of the song book
+% to a file. This option can only be set in the |\usepackage| line because
+% it dictates many top-level macro definitions. Turning rawtext on turns off
+% the indexes by default, but this can be overridden by explicitly setting
+% index options. (Note: Using rawtext with indexes turned on doesn't actually
+% work yet, but might be added in a future revision.)
+% \begin{macrocode}
+\DeclareOption{rawtext}{\rawtexttrue\indexesoff}
+% \end{macrocode}
+% \end{option}
+%
+% \begin{option}{noshading}\MainEnvImpl{noshading}
+% \optdef{off}
+% Inhibit all shaded boxes (e.g., if the color package is unavailable).
+% This option can only be set in the |\usepackage| line because the color
+% package must be loaded in the preamble if at all. (Note: In a future release
+% this might be extended to be modifiable throughout the preamble.)
+% \begin{macrocode}
+\DeclareOption{noshading}{\SB@colorboxesfalse}
+% \end{macrocode}
+% \end{option}
+%
+% \begin{option}{noindexes}\MainEnvImpl{noindexes}
+% \begin{macro}{\indexeson}\MainImpl{indexeson}
+% \begin{macro}{\indexesoff}\MainImpl{indexesoff}
+% \optdef{off}
+% Suppress generation of index files and displaying of in-document indexes.
+% The |\indexeson| and |\indexesoff| macros can be used elsewhere to toggle
+% display of indexes.
+% Index-regeneration will occur if indexes are turned on by the end of the
+% document.
+% \begin{macrocode}
+\DeclareOption{noindexes}{\indexesoff}
+\newcommand\indexeson{\songindexestrue}
+\newcommand\indexesoff{\songindexesfalse}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{option}
+%
+% \begin{option}{nopdfindex}\MainEnvImpl{nopdfindex}
+% \optdef{off}
+% Suppress creation of PDF bookmark entries and hyperlinks.
+% \begin{macrocode}
+\DeclareOption{nopdfindex}{%
+ \let\songtarget\@gobbletwo%
+ \let\songlink\@secondoftwo%
+}
+% \end{macrocode}
+% \end{option}
+%
+% \begin{macro}{\ifSB@measurespec}
+% \begin{macro}{\ifSB@chordedspec}
+% The |showmeasures| and |chorded| options interact in the sense that by
+% default, switching one of them on or off switches the other on or off as
+% well.
+% However, if the user explicitly says that one should be on or off, then
+% switching the other shouldn't affect it.
+% To produce this behavior, we need two extra conditionals to remember whether
+% each of these options has been explicitly specified by the user or whether
+% it is still in a default state.
+% \begin{macrocode}
+\newif\ifSB@measurespec
+\newif\ifSB@chordedspec
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{option}{chorded}\MainEnvImpl{chorded}
+% \begin{option}{lyric}\MainEnvImpl{lyric}
+% \begin{macro}{\chordson}\MainImpl{chordson}
+% \begin{macro}{\chordsoff}\MainImpl{chordsoff}
+% \begin{macro}{\SB@chordson}
+% \begin{macro}{\SB@chordsoff}
+% \changes{v1.22}{2007/05/15}{Update \cs{baselineskip} when in songs.}
+% \optdef{chorded}
+% Determines whether chords should be shown.
+% This option can be set in the |\usepackage| line or toggled elsewhere
+% with the |\chordson| and |\chordsoff| macros.
+% Chords cannot be turned on in conjunction with the |rawtext| option.
+% If chords are turned on by the end of the preamble, no attempt will be made
+% to balance columns on each page.
+% \begin{macrocode}
+\DeclareOption{chorded}{\chordson}
+\DeclareOption{lyric}{\chordsoff}
+\newcommand\chordson{\SB@chordedspectrue\SB@chordson}
+\newcommand\chordsoff{\SB@chordedspectrue\SB@chordsoff}
+\newcommand\SB@chordson{%
+ \ifrawtext%
+ \SB@errrtopt%
+ \else%
+ \chordedtrue\lyricfalse%
+ \let\SB@bracket\SB@chord%
+ \let\SB@rechord\SB@@rechord%
+ \let\SB@ch\SB@ch@on%
+ \ifSB@measurespec%
+ \ifmeasures\SB@measureson\else\SB@measuresoff\fi%
+ \else%
+ \SB@measureson%
+ \fi%
+ \ifSB@preamble\def\colbotglue{\z@\@plus.5\textheight}\fi%
+ \SB@setbaselineskip%
+ \fi%
+}
+\newcommand\SB@chordsoff{%
+ \chordedfalse\lyrictrue%
+ \def\SB@bracket##1]{\ignorespaces}%
+ \let\SB@rechord\relax%
+ \let\SB@ch\SB@ch@off%
+ \ifSB@measurespec%
+ \ifmeasures\SB@measureson\else\SB@measuresoff\fi%
+ \else%
+ \SB@measuresoff%
+ \fi%
+ \ifSB@preamble\let\colbotglue\z@skip\fi%
+ \SB@setbaselineskip%
+}
+% \end{macrocode}
+% \eat\]
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{option}
+% \end{option}
+%
+% \begin{option}{showmeasures}\MainEnvImpl{showmeasures}
+% \begin{option}{nomeasures}\MainEnvImpl{nomeasures}
+% \begin{macro}{\measureson}\MainImpl{measureson}
+% \begin{macro}{\measuresoff}\MainImpl{measuresoff}
+% \begin{macro}{\SB@measureson}
+% \begin{macro}{\SB@measuresoff}
+% \optdef{showmeasures if chorded, nomeasures otherwise}
+% Determines whether measure bars and meter notes should be shown.
+% Option can be set in the |\usepackage| line or toggled elsewhere with the
+% |\measureson| and |\measuresoff| macros.
+% \begin{macrocode}
+\DeclareOption{showmeasures}{\measureson}
+\DeclareOption{nomeasures}{\measuresoff}
+\newcommand\measureson{\SB@measurespectrue\SB@measureson}
+\newcommand\measuresoff{\SB@measurespectrue\SB@measuresoff}
+\newcommand\SB@measureson{%
+ \measurestrue%
+ \let\SB@mbar\SB@makembar%
+ \ifchorded%
+ \let\SB@mch\SB@mch@on%
+ \else%
+ \let\SB@mch\SB@mch@m%
+ \fi%
+ \ifSB@inverse\SB@loadactives\fi%
+ \ifSB@inchorus\SB@loadactives\fi%
+}
+\newcommand\SB@measuresoff{%
+ \measuresfalse%
+ \let\SB@mbar\@gobbletwo%
+ \ifchorded%
+ \let\SB@mch\SB@ch@on%
+ \else%
+ \let\SB@mch\SB@ch@off%
+ \fi%
+ \ifSB@inverse\SB@loadactives\fi%
+ \ifSB@inchorus\SB@loadactives\fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{option}
+% \end{option}
+%
+% \begin{option}{transposecapos}\MainEnvImpl{transposecapos}
+% \optdef{off}
+% If set, the |\capo| macro transposes the song instead of printing a note
+% to use a capo. Use this option to generate a chord book for pianists who
+% have trouble transposing or guitarists who don't have capos.
+% \begin{macrocode}
+\DeclareOption{transposecapos}{\transcapostrue}
+% \end{macrocode}
+% \end{option}
+%
+% \begin{option}{noscripture}\MainEnvImpl{noscripture}
+% \begin{macro}{\scriptureon}\MainImpl{scriptureon}
+% \begin{macro}{\scriptureoff}\MainImpl{scriptureoff}
+% \optdef{off}
+% Inhibits the display of scripture quotes.
+% This option can also be toggled on and off anywhere with the |\sciptureon|
+% and |\scriptureoff| macros.
+% \begin{macrocode}
+\DeclareOption{noscripture}{\SB@omitscriptrue}
+\newcommand\scriptureon{\SB@omitscripfalse}
+\newcommand\scriptureoff{\SB@omitscriptrue}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{option}
+%
+% \begin{option}{onesongcolumn}\MainEnvImpl{onesongcolumn}
+% \begin{option}{twosongcolumns}\MainEnvImpl{twosongcolumns}
+% \begin{macro}{\onesongcolumn}\MainImpl{onesongcolumn}
+% \begin{macro}{\twosongcolumns}\MainImpl{twosongcolumns}
+% \begin{macro}{\songcolumns}\MainImpl{songcolumns}
+% \optdef{onesongcolumn is the default if generating slides or rawtext, twosongcolumns otherwise}
+% The number of columns per page is specified using the following package
+% options and macros.
+% In \env{rawtext} mode it must remain set to one column per page.
+% The entire page-making system can be turned off by setting the number of
+% columns to zero.
+% This will cause each song to be contributed to the current vertical list
+% without any attempt to form columns; the enclosing environment must handle
+% the page layout.
+% Probably this means that |\repchoruses| will not work, since an external
+% package won't know to insert repeated choruses when building pages.
+% \begin{macrocode}
+\DeclareOption{twosongcolumns}{\SB@numcols\tw@}
+\DeclareOption{onesongcolumn}{\SB@numcols\@ne}
+\newcommand\songcolumns[1]{%
+ \SB@cnt#1\relax%
+ \ifnum\SB@cnt=\SB@numcols\else%
+ \ifSB@preamble\else{\SB@clearpage}\fi%
+ \fi%
+ \SB@numcols\SB@cnt%
+ \ifnum\SB@numcols>\z@%
+ \SB@colwidth-\columnsep%
+ \multiply\SB@colwidth\SB@numcols%
+ \advance\SB@colwidth\columnsep%
+ \advance\SB@colwidth\textwidth%
+ \divide\SB@colwidth\SB@numcols%
+ \else%
+ \ifrepchorus\SB@warnrc\fi%
+ \fi%
+}
+\newcommand\onesongcolumn{\songcolumns\@ne}
+\newcommand\twosongcolumns{\songcolumns\tw@}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{option}
+% \end{option}
+%
+% \begin{macro}{\includeonlysongs}\MainImpl{includeonlysongs}
+% \begin{macro}{\songlist}
+% Display only a select list of songs and ignore the rest.
+% \begin{macrocode}
+\newcommand\songlist{}
+\newcommand\includeonlysongs[1]{%
+ \ifSB@songsenv\SB@errpl\else%
+ \partiallisttrue%
+ \renewcommand\songlist{#1}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\nosongnumbers}\MainImpl{nosongnumbers}
+% \changes{v2.9}{2009/04/01}{Added.}
+% The user can turn off song numbering with the following macro.
+% \begin{macrocode}
+\newcommand\nosongnumbers{\setlength\songnumwidth\z@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\noversenumbers}\MainImpl{noversenumbers}
+% \changes{v1.20}{2006/03/12}{Added.}
+% The user can turn off verse numbering with the following macro.
+% \begin{macrocode}
+\newcommand\noversenumbers{%
+ \renewcommand\printversenum[1]{}%
+ \setlength\versenumwidth\z@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\repchoruses}\MainImpl{repchoruses}
+% \begin{macro}{\norepchoruses}\MainImpl{norepchoruses}
+% \changes{v2.1}{2007/08/02}{Added.}
+% Using |\repchoruses| causes choruses to be automatically repeated on
+% subsequent pages of the song.
+% The feature requires $\varepsilon$-\TeX{} because the supporting code needs
+% an extended mark register class.
+% \begin{macrocode}
+\ifSB@etex
+ \newcommand\repchoruses{%
+ \ifnum\SB@numcols<\@ne\SB@warnrc\fi%
+ \repchorustrue%
+ }
+\else
+ \newcommand\repchoruses{\SB@erretex}
+\fi
+\newcommand\norepchoruses{\repchorusfalse}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\sepverses}
+% The following penalty settings cause verses and choruses to be separated
+% onto different slides when in slides mode, except that consecutive choruses
+% remain together when they fit.
+% \begin{macrocode}
+\newcommand\sepverses{%
+ \vvpenalty-\@M%
+ \ccpenalty100 %
+ \vcpenalty\vvpenalty%
+ \cvpenalty\vvpenalty%
+ \let\colbotglue\@flushglue%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Some option settings, margins, and other lengths are finalized at the end of
+% the preamble.
+% That code is below.
+%
+% \begin{macrocode}
+\AtBeginDocument{
+% \end{macrocode}
+%
+% If the user hasn't set the |\versesep|, set it to the default.
+% \begin{macrocode}
+ \SB@setversesep
+% \end{macrocode}
+%
+% Initialize page layout algorithm.
+% \begin{macrocode}
+ \songcolumns\SB@numcols
+% \end{macrocode}
+%
+% Macros used after this point occur outside the preamble.
+% \begin{macrocode}
+ \SB@preamblefalse
+}
+% \end{macrocode}
+%
+% \subsection{Page-builder}
+% \label{sec:pagebuilder}
+%
+% The following macros handle the building of pages that contain songs.
+% They compute where best to place each song (e.g., whether to place it in the
+% current column or move to the next column or page).
+% The output routines for generating a partial list of songs in a specified
+% order also can be found here.
+%
+% \begin{macro}{\SB@songbox}
+% The most recently processed song (or scripture quotation) is stored in this
+% box.
+% \begin{macrocode}
+\SB@newbox\SB@songbox
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@numcols}
+% \begin{macro}{\SB@colnum}
+% Reserve two count registers to hold the total number of columns and the
+% current column number, respectively.
+% \begin{macrocode}
+\SB@newcount\SB@numcols\SB@numcols\tw@
+\SB@newcount\SB@colnum
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@colbox}
+% Reserve a box register to hold the current column in progress.
+% \begin{macrocode}
+\SB@newbox\SB@colbox
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@pgbox}
+% Reserve a box register to hold the current page in progress.
+% \begin{macrocode}
+\SB@newbox\SB@pgbox
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@mrkbox}
+% Reserve a box register to hold marks that migrate out of songs as they
+% get split into columns and pages.
+% \begin{macrocode}
+\SB@newbox\SB@mrkbox
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@maxmin}
+% The following helper macro takes the max or min of two dimensions.
+% If \argp{2}=``|<|'', it sets \argp{1} to the maximum of \argp{1} and
+% \argp{3}.
+% If \argp{2}=``|>|'', it sets \argp{1} to the minimum of \argp{1} and
+% \argp{3}.
+% \begin{macrocode}
+\newcommand\SB@maxmin[3]{\ifdim#1#2#3#1#3\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@mkpage}
+% The following macro is the heart of the page-building engine.
+% It splits the contents of a box into a page of columns.
+% If |\repchoruses| is active, the contents of |\SB@chorusbox|
+% are additionally inserted into fresh columns created during the spitting
+% process.
+% The macro arguments are:
+% \begin{enumerate}
+% \item an integer (positive or zero) indicating whether box $b$ should be
+% fully emptied and committed as columns (if positive), or whether its
+% final less-than-column-height remainder should be reserved as an in-progress
+% column (if zero);
+% \item the box $b$ to split;
+% \item a count register $i$ equaling the column index (zero or greater)
+% where the content of $b$ is to begin; and
+% \item the desired column height.
+% \end{enumerate}
+% Box $b$ is split and $i$ is incremented until $i$ reaches
+% |\SB@numcols| or $b$ is emptied.
+% If $b$ is emptied and the first argument is 0, the final column is \emph{not}
+% contributed; instead it is left in $b$ and $i$ is left equal to the index
+% of the column that would have been added if $b$ had been emptied.
+% This allows the next call to reconsider whether to end the
+% current column here or add some or all of the next contribution to it.
+% Otherwise, if $b$ is emptied and the first argument is positive, the final
+% column is contributed and $i$ is set to one greater than the index of that
+% column.
+% (If $i$ reaches |\SB@numcols| before $b$ is emptied, the first argument is
+% ignored.)
+%
+% Box $b$ and count register $i$ are globally modified.
+% If |\SB@updatepage| is not redefined, boxes |\SB@pgbox| and |\SB@mrkbox|
+% are also globally modified based on the results of the split.
+%
+% The implementation takes two special steps to avoid pre-committing
+% in-progress columns (when the first macro argument is zero):
+% First, the final split that empties box $b$ is ``undone'' by reverting to a
+% backup copy made before each split.
+% Second, any underfull box warnings for this final split are suppressed by
+% temporarily adding infinite-stretch |\vfil| glue to the bottom of the box.
+% This strategy preserves underfull and overfull box warnings for the columns
+% that are actually committed, but suppresses faux warnings for the last split
+% that is undone.
+% \begin{macrocode}
+\newcommand\SB@mkpage[4]{%
+ \ifvoid#2\else\begingroup%
+ \edef\SB@temp{\ifnum#2=\SB@box\SB@boxii\else\SB@box\fi}%
+ \edef\SB@tempii{\ifnum#2=\SB@boxiii\SB@boxii\else\SB@boxiii\fi}%
+ \splitmaxdepth\maxdepth\splittopskip\z@skip%
+ \ifnum#1=\z@\global\setbox#2\vbox{\unvbox#2\vfil}\fi%
+ \loop\ifnum#3<\SB@numcols%
+ \ifnum#1=\z@\setbox\SB@tempii\copy#2\fi%
+ \setbox\SB@temp\vsplit#2to#4\relax%
+ \ifvoid#2%
+ \ifnum#1=\z@%
+ \global\setbox#2\box\SB@tempii%
+ \else%
+ \SB@updatepage%
+ \global\advance#3\@ne%
+ \fi%
+ #3\SB@numcols%
+ \else%
+ \SB@updatepage%
+ \global\advance#3\@ne%
+ \ifrepchorus\ifvoid\SB@chorusbox\else%
+ \SB@insertchorus#2%
+ \fi\fi%
+ \fi%
+ \repeat%
+ \ifnum#1=\z@\global\setbox#2\vbox{\unvbox#2\unskip}\fi%
+ \endgroup\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@migrate}
+% Migrate a mark out of a recently split vertical list, but do not insert
+% superfluous empty marks that may override previous marks.
+% \begin{macrocode}
+\newcommand\SB@migrate[1]{%
+ \SB@toks\expandafter{#1}%
+ \edef\SB@temp{\the\SB@toks}%
+ \ifx\SB@temp\@empty\else\mark{\the\SB@toks}\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@updatepage}
+% Update boxes |\SB@pgbox| and |\SB@mrkbox| immediately after splitting
+% the contents of |\SB@colbox|.
+% \begin{macrocode}
+\newcommand\SB@updatepage{%
+ \global\setbox\SB@mrkbox\vbox{%
+ \unvbox\SB@mrkbox%
+ \SB@migrate\splitfirstmark%
+ \SB@migrate\splitbotmark%
+ }%
+ \global\setbox\SB@pgbox\hbox{%
+ \SB@dimen\SB@colwidth%
+ \advance\SB@dimen\columnsep%
+ \multiply\SB@dimen\SB@colnum%
+ \advance\SB@dimen-\wd\SB@pgbox%
+ \unhbox\SB@pgbox%
+ \ifdim\SB@dimen=\z@\else\hskip\SB@dimen\relax\fi%
+ \box\SB@temp%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@droppage}
+% This alternate definition of |\SB@updatepage| drops the just-created
+% page instead of contributing it.
+% This allows |\SB@mkpage| to be called by the song-positioning algorithm
+% as a trial run without outputting anything.
+% \begin{macrocode}
+\newcommand\SB@droppage{\setbox\SB@temp\box\voidb@x}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@output}
+% This is the main output routine for the page-builder.
+% It repeatedly calls |\SB@mkpage|, emitting pages as they are completed,
+% until the remaining content of box |\SB@colbox| is not enough to fill a
+% column.
+% If the macro argument is 0, this final, in-progress column is left
+% unfinished, pending future contributions.
+% If the argument is positive, the final material is committed as a column.
+% If the argument is two or greater, the entire in-progress page is also
+% committed and the column number reset.
+% \begin{macrocode}
+\newcommand\SB@output[1]{%
+ \ifnum\SB@numcols>\z@\begingroup%
+ \loop%
+ \SB@dimen\textheight%
+ \ifinner\else\advance\SB@dimen-\pagetotal\fi%
+ \SB@mkpage#1\SB@colbox\SB@colnum\SB@dimen%
+ \SB@testfalse\SB@testiitrue%
+ \ifnum#1>\@ne\ifvoid\SB@colbox\ifnum\SB@colnum>\z@%
+ \SB@testtrue\SB@testiifalse%
+ \fi\fi\fi%
+ \ifnum\SB@colnum<\SB@numcols\SB@testiifalse\else\SB@testtrue\fi%
+ \ifSB@test%
+ \unvbox\SB@mrkbox%
+ \ifinner\else\kern\z@\fi%
+ \box\SB@pgbox%
+ \ifinner\else\vfil\break\vskip\vsize\relax\fi%
+ \global\SB@colnum\z@%
+ \fi%
+ \ifSB@testii\repeat%
+ \endgroup\else%
+ \unvbox\SB@colbox\unskip%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@putboxes}
+% Create a vertical list consisting of the already committed contents of the
+% current column plus the most recently submitted song box.
+% The \LaTeX{} primitive that should be used to contribute each box is
+% specified in the first argument.
+% \begin{macrocode}
+\newcommand\SB@putboxes[1]{%
+ \SB@dimen\ifnum\SB@numcols>\z@\ht\SB@colbox\else\p@\fi%
+ #1\SB@colbox%
+ \ifdim\SB@dimen>\z@%
+ \SB@breakpoint\spenalty%
+ \ifdim\sbarheight>\z@%
+ \vskip-\sbarheight\relax%
+ \fi%
+ \fi%
+ #1\SB@songbox%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@nextcol}
+% Force $n$ column breaks, where $n$ is given by the first argument.
+% The first created column is finished with the glue specified in the
+% second argument.
+% When the second argument is |\@flushglue|, this forces a break that leaves
+% whitespace at the bottom of the column.
+% When it's |\colbotglue|, it acts like a natural column break chosen by
+% the page-breaker.
+% However, if the current column is empty, |\@flushglue| is always used so
+% that an empty column will result.
+% \begin{macrocode}
+\newcommand\SB@nextcol[2]{%
+ \ifnum#1>\z@%
+ \ifnum\SB@numcols>\z@%
+ \global\setbox\SB@colbox\vbox{%
+ \SB@cnt#1\relax%
+ \SB@dimen\ht\SB@colbox%
+ \unvbox\SB@colbox%
+ \unskip%
+ \ifdim\SB@dimen>\z@%
+ \vskip#2\relax%
+ \break%
+ \advance\SB@cnt\m@ne%
+ \fi%
+ \loop\ifnum\SB@cnt>\z@%
+ \nointerlineskip%
+ \null%
+ \vfil%
+ \break%
+ \advance\SB@cnt\m@ne%
+ \repeat%
+ }%
+ \SB@output1%
+ \else%
+ \ifnum\lastpenalty=-\@M\null\fi%
+ \break%
+ \fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@selectcol}
+% This is the entrypoint to the song-positioning algorithm.
+% It gets defined by |\songpos| to either |\SB@@selectcol| (below) or
+% |\relax| (when song-positioning is turned off).
+% \begin{macrocode}
+\newcommand\SB@selectcol{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@@selectcol}
+% \changes{v2.1}{2007/08/02}{Rewritten to better handle glue}
+% \changes{v2.9}{2009/07/30}{Rewritten to handle repeated choruses}
+% Songs should be squeezed in wherever they fit, but breaking a column or page
+% within a song should be avoided.
+% The following macro outputs zero or more column breaks to select a good
+% place for |\SB@songbox| to be contributed to the current (or the next) page.
+% The number of column breaks is determined by temporarily setting
+% |\SB@updatepage| to |\SB@droppage| and then calling the |\SB@mkpage|
+% algorithm under various conditions to see how many columns it would
+% contribute if we start the current song at various positions.
+% \begin{macrocode}
+\newcommand\SB@@selectcol{%
+ \begingroup%
+ \SB@cnt\z@%
+ \vbadness\@M\vfuzz\maxdimen%
+ \let\SB@updatepage\SB@droppage%
+ \SB@dimen\textheight%
+ \ifinner\else\advance\SB@dimen-\pagetotal\fi%
+ \setbox\SB@boxii\vbox{\SB@putboxes\unvcopy}%
+ \SB@cntii\SB@colnum%
+ \SB@mkpage0\SB@boxii\SB@cntii\SB@dimen%
+ \SB@spos%
+ \global\SB@cnt\SB@cnt%
+ \endgroup%
+ \SB@nextcol\SB@cnt\colbotglue%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@spbegnew}
+% Begin a trial typesetting of the current song on a fresh page to see if
+% it fits within a page.
+% \begin{macrocode}
+\newcommand\SB@spbegnew{%
+ \setbox\SB@boxiii\copy\SB@songbox%
+ \SB@cntii\z@%
+ \SB@mkpage0\SB@boxiii\SB@cntii\textheight%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@spextold}
+% Tentatively extend the song previously typeset on the current even page to
+% the next odd page to see whether it fits on a double-page.
+% If the current page is odd-numbered, do nothing since extending the song
+% to the next page would introduce a page-turn.
+% \begin{macrocode}
+\newcommand\SB@spextold{%
+ \ifodd\c@page\else%
+ \SB@cntii\z@%
+ \SB@mkpage0\SB@boxii\SB@cntii\textheight%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@spextnew}
+% Extend the trial typesetting started with |\SB@spbegnew| to a second
+% page to see whether the song fits on a fresh double-page.
+% \begin{macrocode}
+\newcommand\SB@spextnew{%
+ \SB@cntii\z@%
+ \SB@mkpage0\SB@boxiii\SB@cntii\textheight%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@spdblpg}
+% Compute the number of column breaks required to shift the current song
+% to the next double-page if the result of the last test run fits within
+% its page (as indicated by counter |\SB@cntii|).
+% Otherwise leave the requested number of column breaks set to zero.
+% \begin{macrocode}
+\newcommand\SB@spdblpg{%
+ \ifnum\SB@cntii<\SB@numcols%
+ \SB@cnt\SB@numcols%
+ \advance\SB@cnt-\SB@colnum%
+ \if@twoside\ifodd\c@page\else%
+ \advance\SB@cnt\SB@numcols%
+ \fi\fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@sposi}
+% This is the level-1 song positioning algorithm.
+% It moves songs to the next double-page only if doing so would avoid a
+% page-turn that would otherwise appear within the song.
+% \begin{macrocode}
+\newcommand\SB@sposi{%
+ \ifnum\SB@cntii<\SB@numcols\else\if@twoside%
+ \SB@spextold%
+ \fi\fi%
+ \ifnum\SB@cntii<\SB@numcols\else%
+ \SB@spbegnew%
+ \ifnum\SB@cntii<\SB@numcols\else\if@twoside%
+ \SB@spextnew%
+ \fi\fi%
+ \SB@spdblpg%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@sposii}
+% This is the level-2 song-positioning algorithm.
+% It moves songs to the next page or double-page if doing so avoids a
+% page-break or page-turn that would otherwise appear within the song.
+% \begin{macrocode}
+\newcommand\SB@sposii{%
+ \ifnum\SB@cntii<\SB@numcols\else%
+ \SB@spbegnew%
+ \ifnum\SB@cntii<\SB@numcols%
+ \SB@cnt\SB@numcols%
+ \advance\SB@cnt-\SB@colnum%
+ \else%
+ \if@twoside%
+ \SB@spextold%
+ \ifnum\SB@cntii<\SB@numcols\else%
+ \SB@spextnew%
+ \SB@spdblpg%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@sposiii}
+% This is the level-3 song-positioning algorithm.
+% It moves songs to the next column, the next page, or the next double-page
+% if doing so avoids a column-break, page-break, or page-turn that would
+% otherwise appear within the song.
+% \begin{macrocode}
+\newcommand\SB@sposiii{%
+ \ifnum\SB@cntii>\SB@colnum%
+ \SB@cnt\SB@colnum%
+ \advance\SB@cnt\@ne%
+ \ifnum\SB@cnt<\SB@numcols%
+ \setbox\SB@boxiii\copy\SB@songbox%
+ \SB@mkpage0\SB@boxiii\SB@cnt\SB@dimen%
+ \advance\SB@cnt\m@ne%
+ \fi%
+ \ifnum\SB@cnt>\SB@colnum%
+ \SB@cnt\z@%
+ \SB@sposii%
+ \else%
+ \SB@cnt\@ne%
+ \fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\songpos}
+% This is the macro by which the user adjusts the aggressiveness level of the
+% song-positioning algorithm.
+% See the macros above for what each level does.
+% \begin{macrocode}
+\newcommand\songpos[1]{%
+ \ifcase#1%
+ \let\SB@selectcol\relax%
+ \let\SB@spos\relax%
+ \or%
+ \let\SB@selectcol\SB@@selectcol%
+ \let\SB@spos\SB@sposi%
+ \or%
+ \let\SB@selectcol\SB@@selectcol%
+ \let\SB@spos\SB@sposii%
+ \or%
+ \let\SB@selectcol\SB@@selectcol%
+ \let\SB@spos\SB@sposiii%
+ \else%
+ \SB@errspos%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@spos}
+% The |\SB@spos| macro gets redefined by |\songpos| above depending on the
+% current song-positioning aggressiveness level.
+% By default it is set to level 3.
+% \begin{macrocode}
+\newcommand\SB@spos{}
+\songpos\thr@@
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@clearpage}
+% Output all contributed material as a new page unless there is no contributed
+% material. In that case do nothing (i.e., don't produce a blank page).
+% The |\SB@colbox| is tested for zero height and depth rather than voidness,
+% since sometimes it contains zero-length |\splittopskip| glue.
+% \begin{macrocode}
+\newcommand\SB@clearpage{%
+ \SB@testtrue%
+ \ifvoid\SB@pgbox%
+ \ifdim\ht\SB@colbox=\z@\ifdim\dp\SB@colbox=\z@%
+ \SB@testfalse%
+ \fi\fi%
+ \fi%
+ \ifSB@test%
+ \SB@cnt\SB@numcols%
+ \advance\SB@cnt-\SB@colnum%
+ \SB@nextcol\SB@cnt\lastcolglue%
+ \SB@output2%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@cleardpage}
+% Like |\SB@clearpage| but shift to a fresh \emph{even-numbered} page in
+% two-sided documents.
+% Note that this differs from \LaTeX's |\cleardoublepage|, which shifts to
+% odd-numbered pages.
+% Song books prefer starting things on even-numbered pages because this
+% maximizes the distance until the next page-turn.
+% \begin{macrocode}
+\newcommand\SB@cleardpage{%
+ \SB@clearpage%
+ \if@twoside\ifodd\c@page%
+ \SB@nextcol\SB@numcols\@flushglue%
+ \SB@output2%
+ \fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@stype}
+% There are two song content submission types: column- and page-submissions.
+% Page-submissions are page-width and go atop fresh pages unless the current
+% page has only page-width material so far.
+% Column-submissions are column-width and start a new page only when the
+% current page is full.
+% This macro gets set to the desired type for the current submission.
+% Mostly it stays set to the default column-submission type.
+% \begin{macrocode}
+\newcommand\SB@stype{\SB@stypcol}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@stypcol}
+% \changes{v2.1}{2007/08/02}{Rewritten to better handle glue}
+% Column-submissions contribute the contents of |\SB@songbox| to either the
+% current column or the next column or page, depending on where it best fits.
+% \begin{macrocode}
+\newcommand\SB@stypcol{%
+ \ifnum\SB@numcols>\z@%
+ \SB@selectcol%
+ \global\setbox\SB@colbox\vbox{\SB@putboxes\unvbox}%
+ \SB@output0%
+ \else%
+ \unvbox\voidb@x%
+ \SB@breakpoint\spenalty%
+ \ifdim\sbarheight>\z@%
+ \vskip-\sbarheight\relax%
+ \fi%
+ \unvbox\SB@songbox%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@styppage}
+% Page-submissions go directly to the top of the nearest fresh page unless
+% the current page has all page-width material so far.
+%
+% Implementation notes:
+% The |\null| is needed because the page builder consults |\pagetotal|,
+% which isn't updated by \TeX{} until a box is contributed (|\unvbox| doesn't
+% count).
+% Both |\nointerlineskip|s are needed because |\unvbox| fails to update
+% |\prevdepth|, and it doesn't make sense to inherit its value from whatever
+% preceeded this contribution.
+% Authors who want interline glue must therefore insert it explicitly at the
+% bottom of their contributed text.
+% \begin{macrocode}
+\newcommand\SB@styppage{%
+ \ifnum\SB@numcols>\z@%
+ \SB@clearpage%
+ \unvbox\SB@songbox%
+ \nointerlineskip\null%
+ \else%
+ \unvbox\SB@songbox%
+ \fi%
+ \nointerlineskip%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@sgroup}
+% This macro controls whether songs submitted to the
+% page-builder are actually contributed to the final document when
+% using |\includeonlysongs| to generate a partial list.
+% If |\SB@sgroup| is empty, then the song is silently dropped.
+% Otherwise it is contributed only if |\SB@sgroup| is a member of
+% |\songlist|.
+% \begin{macrocode}
+\newcommand\SB@sgroup{}
+\let\SB@sgroup\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@groupcnt}
+% This counter assigns a unique integer to each item of a group.
+% Environments that come before the group's song are numbered decreasingly
+% from $-1$.
+% The song itself has number 0.
+% Environments that come after the song are numbered increasingly from 1.
+% \begin{macrocode}
+\SB@newcount\SB@groupcnt
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@clearpboxes}
+% This dynamically constructed macro clears the content of all boxes created
+% by the workings of |\includeonlysongs|.
+% \begin{macrocode}
+\newcommand\SB@clearpboxes{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@partbox}
+% Save a box of full-song or chorus material for later output when producing
+% a partial list using |\includeonlysongs|.
+% \begin{macrocode}
+\newcommand\SB@partbox[1]{%
+ \SB@newbox#1%
+ \SB@app\gdef\SB@clearpboxes{\setbox#1\box\voidb@x}%
+ \global\setbox#1\box%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@submitpart}
+% When a song completes and we're generating a partial list, save the song
+% in a box so that it can be submitted at the end of the section in the
+% order specified by |\includeonlysongs|.
+% \begin{macrocode}
+\newcommand\SB@submitpart{%
+ \ifx\SB@sgroup\@empty\else%
+ \SB@testfalse
+ \@for\SB@temp:=\songlist\do{\ifx\SB@temp\SB@sgroup\SB@testtrue\fi}%
+ \ifSB@test%
+ \edef\SB@tempii{\SB@sgroup @\the\SB@groupcnt}%
+ \expandafter\SB@partbox
+ \csname songbox@\SB@tempii\endcsname\SB@songbox%
+ \global\expandafter\let%
+ \csname stype@\SB@tempii\endcsname\SB@stype%
+ \ifrepchorus\ifvoid\SB@chorusbox\else%
+ \expandafter\SB@partbox
+ \csname chbox@\SB@tempii\endcsname\SB@chorusbox%
+ \fi\fi%
+ \fi%
+ \global\advance\SB@groupcnt%
+ \ifnum\SB@groupcnt<\z@\m@ne\else\@ne\fi%
+ \fi%
+ \setbox\SB@songbox\box\voidb@x%
+ \setbox\SB@chorusbox\box\voidb@x%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@submitsong}
+% Submit the most recently finished song (or block of other vertical material)
+% for output.
+% If we're generating a partial list of songs, save it in a box instead of
+% submitting it here.
+% (The saved boxes will be submitted in the requested order at the end of
+% the songs section.)
+% \begin{macrocode}
+\newcommand\SB@submitsong{%
+ \ifpartiallist\SB@submitpart\else\SB@stype\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@submitenv}
+% Submit the |\SB@envbox| box as a page-width contribution.
+% \begin{macrocode}
+\newcommand\SB@submitenv{%
+ \begingroup%
+ \let\SB@songbox\SB@envbox%
+ \SB@styppage%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@songlistbrk}
+% \begin{macro}{\SB@songlistnc}
+% \begin{macro}{\SB@songlistcp}
+% \begin{macro}{\SB@songlistcdp}
+% These macros define the words that, when placed in a |\songlist|,
+% force a column break at that point.
+% Using |brk| produces a soft break (like |\brk|) that won't leave
+% whitespace at the bottom of the broken column in lyric books.
+% Using |nextcol| produces a hard break (like |\nextcol|) that may
+% insert whitespace to finish the column.
+% Using |sclearpage| moves to the next page if the current page is
+% nonempty.
+% Using |scleardpage| moves to the next double-page if the current
+% double-page is nonempty.
+% \begin{macrocode}
+\newcommand*\SB@songlistbrk{brk}
+\newcommand*\SB@songlistnc{nextcol}
+\newcommand*\SB@songlistcp{sclearpage}
+\newcommand*\SB@songlistcdp{scleardpage}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\commitsongs}\MainImpl{commitsongs}
+% If we're generating only a partial list, then wait until the end of the
+% section and then output all the songs we saved in boxes in the order
+% specified.
+% \begin{macrocode}
+\newcommand\commitsongs{%
+ \ifpartiallist%
+ \ifnum\SB@numcols>\z@%
+ \@for\SB@temp:=\songlist\do{%
+ \ifx\SB@temp\SB@songlistnc\SB@nextcol\@ne\@flushglue\else%
+ \ifx\SB@temp\SB@songlistbrk\SB@nextcol\@ne\colbotglue\else%
+ \ifx\SB@temp\SB@songlistcp\SB@clearpage\else%
+ \ifx\SB@temp\SB@songlistcdp\SB@cleardpage\else%
+ \SB@groupcnt\m@ne\SB@finloop%
+ \SB@groupcnt\z@\SB@finloop%
+ \fi\fi\fi\fi%
+ }%
+ \else%
+ \@for\SB@temp:=\songlist\do{%
+ \ifx\SB@temp\SB@songlistnc\vfil\break\else%
+ \ifx\SB@temp\SB@songlistbrk\break\else%
+ \ifx\SB@temp\SB@songlistcp\clearpage\else%
+ \ifx\SB@temp\SB@songlistcdp%
+ \clearpage%
+ \ifodd\c@page\null\newpage\fi%
+ \else%
+ \SB@groupcnt\m@ne\SB@finloop%
+ \SB@groupcnt\z@\SB@finloop%
+ \fi\fi\fi\fi%
+ }%
+ \fi%
+ \SB@clearpboxes%
+ \fi%
+ \SB@clearpage%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@finloop}
+% While contributing saved material included by |\includeonlysongs|,
+% this macro contributes each series of boxes grouped together as part of a
+% |songgroup| environment.
+% \begin{macrocode}
+\newcommand\SB@finloop{%
+ \loop\edef\SB@tempii{\SB@temp @\the\SB@groupcnt}%
+ \expandafter\ifx%
+ \csname songbox@\SB@tempii\endcsname\relax\else%
+ \setbox\SB@songbox\expandafter\copy%
+ \csname songbox@\SB@tempii\endcsname%
+ \expandafter\ifx\csname chbox@\SB@tempii\endcsname\relax%
+ \repchorusfalse%
+ \else%
+ \repchorustrue%
+ \setbox\SB@chorusbox\expandafter\copy%
+ \csname chbox@\SB@tempii\endcsname%
+ \fi%
+ \csname stype@\SB@tempii\endcsname%
+ \advance\SB@groupcnt\ifnum\SB@groupcnt<\z@\m@ne\else\@ne\fi%
+ \repeat%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@insertchorus}
+% Insert a chorus into the first marked spot in the box given
+% in the first argument.
+% This is usually achieved by splitting the box at the first valid
+% breakpoint after the first |\SB@cmark| in the box.
+% The box is globally modified.
+% \begin{macrocode}
+\newcommand\SB@insertchorus[1]{{%
+ \vbadness\@M\vfuzz\maxdimen%
+ \setbox\SB@box\copy#1%
+ \setbox\SB@box\vsplit\SB@box to\maxdimen%
+ \edef\SB@temp{\splitfirstmarks\SB@nocmarkclass}%
+ \ifx\SB@temp\SB@nocmark\else%
+ \edef\SB@temp{\splitfirstmarks\SB@cmarkclass}%
+ \ifx\SB@temp\SB@cmark%
+ \SB@dimen4096\p@%
+ \SB@dimenii\maxdimen%
+ \SB@dimeniii\SB@dimen%
+ \loop%
+ \SB@dimeniii.5\SB@dimeniii%
+ \setbox\SB@box\copy#1%
+ \setbox\SB@box\vsplit\SB@box to\SB@dimen%
+ \edef\SB@temp{\splitfirstmarks\SB@cmarkclass}%
+ \ifx\SB@temp\SB@cmark%
+ \SB@dimenii\SB@dimen%
+ \advance\SB@dimen-\SB@dimeniii%
+ \else%
+ \advance\SB@dimen\SB@dimeniii%
+ \fi%
+ \ifdim\SB@dimeniii>2\p@\repeat%
+ \setbox\SB@box\vsplit#1to\SB@dimenii%
+ \global\setbox#1\vbox{%
+ \unvbox\SB@box\unskip%
+ \SB@inversefalse\SB@prevversetrue\SB@stanzabreak%
+ \SB@putbox\unvcopy\SB@chorusbox%
+ \SB@inversetrue\SB@prevversefalse\SB@stanzabreak%
+ \unvbox#1%
+ }%
+% \end{macrocode}
+% However, if the first mark is a |\SB@lastcmark|, it means that this chorus
+% should go after the last verse in the song.
+% There is no valid breakpoint there, so to get a chorus into that spot, we
+% have to do a rather ugly hack:
+% We pull the bottom material off the box with |\unskip|, |\unpenalty|, and
+% |\lastbox|, then insert the chorus, then put the bottom material back on.
+% This works because the high-level structure of the bottom material should
+% be static.
+% Even if the user redefines |\makepostlude|, the new definition gets put
+% in a single box that can be manipulated with |\lastbox|.
+% However, if we ever change the high-level structure, we need to remember to
+% change this code accordingly.
+% \begin{macrocode}
+ \else\ifx\SB@temp\SB@lastcmark%
+ \global\setbox#1\vbox{%
+ \unvbox#1%
+ \unskip%
+ \ifdim\sbarheight>\z@%
+ \setbox\SB@box\lastbox%
+ \unskip\unpenalty%
+ \fi%
+ \setbox\SB@box\lastbox%
+ \unskip\unskip%
+ \SB@inversefalse\SB@prevversetrue\SB@stanzabreak%
+ \marks\SB@nocmarkclass{\SB@nocmark}%
+ \unvcopy\SB@chorusbox%
+ \vskip\versesep\vskip\beforepostludeskip\relax%
+ \nointerlineskip\box\SB@box%
+ \ifdim\sbarheight>\z@%
+ \nobreak\vskip2\p@\@plus\p@%
+ \hrule\@height\sbarheight\@width\SB@colwidth%
+ \fi%
+ }%
+ \fi\fi%
+ \fi%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\nextcol}\MainImpl{nextcol}
+% End the current column (inserting vertical space as needed).
+% This differs from column breaks produced with |\brk|, which does not
+% introduce any empty vertical space.
+% \begin{macrocode}
+\newcommand\nextcol{%
+ \@ifstar{\SB@nextcol\@ne\@flushglue}%
+ {\ifpartiallist\else\SB@nextcol\@ne\@flushglue\fi}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sclearpage}\MainImpl{sclearpage}
+% Move to the next page if the current page is nonempty.
+% \begin{macrocode}
+\newcommand\sclearpage{%
+ \@ifstar\SB@clearpage{\ifpartiallist\else\SB@clearpage\fi}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\scleardpage}\MainImpl{scleardpage}
+% Move to the next even-numbered page if the current page is odd or nonempty.
+% \begin{macrocode}
+\newcommand\scleardpage{%
+ \@ifstar\SB@cleardpage{\ifpartiallist\else\SB@cleardpage\fi}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Songs}
+%
+% The following macros handle the parsing and formatting of the material that
+% begins and ends each song.
+%
+% \begin{macro}{\SB@lop}
+% \begin{macro}{\SB@@lop}
+% \begin{macro}{\SB@emptylist}
+% \begin{macro}{\SB@ifempty}
+% The following macros were adapted from Donald Knuth's \emph{The \TeX book},
+% for manipulating lists of the form
+% {\it |\\|item1|\\|item2|\\|...|\\|itemN|\\|}.
+% \begin{macrocode}
+\newcommand\SB@lop[1]{\expandafter\SB@@lop\the#1\SB@@lop#1}
+\newcommand\SB@@lop{}
+\def\SB@@lop\\#1\\#2\SB@@lop#3#4{\global#3{\\#2}\global#4{#1}}
+\newcommand*\SB@emptylist{\\}
+\newcommand\SB@ifempty[3]{%
+ \edef\SB@temp{\the#1}%
+ \ifx\SB@temp\SB@emptylist#2\else#3\fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@titlelist}
+% \begin{macro}{\SB@titletail}
+% These registers hold the full list of titles for the current song and
+% the tail list of titles that has not yet been iterated over.
+% \begin{macrocode}
+\SB@newtoks\SB@titlelist
+\SB@newtoks\SB@titletail
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\songtitle}
+% \changes{v1.15}{2005/05/26}{Added song title iterators}
+% The |\songtitle| macro will initially hold the primary title of the
+% current song.
+% The user can iterate over titles using |\nexttitle| or |\foreachtitle|.
+% \begin{macrocode}
+\newcommand\songtitle{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\resettitles}\MainImpl{resettitles}
+% \changes{v1.15}{2005/05/26}{Added.}
+% Initialize the title list iterator.
+% \begin{macrocode}
+\newcommand\resettitles{%
+ \global\SB@titletail\SB@titlelist%
+ \nexttitle%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\nexttitle}\MainImpl{nexttitle}
+% \changes{v1.15}{2005/05/26}{Added.}
+% Advance the title list iterator to the next title.
+% \begin{macrocode}
+\newcommand\nexttitle{%
+ \SB@ifempty\SB@titletail{%
+ \global\let\songtitle\relax%
+ }{%
+ \SB@lop\SB@titletail\SB@toks%
+ \edef\songtitle{\the\SB@toks}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\foreachtitle}\MainImpl{foreachtitle}
+% \changes{v1.15}{2005/05/26}{Added.}
+% Execute a block of code for each remaining title in the title list.
+% \begin{macrocode}
+\newcommand\foreachtitle[1]{%
+ \ifx\songtitle\relax\else%
+ \loop#1\nexttitle\ifx\songtitle\relax\else\repeat%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@insong}
+% \begin{macro}{\ifSB@intersong}
+% \begin{macro}{\ifSB@inverse}
+% \begin{macro}{\ifSB@inchorus}
+% To help the user locate errors, keep track of which environments we're inside
+% and immediately signal an error if someone tries to use a song command inside
+% a scripture quotation, etc.
+% \begin{macrocode}
+\newif\ifSB@songsenv\SB@songsenvfalse
+\newif\ifSB@insong\SB@insongfalse
+\newif\ifSB@intersong\SB@intersongfalse
+\newif\ifSB@inverse\SB@inversefalse
+\newif\ifSB@inchorus\SB@inchorusfalse
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@closeall}
+% If an error is detected using one of the above, the following macro will
+% contain a macro sequence sufficient to end the unclosed environment,
+% hopefully allowing processing to continue.
+% \begin{macrocode}
+\newcommand\SB@closeall{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@rawrefs}
+% \begin{macro}{\songauthors}\MainImpl{songauthors}
+% \begin{macro}{\songcopyright}\MainImpl{songcopyright}
+% \begin{macro}{\songlicense}\MainImpl{songlicense}
+% The current song's scripture references, authors, copyright info, and
+% copyright license information are stored in these macros.
+% \begin{macrocode}
+\newcommand\SB@rawrefs{}
+\newcommand\songauthors{}
+\newcommand\songcopyright{}
+\newcommand\songlicense{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\songrefs}\MainImpl{songrefs}
+% When the user asks for the song's scripture references, rather than give
+% them the raw token list that the author entered, we return a prettier
+% version in which spaces, dashes, and penalties have been adjusted.
+% The prettier version is stored in the following control sequence.
+% \begin{macrocode}
+\newcommand\songrefs{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setlicense}\MainImpl{setlicense}
+% The user sets the licensing info for the current song with this command.
+% \begin{macrocode}
+\newcommand\setlicense{\gdef\songlicense}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newsongkey}\MainImpl{newsongkey}
+% \begin{macro}{\SB@clearbskeys}
+% \changes{v2.0}{2007/06/18}{Added.}
+% Defining a new key for |\beginsong| is just like the |keyval| package's
+% |\define@key| macro except that we must also define some initializer code
+% for each key.
+% This provides an opportunity to clear registers before each song.
+% (Otherwise when a key wasn't specified, we'd inherit the old values from
+% the previous song.)
+% \begin{macrocode}
+\newcommand\SB@clearbskeys{}
+\newcommand\newsongkey[2]{%
+ \SB@app\gdef\SB@clearbskeys{#2}%
+ \define@key{beginsong}{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Define keys |sr|, |by|, |cr|, |li|, |index|, and |ititle| for scripture
+% references, authors, copyright info, licensing info, lyric index entries,
+% and alternate title index entries, respectively.
+% \begin{macrocode}
+\newsongkey{sr}{\def\SB@rawrefs{}\gdef\songrefs{}}
+ {\def\SB@rawrefs{#1}\SB@parsesrefs{#1}}
+\newsongkey{by}{\def\songauthors{}}{\def\songauthors{#1}}
+\newsongkey{cr}{\def\songcopyright{}}{\def\songcopyright{#1}}
+\newsongkey{li}{\setlicense{}}{\setlicense{#1}}
+\newsongkey{index}{}{\indexentry{#1}}
+\newsongkey{ititle}{}{\indextitleentry{#1}}
+% \end{macrocode}
+%
+% \begin{environment}{song}\MainEnvImpl{song}
+% \begin{macro}{\beginsong}
+% \begin{macro}{\SB@@beginsong}
+% \begin{macro}{\SB@bsoldfmt}
+% \begin{macro}{\SB@@bskvfmt}
+% Parse the arguments of a |\beginsong| macro.
+% The |\beginsong| macro supports two syntaxes.
+% The preferred syntax takes the song title(s) as its first argument and
+% an optional keyval list in brackets as its second argument.
+% A legacy syntax supports four arguments, all enclosed in braces,
+% which are: the title(s), scripture references, authors, and copyright info.
+% \begin{macrocode}
+\newenvironment{song}{\beginsong}{\SB@endsong}
+\newcommand\beginsong[1]{%
+ \ifSB@insong\SB@errboo\SB@closeall\fi%
+ \ifSB@intersong\SB@errbor\SB@closeall\fi%
+ \SB@insongtrue%
+ \def\SB@closeall{\endsong}%
+ \SB@parsetitles{#1}%
+ \global\setbox\SB@songwrites\box\voidb@x%
+ \SB@clearbskeys%
+ \@ifnextchar[\SB@bskvfmt\SB@@beginsong%
+}
+\newcommand\SB@@beginsong{%
+ \@ifnextchar\bgroup\SB@bsoldfmt\SB@@@beginsong%
+}
+\newcommand\SB@bsoldfmt[3]{%
+ \SB@bskvfmt[sr={#1},by={#2},cr={#3}]%
+}
+\newcommand\SB@bskvfmt{}
+\def\SB@bskvfmt[#1]{%
+ \setkeys{beginsong}{#1}%
+ \SB@@@beginsong%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@@@beginsong}
+% \changes{v1.12}{2005/05/10}{Redid spacing and page-breaking}
+% \changes{v1.14}{2005/05/15}{Improved scripture reference line-breaking}
+% \changes{v2.0}{2007/06/18}{Added keyval syntax.}
+% Begin typesetting a song.
+% Beginning a song involves typesetting the title and other info, adding
+% entries to the indexes, and setting up the environment in which verses and
+% choruses reside.
+% \begin{macrocode}
+\newcommand\SB@@@beginsong{%
+ \global\SB@stanzafalse%
+ \setbox\SB@chorusbox\box\voidb@x%
+ \SB@gotchorusfalse%
+ \setbox\SB@songbox\vbox\bgroup\begingroup%
+ \ifnum\SB@numcols>\z@\hsize\SB@colwidth\fi%
+ \leftskip\z@skip\rightskip\z@skip%
+ \parfillskip\@flushglue\parskip\z@skip%
+ \SB@raggedright%
+ \global\SB@transposefactor\z@%
+ \global\SB@cr@{\\}%
+ \protected@edef\@currentlabel{\p@songnum\thesongnum}%
+ \setcounter{versenum}{1}%
+ \SB@prevversetrue%
+ \meter44%
+ \resettitles%
+ \SB@addtoindexes\songtitle\SB@rawrefs\songauthors%
+ \nexttitle%
+ \foreachtitle{\expandafter\SB@addtotitles\expandafter{\songtitle}}%
+ \resettitles%
+ \lyricfont\relax%
+ \SB@setbaselineskip%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@endsong}
+% \changes{v1.12}{2005/05/10}{Redid spacing and page-breaking}
+% \changes{v2.0}{2007/06/18}{Removed hyperref dependency}
+% Ending a song involves creating the song header (with |\makeprelude|),
+% creating the song footer (with |\makepostlude|), and then assembling
+% everything together into the |\SB@songbox|.
+% The box is then submitted to the page-builder via |\SB@submitsong|.
+% We do things this way instead of just contributing material directly
+% to the main vertical list because submitting material song by song allows
+% for a more sophisticated page-breaking algorithm than is possible with
+% \TeX's built-in algorithm.
+% \begin{macrocode}
+\newcommand\SB@endsong{%
+ \ifSB@insong%
+ \ifSB@inverse\SB@erreov\endverse\fi%
+ \ifSB@inchorus\SB@erreoc\endchorus\fi%
+ \global\SB@skip\versesep%
+ \unskip%
+ \ifrepchorus\ifvoid\SB@chorusbox\else%
+ \ifSB@prevverse\ifvnumbered%
+ \marks\SB@cmarkclass{\SB@lastcmark}%
+ \fi\fi%
+ \fi\fi%
+ \endgroup\egroup%
+ \begingroup%
+ \ifnum\SB@numcols>\z@%
+ \hsize\ifpagepreludes\textwidth\else\SB@colwidth\fi%
+ \fi%
+ \leftskip\z@skip\rightskip\z@skip%
+ \parfillskip\@flushglue\parskip\z@skip\parindent\z@%
+ \global\setbox\SB@envbox\vbox{%
+ \songmark%
+ \unvbox\SB@songwrites%
+ \ifpagepreludes\else\ifdim\sbarheight>\z@%
+ \hrule\@height\sbarheight\@width\hsize%
+ \nobreak\vskip5\p@\relax%
+ \fi\fi%
+ \resettitles%
+ \begingroup%
+ \songtarget{\ifnum\c@section=\z@1\else2\fi}%
+ {song\theSB@songsnum-\thesongnum}%
+ \endgroup%
+ \vbox{\makeprelude}%
+ \nobreak\vskip\SB@skip%
+ \vskip\afterpreludeskip\relax%
+ }%
+ \ifnum\SB@numcols>\z@\hsize\SB@colwidth\fi%
+ \global\setbox\SB@songbox\vbox{%
+ \ifpagepreludes\else\unvbox\SB@envbox\fi%
+ \unvbox\SB@songbox%
+ \nobreak\vskip\SB@skip%
+ \vskip\beforepostludeskip\relax%
+ \nointerlineskip%
+ \vbox{\makepostlude}%
+ \ifdim\sbarheight>\z@%
+ \nobreak\vskip2\p@\@plus\p@%
+ \nointerlineskip%
+ \hbox{\vrule\@height\sbarheight\@width\hsize}%
+ \fi%
+ }%
+ \endgroup%
+ \SB@insongfalse%
+ \edef\SB@sgroup{\thesongnum}%
+ \global\SB@groupcnt\z@%
+ \ifpagepreludes\SB@submitenv\fi%
+ \SB@submitsong%
+ \ifnum\SB@grouplvl=\z@\let\SB@sgroup\@empty\fi%
+ \stepcounter{songnum}%
+ \else%
+ \ifSB@intersong\SB@erreor\SB@closeall%
+ \else\SB@erreot\fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+%
+% \begin{macro}{\SB@setbaselineskip}
+% \changes{v1.22}{2007/05/15}{Added.}
+% \changes{v2.1}{2007/08/02}{Fixed to scale better with large font sizes.}
+% Set the |\baselineskip| to an appropriate line height.
+% \begin{macrocode}
+\newcommand\SB@setbaselineskip{%
+ \SB@dimen\f@size\p@%
+ \baselineskip\SB@dimen\relax%
+ \ifchorded%
+ \setbox\SB@box\hbox{{\printchord{ABCDEFG\shrp\flt/j7}}}%
+ \advance\baselineskip\ht\SB@box%
+ \advance\baselineskip2\p@%
+ \fi%
+ \ifslides%
+ \advance\baselineskip.2\SB@dimen\@plus.5\SB@dimen%
+ \@minus.2\SB@dimen%
+ \else%
+ \advance\baselineskip\z@\@plus.1\SB@dimen\relax%
+ \fi%
+ \advance\baselineskip\baselineadj%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@setversesep}
+% Set the |\versesep| to an appropriate amount if has not already been
+% explicitly set by the user.
+% \begin{macrocode}
+\newcommand\SB@setversesep{%
+ \SB@dimen123456789sp%
+ \edef\SB@temp{\the\SB@dimen}%
+ \edef\SB@tempii{\the\versesep}%
+ \ifx\SB@temp\SB@tempii%
+ \begingroup%
+ \lyricfont\relax%
+ \SB@dimen\f@size\p@%
+ \ifchorded%
+ \setbox\SB@box\hbox{{\printchord{ABCDEFG\shrp\flt/j7}}}%
+ \advance\SB@dimen\ht\SB@box%
+ \fi%
+ \ifslides%
+ \global\versesep1.2\SB@dimen\@plus.3\SB@dimen%
+ \@minus.3\SB@dimen%
+ \else%
+ \global\versesep.75\SB@dimen\@plus.25\SB@dimen%
+ \@minus.13\SB@dimen%
+ \fi%
+ \endgroup%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\makeprelude}\MainImpl{makeprelude}
+% \changes{v1.15}{2005/05/26}{Added to make song header format customizable.}
+% \changes{v2.0}{2007/06/18}{Arguments removed to support keyval syntax.}
+% Generate the material that begins each song.
+% This macro is invoked at |\endsong| so that its code can access song info
+% defined throughout the song.
+%
+% Note that if you are redefining |\makeprelude|, you can probably replace
+% everything below with something much simpler.
+% The code below is lengthy because it accommodates all of the many different
+% options that various authors may adjust to customize their books.
+% If you redefine it, you can replace all of this with smaller, more
+% specialized programming that just outputs the prelude format you desire.
+% \begin{macrocode}
+\newcommand\makeprelude{%
+ \resettitles%
+% \end{macrocode}
+% In slides mode, the title, references, and authors are simply centered on
+% the page with no song number.
+% Only the first of the song titles is included.
+% The references and authors only span the middle 50\% of the page, since
+% letting them span the whole page width stretches them out too much and makes
+% their fine print too hard to read.
+% \begin{macrocode}
+ \ifslides%
+ \hbox to\hsize{{\hfil\stitlefont\relax\songtitle\hfil}}%
+ \vskip5\p@%
+ \hbox to\hsize{%
+ \hfil%
+ \vbox{%
+ \divide\hsize\tw@\parskip\p@\relax%
+ \centering\small\extendprelude%
+ }%
+ \hfil%
+ }%
+ \else%
+% \end{macrocode}
+% In non-slides mode, we write the song number in a shaded box to the left
+% (if |\songnumwidth| is positive) and everything else in left-justified
+% paragraphs to the right of it (or centered if |\pagepreludes| is on).
+% The height of the shaded box that contains the song number depends on
+% which is higher: the natural height of the song number, or everything else
+% that goes to the right of it.
+% To find out which is higher, we start by putting the song number in its
+% own box (|\SB@boxii|).
+% \begin{macrocode}
+ \ifdim\songnumwidth>\z@%
+ \setbox\SB@boxii\hbox{{\SB@colorbox\snumbgcolor{%
+ \hbox to\songnumwidth{%
+ \printsongnum{\thesongnum}\hfil%
+ }%
+ }}}%
+ \fi%
+% \end{macrocode}
+% Now we know the width $w$ of the song number box, so we typeset everything
+% else in a box (|\SB@box|) of width $c-w$, where $c$ is the column width.
+% (If |\pagepreludes| is on, we instead use width $c-2w$ so that the material
+% stays centered on the page.)
+% \begin{macrocode}
+ \setbox\SB@box\vbox{%
+ \ifdim\songnumwidth>\z@%
+ \SB@dimen\wd\SB@boxii%
+ \advance\SB@dimen3\p@%
+ \ifpagepreludes\multiply\SB@dimen\tw@\fi%
+ \advance\hsize-\SB@dimen%
+ \fi%
+ \ifpagepreludes\centering\else\SB@raggedright\fi%
+ \offinterlineskip\lineskip\p@%
+ {\stitlefont\relax%
+ \songtitle\par%
+ \nexttitle%
+ \foreachtitle{(\songtitle)\par}}%
+ \ifdim\prevdepth=\z@\kern\p@\fi%
+ \parskip\p@\relax\tiny%
+ \extendprelude%
+ \kern\z@%
+ }%
+% \end{macrocode}
+% If the song number is being printed (i.e., |\songnumwidth| is positive),
+% and its height is greater than the height of the other material, then we
+% just put |\SB@boxii| and |\SB@box| side-by-side.
+% If the song number is being printed but its height is less, then we
+% re-typeset it at height equal to the other material, and place the boxes
+% side-by-side.
+% Finally, if the song number is not being printed at all, we just unbox
+% |\SB@box| onto the vertical list.
+% \begin{macrocode}
+ \ifdim\songnumwidth>\z@%
+ \hbox{%
+ \ifdim\ht\SB@boxii>\ht\SB@box%
+ \box\SB@boxii%
+ \kern3\p@%
+ \vtop{\box\SB@box}%
+ \else%
+ \SB@colorbox\snumbgcolor{\vbox to\ht\SB@box{{%
+ \hbox to\songnumwidth{%
+ \printsongnum{\thesongnum}\hfil%
+ }\vfil%
+ }}}%
+ \kern3\p@%
+ \box\SB@box%
+ \fi%
+ }%
+ \else%
+ \unvbox\SB@box%
+ \fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\makepostlude}\MainImpl{makepostlude}
+% \changes{v1.15}{2005/05/26}{Added to make song trailer format customizable.}
+% \changes{v2.0}{2007/06/18}{Arguments removed to support keyval syntax.}
+% Generate the material that ends each song.
+% The default implementation just prints the copyright and licensing
+% information (if any) as a single, left-justified, non-indentended paragraph
+% in fine print.
+% \begin{macrocode}
+\newcommand\makepostlude{%
+ \SB@raggedright\baselineskip\z@skip\parskip\z@skip\parindent\z@%
+ \tiny\extendpostlude%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\showauthors}\MainImpl{showauthors}
+% Display the author information in the prelude.
+% This macro is only called by |\extendprelude|, which is only called by
+% |\makeprelude|; so if you redefine either of those, you don't need this.
+% The default implementation prints the authors in boldface and shortens the
+% spacing after periods so that they don't look like ends of sentences.
+% \begin{macrocode}
+\newcommand\showauthors{%
+ \setbox\SB@box\hbox{\bfseries\sfcode`.\@m\songauthors}%
+ \ifdim\wd\SB@box>\z@\unhbox\SB@box\par\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\showrefs}\MainImpl{showrefs}
+% Display the scripture references in the prelude.
+% This macro is only called by |\extendprelude|, which is only called by
+% |\makeprelude|; so if you redefine either of those, you don't need this.
+% The default implementation prints the scripture references in slanted
+% (oblique) font.
+% \begin{macrocode}
+\newcommand\showrefs{%
+ \setbox\SB@box\hbox{\slshape\songrefs\vphantom,}%
+ \ifdim\wd\SB@box>\z@\unhbox\SB@box\par\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@next}
+% \begin{macro}{\SB@donext}
+% \begin{macro}{\SB@dothis}
+% Several macros use |\futurelet| to look ahead in the input stream, and then
+% take various actions depending on what is seen.
+% In these macros, |\SB@next| is assigned the token seen, |\SB@dothis| is
+% assigned the action to be taken on this loop iteration, and |\SB@donext| is
+% assigned the action to be taken to continue (or terminate) the loop.
+% \begin{macrocode}
+\newcommand\SB@next{}
+\newcommand\SB@donext{}
+\newcommand\SB@dothis{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@nextname}
+% Sometimes when scanning ahead we |\string|ify the name of the next token.
+% When that happens, the name is stored in this macro for safekeeping.
+% \begin{macrocode}
+\newcommand\SB@nextname{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@appendsp}
+% Append an explicit space token (catcode 10) to a token register.
+% This is a useful macro to have around because inlining this code directly
+% into a larger macro is harder than it seems:
+% If you write the following code but with an explicit control sequence
+% instead of |#1|, then the space immediately following the name will get
+% stripped by the \TeX{} parser.
+% But invoking the following macro with a control sequence as an argument
+% works fine, because in that case the explicit space has already been
+% tokenized when this macro was first defined and won't be stripped as it
+% is expanded.
+% \begin{macrocode*}
+\newcommand\SB@appendsp[1]{#1\expandafter{\the#1 }}
+% \end{macrocode*}
+% \end{macro}
+%
+% \begin{macro}{\SB@parsetitles}
+% \changes{v2.1}{2007/08/02}{Added}
+% Parse a list of song titles.
+% This just involves removing leading and trailing spaces from around each
+% title in the |\\|-separated list.
+% \begin{macrocode}
+\newcommand\SB@parsetitles[1]{%
+ \begingroup%
+ \global\SB@titlelist{\\}%
+ \SB@toks{}%
+ \let\\\SB@titlesep%
+ \SB@pthead#1\SB@endparse%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@pthead}
+% \begin{macro}{\SB@@pthead}
+% \begin{macro}{\SB@@@pthead}
+% While processing tokens at the head of a title, we skip over all spaces
+% until we reach a non-space token.
+% \begin{macrocode}
+\newcommand\SB@pthead{\futurelet\SB@next\SB@@pthead}
+\newcommand\SB@@pthead{%
+ \ifcat\noexpand\SB@next\@sptoken%
+ \expandafter\SB@@@pthead%
+ \else%
+ \expandafter\SB@ptmain%
+ \fi%
+}
+\newcommand\SB@@@pthead{%
+ \afterassignment\SB@pthead%
+ \let\SB@next= }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@ptloop}
+% The iterator of the title parser loop just scans the next token.
+% \begin{macrocode}
+\newcommand\SB@ptloop{\futurelet\SB@next\SB@ptmain}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@ptmain}
+% Once we've reached a non-space token in the title, we consume the remainder
+% of the title as-is, except that space tokens should be trimmed from the end
+% of each title.
+% \begin{macrocode}
+\newcommand\SB@ptmain{%
+ \ifcat\noexpand\SB@next\@sptoken%
+ \let\SB@donext\SB@ptsp%
+ \else\ifcat\noexpand\SB@next\bgroup%
+ \let\SB@donext\SB@ptbg%
+ \else\ifx\SB@next\SB@endparse%
+ \global\SB@titlelist\expandafter{\the\SB@titlelist\\}%
+ \let\SB@donext\@gobble%
+ \else\ifx\SB@next\\%
+ \SB@toks{}%
+ \def\SB@donext{\SB@ptstep\SB@pthead}%
+ \else%
+ \def\SB@donext{\SB@ptstep\SB@ptloop}%
+ \fi\fi\fi\fi%
+ \SB@donext}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@ptstep}
+% Consume a non-space, non-left-brace token and add it to the current song
+% title.
+% If any spaces preceded it, add those too.
+% \begin{macrocode}
+\newcommand\SB@ptstep[2]{%
+ \global\SB@titlelist\expandafter\expandafter\expandafter{%
+ \expandafter\the\expandafter\SB@titlelist\the\SB@toks#2}%
+ \SB@toks{}%
+ #1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@ptbg}
+% The next title token is a left-brace.
+% It should be balanced, so consume the entire group and add it (along with
+% its surrounding braces) as-is to the current title.
+% \begin{macrocode}
+\newcommand\SB@ptbg[1]{\SB@ptstep\SB@ptloop{{#1}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@ptsp}
+% The next title token is a space.
+% We won't know whether to include it in the title until we see what
+% follows it.
+% Strings of spaces followed by the |\\| title-delimiter token, or that
+% conclude a title argument, should be stripped.
+% So rather than add the space token to the title, we remember it in a
+% token register for possible later inclusion.
+% \begin{macrocode}
+\newcommand\SB@ptsp{
+ \SB@appendsp\SB@toks%
+ \afterassignment\SB@ptloop%
+ \let\SB@next= }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@titlesep}
+% While parsing song titles, we temporarily assign |\\| a non-trivial
+% top-level expansion (|\SB@titlesep|) in order to distinguish it from
+% other macros.
+% \begin{macrocode}
+\newcommand\SB@titlesep{SB@titlesep}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@endparse}
+% The |\SB@endparse| token marks the end of a token sequence being parsed.
+% If parsing works as intended, the macro should never be expanded, so
+% produce an error if it is.
+% \begin{macrocode}
+\newcommand\SB@endparse{%
+ \SB@Error{Title parsing failed}{This error should not occur.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@parsesrefs}
+% \changes{v1.14}{2005/05/15}{Added}
+% Assign the |\songrefs| macro a processed version of a scripture reference in
+% which the following adjustments have been made:
+% (1)~Spaces not preceded by a comma or semicolon are made non-breaking.
+% For example, |2 John 1:1| and |Song of Solomon 1:1| become |2~John~1:1| and
+% |Song~of~Solomon~1:1|, respectively.
+% (2)~Spaces between a semicolon and a book name are lengthened to en-spaces.
+% (3)~Single hyphens are lengthened to en-dashes (|--|).
+% (4)~Non-breaking, thin spaces are appended to commas not followed by a
+% space. For example |John 3:16,17| becomes |John~3:16,\nobreak\thinspace17|.
+% (5)~Everything within an explicit group is left unchanged, allowing the
+% user to suppress all of the above as desired.
+%
+% To achieve this, we must change all commas, hyphens, and spaces
+% in the scripture reference into active characters.
+% Unfortunately, the catcodes of everything in the text were set back when
+% the full keyval list was digested as an argument to |\beginsong|, so we
+% must unset and reset the catcodes.
+% One obvious solution is to use |\scantokens| from $\varepsilon$-\TeX{} to
+% do this, but that doesn't allow us to suppress the re-catcoding process
+% within groups, and we'd like to avoid intoducing features that require
+% $\varepsilon$-\TeX{} anyway for compatibility reasons.
+% Therefore, we build the following small scanner instead.
+%
+% The scanner walks through the text token by token, replacing each important
+% token by its active equivalent.
+% No character codes are modified during this process and no tokens are
+% inserted because some of these tokens might end up being arguments to
+% multi-byte unicode character macros rather than being expanded directly.
+% The |inputenc| package only cares about the character codes, not the
+% category codes, so modifying only the category codes should be safe.
+% \begin{macrocode}
+\newcommand\SB@parsesrefs[1]{%
+ \begingroup%
+ \SB@toks{\begingroup\SB@sractives}%
+ \SB@prloop#1\SB@endparse%
+ \xdef\songrefs{\the\SB@toks\endgroup}%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@prloop}
+% \begin{macro}{\SB@prstep}
+% \begin{macro}{\SB@@prstep}
+% The main loop of the scripture reference scanner identifies each space,
+% hyphen, and comma for special treatment.
+% \begin{macrocode}
+\newcommand\SB@prloop{\futurelet\SB@next\SB@prstep}
+\newcommand\SB@prstep{%
+ \ifcat\noexpand\SB@next A%
+ \expandafter\SB@prcpy%
+ \else%
+ \expandafter\SB@@prstep%
+ \fi%
+}
+\newcommand\SB@@prstep{%
+ \ifcat\noexpand\SB@next\@sptoken%
+ \let\SB@donext\SB@prspace%
+ \else\ifx\SB@next-%
+ \let\SB@donext\SB@prhyphen%
+ \else\ifx\SB@next,%
+ \let\SB@donext\SB@prcomma%
+ \else\ifx\SB@next\SB@endparse%
+ \let\SB@donext\@gobble%
+ \else\ifcat\noexpand\SB@next\bgroup%
+ \let\SB@donext\SB@prgr%
+ \else%
+ \let\SB@donext\SB@prcpy%
+ \fi\fi\fi\fi\fi%
+ \SB@donext%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@prcpy}
+% \begin{macro}{\SB@prgr}
+% Anything that isn't one of the special tokens above, and anything in a
+% group, is copied without modification.
+% \begin{macrocode}
+\newcommand\SB@prcpy[1]{\SB@toks\expandafter{\the\SB@toks#1}\SB@prloop}
+\newcommand\SB@prgr[1]{\SB@toks\expandafter{\the\SB@toks{#1}}\SB@prloop}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+
+% \begin{macro}{\SB@prcomma}
+% \begin{macro}{\SB@prhyphen}
+% Commas and hyphens are replaced with active equivalents.
+% \begin{macrocode}
+\newcommand\SB@prcomma[1]{}
+{\catcode`,\active
+ \gdef\SB@prcomma#1{\SB@toks\expandafter{\the\SB@toks,}\SB@prloop}}
+\newcommand\SB@prhyphen[1]{}
+{\catcode`-\active
+ \gdef\SB@prhyphen#1{\SB@toks\expandafter{\the\SB@toks-}\SB@prloop}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@prspace}
+% \begin{macro}{\SB@@prspace}
+% Spaces are made active as well, but doing so requires some
+% specialized code since they cannot be consumed as implicit macro arguments.
+% \begin{macrocode*}
+\newcommand\SB@prspace[1]{}
+{\obeyspaces
+\gdef\SB@prspace{\SB@toks\expandafter{\the\SB@toks }\SB@@prspace}}
+% \end{macrocode*}
+% \begin{macrocode}
+\newcommand\SB@@prspace{\afterassignment\SB@prloop\let\SB@temp= }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+
+% \begin{macro}{\SB@sractives}
+% Assign macro definitions to active commas, hyphens, spaces, and returns
+% when the token list generated by |\SB@parsesrefs| is used to typeset a
+% scripture reference list.
+% \begin{macrocode*}
+\newcommand\SB@sractives{}
+{\catcode`,\active\catcode`-\active\obeyspaces%
+\gdef\SB@sractives{%
+\let,\SB@srcomma\let-\SB@srhyphen\let \SB@srspace%
+\SB@srspacing}%
+}
+% \end{macrocode*}
+% \end{macro}
+%
+% \begin{macro}{\SB@srspacing}
+% The space factors of semicolons and commas are what the active spaces
+% within a scripture reference text use to decide what came before.
+% The following sets them to their default values in case they have been
+% changed, but sets all other space factors to 1000.
+% \begin{macrocode}
+\newcommand\SB@srspacing{%
+ \nonfrenchspacing\sfcode`\;=1500\sfcode`\,=1250\relax%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@srcomma}
+% \begin{macro}{\SB@@srcomma}
+% Commas not already followed by whitespace are appended with a thin,
+% non-breaking space.
+% \begin{macrocode}
+\newcommand\SB@srcomma{,\futurelet\SB@next\SB@@srcomma}
+\newcommand\SB@@srcomma{%
+ \ifx\SB@next\SB@srspace\else%
+ \nobreak\thinspace%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@srhyphen}
+% \begin{macro}{\SB@@srhyphen}
+% \begin{macro}{\SB@srdash}
+% \begin{macro}{\SB@@srdash}
+% Hyphens that are not already part of a ligature (an en- or em-dash)
+% become en-dashes.
+% \begin{macrocode}
+\newcommand\SB@srhyphen{\futurelet\SB@next\SB@@srhyphen}
+\newcommand\SB@@srhyphen{%
+ \ifx\SB@next\SB@srhyphen\expandafter\SB@srdash\else--\fi%
+}
+\newcommand\SB@srdash[1]{\futurelet\SB@next\SB@@srdash}
+\newcommand\SB@@srdash{%
+ \ifx\SB@next\SB@srhyphen---\expandafter\@gobble\else--\fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@srspace}
+% \begin{macro}{\SB@@srspace}
+% To compress consecutive whitespace, we ignore spaces
+% immediately followed by more whitespace.
+% Spaces not preceded by a semicolon or comma become non-breaking.
+% Most spaces following a semicolon become en-spaces with favorable
+% breakpoints, but a special case arises for spaces between a semicolon
+% and a digit (see |\SB@srcso| below).
+% \begin{macrocode}
+\newcommand\SB@srspace{\futurelet\SB@next\SB@@srspace}
+\newcommand\SB@@srspace{%
+ \let\SB@donext\relax%
+ \ifx\SB@next\SB@srspace\else%
+ \ifnum\spacefactor>\@m%
+ \ifnum\spacefactor>1499 %
+ \ifcat\noexpand\SB@next0%
+ \let\SB@donext\SB@srcso%
+ \else%
+ \penalty-5\enskip%
+ \fi%
+ \else%
+ \space%
+ \fi%
+ \else%
+ \nobreak\space%
+ \fi%
+ \fi%
+ \SB@donext%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@srcso}
+% \begin{macro}{\SB@@srcso}
+% A space between a semicolon and a digit could be within a list of
+% verse references for a common book (e.g., |Job 1:1; 2:2|);
+% or it could separate the previous book from a new book whose name
+% starts with a number (e.g., |Job 1:1; 1 John 1:1|).
+% In the former case, we should just use a regular space;
+% but in the latter case we should be using an en-space with a
+% favorable breakpoint.
+% To distinguish between the two, we peek ahead at the next two tokens.
+% If the second one is a space, assume the latter; otherwise assume the
+% former.
+% \begin{macrocode}
+\newcommand\SB@srcso[1]{\futurelet\SB@temp\SB@@srcso}
+\newcommand\SB@@srcso{%
+ \ifx\SB@temp\SB@srspace%
+ \penalty-5\enskip%
+ \else%
+ \space%
+ \fi%
+ \SB@next%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Verses and Choruses}
+%
+% The following programming typesets song contents, including verses, choruses,
+% and textual notes.
+%
+% \begin{macro}{\ifSB@stanza}
+% The following conditional remembers if we've seen any stanzas yet in the
+% current song.
+% \begin{macrocode}
+\newif\ifSB@stanza
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@stanzabreak}
+% \changes{v1.12}{2005/05/10}{Fixed stanza counting code and improved spacing}
+% End this song stanza and start a new one.
+% \begin{macrocode}
+\newcommand\SB@stanzabreak{%
+ \ifhmode\par\fi%
+ \ifSB@stanza%
+ \SB@breakpoint{%
+ \ifSB@inverse%
+ \ifSB@prevverse\vvpenalty\else\cvpenalty\fi%
+ \else%
+ \ifSB@prevverse\vcpenalty\else\ccpenalty\fi%
+ \fi%
+ }%
+ \vskip\versesep%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@breakpoint}
+% Insert a valid breakpoint into the vertical list comprising a song.
+% \begin{macrocode}
+\newcommand\SB@breakpoint[1]{%
+ \begingroup%
+ \ifnum#1<\@M%
+ \SB@skip\colbotglue\relax%
+ \SB@skip-\SB@skip%
+ \else%
+ \SB@skip\z@skip%
+ \fi%
+ \advance\SB@skip\lastskip%
+ \unskip%
+ \nobreak%
+ \ifnum#1<\@M%
+ \vskip\colbotglue\relax%
+ \penalty#1%
+ \fi%
+ \vskip\SB@skip%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@putbox}
+% Unbox a vbox and follow it by vertical glue if its depth is unusually
+% shallow.
+% This ensures that verses and choruses will look equally spaced even if
+% one of them has a final line with no descenders.
+% \begin{macrocode}
+\newcommand\SB@putbox[2]{%
+ \begingroup%
+ \SB@dimen\dp#2%
+ #1#2%
+ \setbox\SB@box\hbox{{\lyricfont\relax p}}%
+ \ifdim\SB@dimen<\dp\SB@box%
+ \advance\SB@dimen-\dp\SB@box%
+ \vskip-\SB@dimen%
+ \fi%
+ \setbox\SB@box\box\voidb@x%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@obeylines}
+% Within verses and choruses we would like to use |\obeylines| so that each
+% \Meta{return} in the source file ends a paragraph without having to say
+% |\par| explicitly.
+% The \LaTeX{} base code establishes the convention that short-term changes to
+% |\par| will restore |\par| by setting it equal to |\@par|.
+% Long-term (i.e., environment-long) changes to |\par| should therefore
+% redefine |\@par| to restore the desired long-term definition.
+% The following code starts a long-term redefinition of |\par| adhering to
+% these conventions, and extends that definition to \Meta{return} as well.
+% \begin{macrocode}
+\newcommand\SB@obeylines{%
+ \let\par\SB@par%
+ \obeylines%
+ \let\@par\SB@@par%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@par}
+% The following replacement definition of |\par| constructs paragraphs in
+% which page-breaks are disallowed, since no wrapped line in a song should
+% span a page- or column-break.
+% It then inserts an interlinepenalty after the paragraph so that such
+% penalties will appear between consecutive lines in each verse.
+% (Note: The |\endgraf| macro must not be uttered within a local group
+% since this prevents parameters like |\hangindent| from being
+% reset at the conclusion of each paragraph.)
+% \begin{macrocode}
+\newcommand\SB@par{%
+ \ifhmode%
+ \SB@cnt\interlinepenalty%
+ \interlinepenalty\@M%
+ \endgraf%
+ \interlinepenalty\SB@cnt%
+ \ifSB@inchorus%
+ \ifdim\cbarwidth>\z@\nobreak\else\SB@ilpenalty\fi%
+ \else%
+ \SB@ilpenalty%
+ \fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@ilpenalty}
+% By default, breaking a vertical list between paragraphs incurs a penalty
+% of zero.
+% Thus, we only insert an explicit penalty between lines if
+% |\interlinepenalty| is non-zero.
+% This avoids cluttering the vertical list with superfluous zero penalties.
+% \begin{macrocode}
+\newcommand\SB@ilpenalty{%
+ \ifnum\interlinepenalty=\z@\else%
+ \penalty\interlinepenalty%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@@par}
+% This replacement definition of |\@par| restores the |\SB@par| definition of
+% |\par| and then ends the paragraph.
+% \begin{macrocode}
+\newcommand\SB@@par{\let\par\SB@par\par}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@parindent}
+% \changes{v1.12}{2005/05/10}{Added}
+% Reserve a length to remember the current |\parindent|.
+% \begin{macrocode}
+\SB@newdimen\SB@parindent
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@everypar}
+% Reserve a control sequence to hold short-term changes to |\everypar|.
+% \begin{macrocode}
+\newcommand\SB@everypar{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@raggedright}
+% \changes{v1.12}{2005/05/10}{Added}
+% Perform |\raggedright| except don't nuke the |\parindent|.
+% \begin{macrocode}
+\newcommand\SB@raggedright{%
+ \SB@parindent\parindent%
+ \raggedright%
+ \parindent\SB@parindent%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\vnumbered}
+% \changes{v2.1}{2007/08/02}{Renamed.}
+% The following conditional remembers whether this verse is being numbered
+% or not (i.e., it distinguishes between |\beginverse| and |\beginverse*|).
+% \begin{macrocode}
+\newif\ifvnumbered
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@prevverse}
+% Reserve a conditional to remember if the previous block in this song was
+% a verse.
+% \begin{macrocode}
+\newif\ifSB@prevverse
+% \end{macrocode}
+% \end{macro}
+%
+% Before replacing the little-used |verse| environment with a new one,
+% issue a warning if the current definition of |\verse| is not the
+% \LaTeX-default one.
+% This may indicate a package clash.
+% \begin{macrocode}
+\CheckCommand\verse{%
+ \let\\\@centercr%
+ \list{}{%
+ \itemsep\z@%
+ \itemindent-1.5em%
+ \listparindent\itemindent%
+ \rightmargin\leftmargin%
+ \advance\leftmargin1.5em%
+ }%
+ \item\relax%
+}
+% \end{macrocode}
+%
+% \begin{environment}{verse}\MainEnvImpl{verse}
+% \begin{environment}{verse*}
+% \begin{macro}{\beginverse}
+% Begin a new verse.
+% This can be done by beginning a |verse| environment or by using the
+% |\beginverse| macro.
+% The latter must check for a trailing star to determine whether this
+% verse should be numbered.
+% We use |\@ifstar| to scan ahead for the star, but this needs to be done
+% carefully because while scanning we might encounter tokens that
+% should be assigned different catcodes once the verse really begins.
+% Thus, we temporarily invoke |\SB@loadactives| for the duration of
+% |\@ifstar| so that everything gets the right catcode.
+% \begin{macrocode}
+\renewenvironment{verse}
+ {\vnumberedtrue\SB@beginverse}
+ {\SB@endverse}
+\newenvironment{verse*}
+ {\vnumberedfalse\SB@beginverse}
+ {\SB@endverse}
+\newcommand\beginverse{%
+ \begingroup%
+ \SB@loadactives%
+ \@ifstar{\endgroup\vnumberedfalse\SB@beginverse}%
+ {\endgroup\vnumberedtrue\SB@beginverse}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \end{environment}
+%
+% \begin{macro}{\SB@beginverse}
+% \changes{v1.12}{2005/05/10}{Shifted to using \cs{parindent} instead of \cs{everypar} to do indentation}
+% Start the body of a verse.
+% We begin by inserting a mark if |\repchoruses| is active and this verse
+% was preceded by a numbered verse (making this an eligible place to insert
+% a chorus later).
+%
+% Verse numbering is implemented using |\everypar| so that if there is any
+% vertical material between the |\beginverse| and the first line of the
+% verse, that material will come before the verse number.
+% Intervening horizontal material (e.g., |\textnote|) can temporarily
+% clear |\everypar| to defer the verse number until later.
+% \begin{macrocode}
+\newcommand\SB@beginverse{%
+ \ifSB@insong%
+ \ifSB@inverse\SB@errbvv\endverse\fi%
+ \ifSB@inchorus\SB@errbvc\endchorus\fi%
+ \else%
+ \SB@errbvt\beginsong{Unknown Song}%
+ \fi%
+ \ifrepchorus\ifvoid\SB@chorusbox\else%
+ \SB@gotchorustrue%
+ \ifSB@prevverse\ifvnumbered%
+ \marks\SB@cmarkclass{\SB@cmark}%
+ \fi\fi%
+ \fi\fi%
+ \SB@inversetrue%
+ \def\SB@closeall{\endverse\endsong}%
+ \SB@stanzabreak%
+ \versemark\nobreak%
+ \global\SB@stanzatrue%
+ \SB@ifempty\SB@cr@\memorize{\replay[]}%
+ \setbox\SB@box\vbox\bgroup\begingroup%
+ \ifvnumbered%
+ \protected@edef\@currentlabel{\p@versenum\theversenum}%
+ \def\SB@everypar{%
+ \setbox\SB@box\hbox{{\printversenum{\theversenum}}}%
+ \ifdim\wd\SB@box<\versenumwidth%
+ \setbox\SB@box%
+ \hbox to\versenumwidth{\unhbox\SB@box\hfil}%
+ \fi%
+ \ifchorded\vrule\@height\baselineskip\@width\z@\@depth\z@\fi%
+ \placeversenum\SB@box%
+ \gdef\SB@everypar{}%
+ }%
+ \else%
+ \def\SB@everypar{%
+ \ifchorded\vrule\@height\baselineskip\@width\z@\@depth\z@\fi%
+ \gdef\SB@everypar{}%
+ }%
+ \fi%
+ \everypar{\SB@everypar\everypar{}}%
+ \versefont\relax\SB@setbaselineskip\versejustify%
+ \SB@loadactives%
+ \SB@obeylines%
+ \penalty12345 %
+ \everyverse\relax%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@endverse}
+% End a verse.
+% This involves unboxing the verse material with |\SB@putbox|, which
+% corrects for last lines that are unusually shallow.
+% \begin{macrocode}
+\newcommand\SB@endverse{%
+ \ifSB@insong%
+ \ifSB@inverse%
+ \unpenalty%
+ \endgroup\egroup%
+ \SB@putbox\unvbox\SB@box%
+ \SB@inversefalse%
+ \def\SB@closeall{\endsong}%
+ \ifvnumbered\stepcounter{versenum}\fi%
+ \SB@prevversetrue%
+ \else\ifSB@inchorus\SB@errevc\endchorus%
+ \else\SB@errevo\fi\fi%
+ \else%
+ \SB@errevt%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@chorustop}
+% When a chorus is broken in to several pieces by column-breaks (via |\brk|),
+% the following conditional remembers whether the current piece is the
+% topmost one for this chorus.
+% \begin{macrocode}
+\newif\ifSB@chorustop
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chorusbox}
+% When |\repchoruses| is used, the first sequence of consecutive choruses
+% is remembered in the following box register.
+% \begin{macrocode}
+\SB@newbox\SB@chorusbox
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@gotchorus}
+% The following conditional remembers whether we've completed storing the
+% first block of consecutive choruses.
+% \begin{macrocode}
+\newif\ifSB@gotchorus
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@cmarkclass}
+% \begin{macro}{\SB@nocmarkclass}
+% \changes{v2.6}{2008/02/14}{Added safe allocation of extended mark registers}
+% The |\repeatchoruses| feature requires the use of two extended mark
+% classes provided by $\varepsilon$-\TeX.
+% We use the |\newmarks| macro to allocate these classes, if it's
+% available.
+% If |\newmarks| doesn't exist, then that means the user has an
+% $\varepsilon$-\TeX{} compatible version of \LaTeX, but no |etex| style
+% file to go with it;
+% we just have to pick two mark classes and hope that nobody else is
+% using them.
+% \begin{macrocode}
+\ifSB@etex
+ \@ifundefined{newmarks}{
+ \@ifundefined{newmark}{
+ \mathchardef\SB@cmarkclass83
+ \mathchardef\SB@nocmarkclass84
+ }{
+ \newmark\SB@cmarkclass
+ \newmark\SB@nocmarkclass
+ }
+ }{
+ \newmarks\SB@cmarkclass
+ \newmarks\SB@nocmarkclass
+ }
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@cmark}
+% \begin{macro}{\SB@lastcmark}
+% \begin{macro}{\SB@nocmark}
+% To determine where choruses should be inserted when |\repchoruses| is
+% active, three kinds of marks are inserted into song boxes:
+% |\SB@cmark| is used to mark places where a chorus might be inserted between
+% verses, and |\SB@lastcmark| marks a place where a chorus might be inserted
+% after the last verse of the song.
+% Both marks are $\varepsilon$-\TeX{} marks of class |\SB@cmarkclass|,
+% to avoid disrupting the use of standard \TeX{} marks.
+% Each time a chorus is automatically inserted, |\SB@nocmark| is inserted
+% with mark class |\SB@nocmarkclass| just above it (and at the top of each
+% additional page it spans).
+% This inhibits future chorus inserts until the already-inserted chorus has
+% been fully committed to the output file.
+% Otherwise some choruses could get auto-inserted multiple times at the same
+% spot, possibly even leading to an infinite loop!
+% \begin{macrocode}
+\newcommand*\SB@cmark{SB@cmark}
+\newcommand*\SB@lastcmark{SB@lastcmark}
+\newcommand*\SB@nocmark{SB@nocmark}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{chorus}\MainEnvImpl{chorus}
+% \begin{macro}{\beginchorus}
+% \changes{v1.12}{2005/05/10}{Shifted to using \cs{parindent} instead of \cs{everypar} to do indentation}
+% \changes{v1.14}{2005/05/15}{Choruses now stretch like the verses}
+% Start a new chorus.
+% If |\repchoruses| is active and this is part of the first set of consecutive
+% choruses in the song, then include it and its preceding vertical material
+% in the |\SB@chorusbox| for possible later duplication elsewhere.
+% \begin{macrocode}
+\newenvironment{chorus}{\beginchorus}{\SB@endchorus}
+\newcommand\beginchorus{%
+ \ifSB@insong
+ \ifSB@inverse\SB@errbcv\endverse\fi%
+ \ifSB@inchorus\SB@errbcc\endchorus\fi%
+ \else%
+ \SB@errbct\beginsong{Unknown Song}%
+ \fi%
+ \SB@inchorustrue%
+ \def\SB@closeall{\endchorus\endsong}%
+ \SB@chorustoptrue%
+ \vnumberedfalse%
+ \SB@stanzabreak%
+ \chorusmark%
+ \ifrepchorus%
+ \ifSB@gotchorus\else\ifSB@prevverse\else%
+ \global\setbox\SB@chorusbox\vbox{%
+ \unvbox\SB@chorusbox%
+ \SB@stanzabreak%
+ \chorusmark%
+ }%
+ \fi\fi%
+ \fi%
+ \global\SB@stanzatrue%
+ \replay[]%
+ \SB@@beginchorus%
+ \everychorus\relax%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+%
+% \begin{macro}{\SB@@beginchorus}
+% Begin the body of a chorus, or continue the body of a chorus after |\brk|
+% has paused it to insert a valid breakpoint.
+% We insert an empty class-|\SB@cmarkclass| mark here so that this chorus
+% will not be duplicated elsewhere on the same page(s) where it initially
+% appears.
+% \begin{macrocode}
+\newcommand\SB@@beginchorus{%
+ \ifrepchorus\marks\SB@cmarkclass{}\fi%
+ \setbox\SB@box\vbox\bgroup\begingroup%
+ \ifchorded%
+ \def\SB@everypar{%
+ \vrule\@height\baselineskip\@width\z@\@depth\z@%
+ \gdef\SB@everypar{}%
+ }%
+ \everypar{\SB@everypar\everypar{}}%
+ \fi%
+ \chorusfont\relax\SB@setbaselineskip\chorusjustify%
+ \SB@loadactives%
+ \SB@obeylines%
+ \penalty12345 %
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@endchorus}
+% End a chorus.
+% This involves creating the vertical line to the left of the chorus and then
+% unboxing the chorus material that was previously accumulated.
+% \begin{macrocode}
+\newcommand\SB@endchorus{%
+ \ifSB@insong%
+ \ifSB@inchorus%
+ \unpenalty%
+ \endgroup\egroup%
+ \SB@inchorusfalse%
+ \def\SB@closeall{\endsong}%
+ \setbox\SB@box\vbox{%
+ \SB@chorusbar\SB@box%
+ \SB@putbox\unvbox\SB@box%
+ }
+ \ifrepchorus\ifSB@gotchorus\else%
+ \global\setbox\SB@chorusbox\vbox{%
+ \unvbox\SB@chorusbox%
+ \unvcopy\SB@box%
+ }%
+ \fi\fi%
+ \unvbox\SB@box%
+ \SB@prevversefalse%
+ \else\ifSB@inverse\SB@errecv\endverse%
+ \else\SB@erreco\fi\fi%
+ \else%
+ \SB@errect%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@cbarshift}
+% Increase |\leftskip| to accommodate the chorus bar, if any.
+% \begin{macrocode}
+\newcommand\SB@cbarshift{%
+ \ifSB@inchorus\ifdim\cbarwidth>\z@%
+ \advance\leftskip\cbarwidth%
+ \advance\leftskip5\p@\relax%
+ \fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chorusbar}
+% Create the vertical bar that goes to the left of a chorus.
+% Rather than boxing up the chorus in order to put the bar to the left,
+% the bar is introduced as leaders directly into the vertical list of the
+% main song box.
+% This allows it to stretch and shrink when a column is typeset by the
+% page-builder.
+% \begin{macrocode}
+\newcommand\SB@chorusbar[1]{%
+ \ifdim\cbarwidth>\z@%
+ \SB@dimen\ht#1%
+ \SB@dimenii\dp#1%
+ \advance\SB@dimen%
+ \ifSB@chorustop\ifchorded\else2\fi\fi\SB@dimenii%
+ \SB@skip\SB@dimen\relax%
+ \SB@computess\SB@skip1\@plus#1%
+ \SB@computess\SB@skip{-1}\@minus#1%
+ \nointerlineskip\null\nobreak%
+ \leaders\vrule\@width\cbarwidth\vskip\SB@skip%
+ \ifSB@chorustop\ifchorded\else%
+ \advance\SB@skip-\SB@dimenii%
+ \fi\fi%
+ \nobreak\vskip-\SB@skip%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@computess}
+% \changes{v1.14}{2005/05/15}{Added}
+% This computes the stretchability or shrinkability of a vbox and stores
+% the result in the skip register given by \argp{1}.
+% If $\argp{2}=1$ and \argp{3} is ``\texttt{plus}'', then the stretchability
+% of box \argp{4} is added to the plus component of \argp{1}.
+% If $\argp{2}=-1$ and \argp{3} is ``\texttt{minus}'', then the shrinkability
+% of the box is added to the minus component of \argp{1}.
+% If the stretchability or shrinkability is infinite, then we guess 1fil
+% for that component.
+% \begin{macrocode}
+\newcommand\SB@computess[4]{%
+ \begingroup%
+ \vbadness\@M\vfuzz\maxdimen%
+ \SB@dimen4096\p@%
+ \setbox\SB@box\vbox spread#2\SB@dimen{\unvcopy#4}%
+ \ifnum\badness=\z@%
+ \global\advance#1\z@#31fil\relax%
+ \else%
+ \SB@dimenii\SB@dimen%
+ \loop%
+ \SB@dimenii.5\SB@dimenii%
+ \ifnum\badness<100 %
+ \advance\SB@dimen\SB@dimenii%
+ \else
+ \advance\SB@dimen-\SB@dimenii%
+ \fi%
+ \setbox\SB@box\vbox spread#2\SB@dimen{\unvcopy#4}%
+ \ifnum\badness=100 \SB@dimenii\z@\fi%
+ \ifdim\SB@dimenii>.1\p@\repeat%
+ \ifdim\SB@dimen<.1\p@\SB@dimen\z@\fi%
+ \global\advance#1\z@#3\SB@dimen\relax%
+ \fi%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\brk}\MainImpl{brk}
+% Placing |\brk| within a line in a verse or chorus tells \TeX{} to break the
+% line at that point (if it needs to be broken at all).
+%
+% Placing |\brk| on a line by itself within a chorus stops the chorus (and its
+% vertical bar), inserts a valid breakpoint, and then restarts the chorus
+% with no intervening space so that if the breakpoint isn't used, there will
+% be no visible effect.
+% Placing it on a line by itself within a verse just inserts a breakpoint.
+%
+% Placing |\brk| between songs forces a column- or page-break, but only if
+% generating a non-partial list of songs.
+% When generating a partial list, |\brk| between songs is ignored.
+% \begin{macrocode}
+\newcommand\brk{%
+ \ifSB@insong%
+ \ifhmode\penalty-5 \else%
+ \unpenalty%
+ \ifSB@inchorus%
+ \ifdim\cbarwidth=\z@%
+ \ifrepchorus\marks\SB@cmarkclass{}\fi%
+ \SB@breakpoint\brkpenalty%
+ \else%
+ \endgroup\egroup%
+ \ifrepchorus\ifSB@gotchorus\else%
+ \global\setbox\SB@chorusbox\vbox{%
+ \unvbox\SB@chorusbox%
+ \SB@chorusbar\SB@box%
+ \unvcopy\SB@box%
+ \SB@breakpoint\brkpenalty%
+ }%
+ \fi\fi%
+ \SB@chorusbar\SB@box%
+ \unvbox\SB@box%
+ \SB@breakpoint\brkpenalty%
+ \SB@chorustopfalse%
+ \SB@@beginchorus%
+ \fi%
+ \else%
+ \SB@breakpoint\brkpenalty%
+ \fi%
+ \fi%
+ \else%
+ \ifpartiallist\else\SB@nextcol\@ne\colbotglue\fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@boxup}
+% Typeset a shaded box containing a textual note to singers or musicians.
+% We first try typesetting the note on a single line.
+% If it's too big, then we try again in paragraph mode with full
+% justification.
+% \begin{macrocode}
+\newcommand\SB@boxup[1]{%
+ \setbox\SB@box\hbox{{\notefont\relax#1}}%
+ \SB@dimen\wd\SB@box%
+ \advance\SB@dimen6\p@%
+ \advance\SB@dimen\leftskip%
+ \advance\SB@dimen\rightskip%
+ \ifdim\SB@dimen>\hsize%
+ \vbox{{%
+ \advance\hsize-6\p@%
+ \advance\hsize-\leftskip%
+ \advance\hsize-\rightskip%
+ \notejustify%
+ \unhbox\SB@box\par%
+ \kern\z@%
+ }}%
+ \else%
+ \vbox{\box\SB@box\kern\z@}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\textnote}\MainImpl{textnote}
+% \changes{v1.12}{2005/05/10}{Defined unset paragraph parameters}
+% Create a textual note for singers and musicians.
+% If the note begins a verse or chorus, it should not be preceded by any
+% spacing.
+% Verses and choruses begin with the sentinel penalty 12345, so we check
+% |\lastpenalty| to identify this case.
+% When typesetting the note, we must be sure to temporarily clear |\everypar|
+% to inhibit any verse numbering that might be pending.
+% We also readjust the |\baselineskip| as if we weren't doing chords, since
+% no chords go above a textual note.
+% \begin{macrocode}
+\newcommand\textnote[1]{%
+ \ifhmode\par\fi%
+ \ifnum\lastpenalty=12345\else%
+ \ifSB@inverse%
+ \vskip2\p@\relax%
+ \else\ifSB@inchorus%
+ \vskip2\p@\relax%
+ \else\ifSB@stanza%
+ \nobreak\vskip\versesep%
+ \fi\fi\fi%
+ \fi%
+ \begingroup%
+ \everypar{}%
+ \ifchorded\chordedfalse\SB@setbaselineskip\chordedtrue\fi%
+ \placenote{\SB@colorbox\notebgcolor{\SB@boxup{#1}}}%
+ \endgroup%
+ \nobreak%
+ \ifSB@inverse%
+ \vskip2\p@\relax%
+ \else\ifSB@inchorus%
+ \vskip2\p@\relax%
+ \else\ifSB@stanza\else%
+ \nobreak\vskip\versesep%
+ \fi\fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\musicnote}\MainImpl{musicnote}
+% \changes{v1.12}{2005/05/10}{Now just (conditionally) calls \cs{textnote} for consistency}
+% Create a textual note for musicians.
+% \begin{macrocode}
+\newcommand\musicnote[1]{\ifchorded\textnote{#1}\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\echo}\MainImpl{echo}
+% \begin{macro}{\SB@echo}
+% \begin{macro}{\SB@@echo}
+% \changes{v1.21}{2006/09/17}{Customized fonts now preserved.}
+% \changes{v2.1}{2007/08/02}{Toggles instead of forces slanted font.}
+% Typeset an echo part in the lyrics.
+% Echo parts are in a user-customizable font and parenthesized.
+%
+% The |\echo| macro must be able to accept chords in its argument.
+% This complicates the implementation because chord macros should change
+% catcodes, but if we grab |\echo|'s argument in the usual way then all the
+% catcodes will be set before the chord macros have a chance to change them.
+% This would disallow chord name abbreviations like |#| and |&| within
+% |\echo| parts.
+%
+% If we're using $\varepsilon$-\TeX{} then the solution is easy: we use
+% |\scantokens| to re-scan the argument and thereby re-assign the catcodes.
+% (One subtlety: Whenever \LaTeX{} consumes an argument to a macro, it changes
+% |#| to |##| so that when the argument text is substituted into the body of
+% the macro, the replacement text will not contain unsubstituted parameters
+% (such as |#1|).
+% If |\scantokens| is used on the replacement text and the scanned tokens
+% assign a new catcode to |#|, that causes |#|'s to be doubled in the
+% \emph{output}, which was not the intent.
+% To avoid this problem, we use |\@sanitize| before consuming the argument to
+% |\echo|, which sets the catcodes of most special tokens (including |#|) to
+% 12, so that \LaTeX{} will not recognize any of them as parameters and will
+% therefore not double any of them.)
+% \begin{macrocode}
+\ifSB@etex
+ \newcommand\echo{\begingroup\@sanitize\SB@echo}
+ \newcommand\SB@echo[1]{%
+ \endgroup%
+ \begingroup%
+ \echofont\relax%
+ \endlinechar\m@ne%
+ \scantokens{(#1)}%
+ \endgroup%
+ }
+\else
+% \end{macrocode}
+% If we're not using $\varepsilon$-\TeX, we must do something more complicated.
+% We set up the appropriate font within a local group and finish with
+% |\hbox| so that the argument to |\echo| is treated as the body of the box.
+% Control is reacquired after the box using |\aftergroup|, whereupon we
+% unbox the box and insert the closing parenthesis.
+% This almost works except that if the last thing in an echo part is a long
+% chord name atop a short lyric, the closing parenthesis will float out away
+% from the lyric instead of being sucked under the chord.
+% I can find no solution to this problem, so to avoid it users must find a
+% version of \LaTeX{} that is $\varepsilon$-\TeX{} compatible.
+% \begin{macrocode}
+ \newcommand\echo{%
+ \begingroup%
+ \echofont\relax%
+ \afterassignment\SB@echo%
+ \setbox\SB@box\hbox%
+ }
+ \newcommand\SB@echo{\aftergroup\SB@@echo(}
+ \newcommand\SB@@echo{\unhbox\SB@box)\endgroup}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\rep}\MainImpl{rep}
+% \changes{v1.21}{2006/09/17}{Changed to avoid math mode.}
+% Place |\rep{|\Meta{n}|}| at the end of a line to indicate that it should be
+% sung \Meta{n} times.
+% \begin{macrocode}
+\newcommand\rep[1]{%
+ (\raise.25ex\hbox{%
+ \fontencoding{OMS}\fontfamily{cmsy}\selectfont\char\tw@%
+ }#1)%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Scripture Quotations}
+%
+% The macros in this section typeset scripture quotations and other
+% between-songs environments.
+%
+% \begin{environment}{songgroup}\MainEnvImpl{songgroup}
+% A |songgroup| environment associates all enclosed environments
+% with the enclosed song.
+% When generating a partial list, all the enclosed environments are
+% contributed if and only if the enclosed song is contributed.
+% \begin{macrocode}
+\newenvironment{songgroup}{%
+ \ifnum\SB@grouplvl=\z@%
+ \edef\SB@sgroup{\thesongnum}%
+ \global\SB@groupcnt\m@ne%
+ \fi%
+ \advance\SB@grouplvl\@ne%
+}{%
+ \advance\SB@grouplvl\m@ne%
+ \ifnum\SB@grouplvl=\z@\let\SB@sgroup\@empty\fi%
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\SB@grouplvl}
+% Count the |songgroup| environment nesting depth.
+% \begin{macrocode}
+\SB@newcount\SB@grouplvl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{intersong}\MainEnvImpl{intersong}
+% An intersong block contributes vertical material to a column between the
+% songs of a songs section.
+% It is subject to the same column-breaking algorithm as real songs, but
+% receives none of the other formatting applied to songs.
+% \begin{macrocode}
+\newenvironment{intersong}{%
+ \ifSB@insong\SB@errbro\SB@closeall\fi%
+ \ifSB@intersong\SB@errbrr\SB@closeall\fi%
+ \setbox\SB@chorusbox\box\voidb@x%
+ \SB@intersongtrue%
+ \def\SB@closeall{\end{intersong}}%
+ \setbox\SB@songbox\vbox\bgroup\begingroup%
+ \ifnum\SB@numcols>\z@\hsize\SB@colwidth\fi%
+ \ifdim\sbarheight>\z@%
+ \hrule\@height\sbarheight\@width\hsize%
+ \nobreak%
+ \fi%
+}{%
+ \ifSB@intersong
+ \ifdim\sbarheight>\z@%
+ \ifhmode\par\fi%
+ \SB@skip\lastskip%
+ \unskip\nobreak\vskip\SB@skip%
+ \hbox{\vrule\@height\sbarheight\@width\hsize}%
+ \fi%
+ \endgroup\egroup%
+ \ifSB@omitscrip%
+ \setbox\SB@songbox\box\voidb@x%
+ \else%
+ \SB@submitsong%
+ \fi%
+ \SB@intersongfalse%
+ \else%
+ \ifSB@insong\SB@errero\SB@closeall\else\SB@errert\fi%
+ \fi%
+}
+% \end{macrocode}
+% The starred form contributes page-spanning vertical material directly to
+% the top of the nearest fresh page.
+% \begin{macrocode}
+\newenvironment{intersong*}{%
+ \ifSB@insong\SB@errbro\SB@closeall\fi%
+ \ifSB@intersong\SB@errbrr\SB@closeall\fi%
+ \setbox\SB@chorusbox\box\voidb@x%
+ \SB@intersongtrue%
+ \def\SB@closeall{\end{intersong*}}%
+ \setbox\SB@songbox\vbox\bgroup\begingroup%
+}{%
+ \ifSB@intersong%
+ \endgroup\egroup%
+ \ifSB@omitscrip%
+ \setbox\SB@songbox\box\voidb@x%
+ \else%
+ \def\SB@stype{\SB@styppage}%
+ \SB@submitsong%
+ \def\SB@stype{\SB@stypcol}%
+ \fi%
+ \SB@intersongfalse%
+ \else%
+ \ifSB@insong\SB@errero\SB@closeall\else\SB@errert\fi%
+ \fi%
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{scripture}\MainEnvImpl{scripture}
+% \begin{macro}{\beginscripture}
+% Begin a scripture quotation.
+% We first store the reference in a box for later use, and then set up
+% a suitable environment for the quotation.
+% Quotations cannot typically be reworded if line-breaking fails,
+% so we set |\emergencystretch| to a relatively high value at the outset.
+% \begin{macrocode}
+\newenvironment{scripture}{\beginscripture}{\SB@endscripture}
+\newcommand\beginscripture[1]{%
+ \begin{intersong}%
+ \SB@parsesrefs{#1}%
+ \setbox\SB@envbox\hbox{{\printscrcite\songrefs}}%
+ \def\SB@closeall{\endscripture}%
+ \nobreak\vskip5\p@%
+ \SB@parindent\parindent\parindent\z@%
+ \parskip\z@skip\parfillskip\@flushglue%
+ \leftskip\SB@parindent\rightskip\SB@parindent\relax%
+ \scripturefont\relax%
+ \baselineskip\f@size\p@\@plus\p@\relax%
+ \advance\baselineskip\p@\relax%
+ \emergencystretch.3em%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@endscripture}
+% End a scripture quotation.
+% \begin{macrocode}
+\newcommand\SB@endscripture{%
+ \ifSB@intersong
+ \scitehere%
+ \ifhmode\par\fi%
+ \vskip-3\p@%
+ \end{intersong}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+%
+% \begin{macro}{\scitehere}\MainImpl{scitehere}
+% \changes{v2.1}{2007/08/02}{Added}
+% Usually the scripture citation should just come at the |\endscripture|
+% line, but at times the user might want to invoke this macro explicitly
+% at a more suitable point.
+% A good example is when something near the end of the scripture quotation
+% drops \TeX{} into vertical mode.
+% In such cases, it is often better to issue the citation before leaving
+% horizontal mode.
+%
+% In any case, this macro should work decently whether in horizontal or
+% vertical mode.
+% In horizontal mode life is easy: we just append the reference to the
+% current horizontal list using the classic code from p.~106 of The \TeX book.
+% However, if we're now in vertical mode, the problem is a little harder.
+% We do the best we can by using |\lastbox| to remove the last line, then
+% adding the reference and re-typesetting it.
+% This isn't as good as the horizontal mode solution because \TeX{} only
+% gets to reevaluate the last line instead of the whole paragraph, but
+% usually the results are passable.
+% \begin{macrocode}
+\newcommand\scitehere{%
+ \ifSB@intersong%
+ \ifvoid\SB@envbox\else%
+ \ifvmode%
+ \setbox\SB@box\lastbox%
+ \nointerlineskip\noindent\hskip-\leftskip%
+ \unhbox\SB@box\unskip%
+ \fi%
+ \unskip\nobreak\hfil\penalty50\hskip.8em\null\nobreak\hfil%
+ \box\SB@envbox\kern-\SB@parindent%
+ {\parfillskip\z@\finalhyphendemerits2000\par}%
+ \fi%
+ \else%
+ \SB@errscrip\scitehere%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\Acolon}\MainImpl{Acolon}
+% \begin{macro}{\Bcolon}\MainImpl{Bcolon}
+% \changes{v1.13}{2005/05/12}{Added}
+% Typeset a line of poetry in a scripture quotation.
+% \begin{macrocode}
+\newcommand\Acolon{\SB@colon2\Acolon}
+\newcommand\Bcolon{\SB@colon1\Bcolon}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@colon}
+% Begin a group of temporary definitions that will end at the next
+% \Meta{return}.
+% The \Meta{return} will end the paragraph and close the local scope.
+% \begin{macrocode}
+\newcommand\SB@colon[2]{%
+ \ifSB@intersong\else%
+ \SB@errscrip#2%
+ \beginscripture{Unknown}%
+ \fi%
+ \ifhmode\par\fi%
+ \begingroup%
+ \rightskip\SB@parindent\@plus4em%
+ \advance\leftskip2\SB@parindent%
+ \advance\parindent-#1\SB@parindent%
+ \def\par{\endgraf\endgroup}%
+ \obeylines%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\strophe}\MainImpl{strophe}
+% \changes{v1.13}{2005/05/12}{Added}
+% Insert blank space indicative of a strophe division in a scripture quotation.
+% \begin{macrocode}
+\newcommand\strophe{%
+ \ifSB@intersong\else%
+ \SB@errscrip\strophe\beginscripture{Unknown}%
+ \fi%
+ \vskip.9ex\@plus.45ex\@minus.68ex\relax%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\scripindent}\MainImpl{scripindent}
+% \begin{macro}{\scripoutdent}\MainImpl{scripoutdent}
+% \begin{macro}{\SB@scripdent}
+% \changes{v1.13}{2005/05/12}{Added}
+% Create an indented sub-block within a scripture quotation.
+% \begin{macrocode}
+\newcommand\SB@scripdent[2]{%
+ \ifSB@intersong\else%
+ \SB@errscrip#2\beginscripture{Unknown}%
+ \fi%
+ \ifhmode\par\fi%
+ \advance\leftskip#1\SB@parindent\relax%
+}
+\newcommand\scripindent{\SB@scripdent1\scripindent}
+\newcommand\scripoutdent{\SB@scripdent-\scripoutdent}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\shiftdblquotes}\MainImpl{shiftdblquotes}
+% \changes{v1.13}{2005/05/12}{Added}
+% \begin{macro}{\SB@ldqleft}
+% \begin{macro}{\SB@ldqright}
+% \begin{macro}{\SB@rdqleft}
+% \begin{macro}{\SB@rdqright}
+% \begin{macro}{\SB@scanlq}
+% \begin{macro}{\SB@scanrq}
+% \begin{macro}{\SB@dolq}
+% \begin{macro}{\SB@dorq}
+% The Zaph Chancery font used by default to typeset scripture quotations
+% seems to have some kerning problems with double-quote ligatures. The
+% |\shiftdblquotes| macro allows one to modify the spacing around all
+% double-quotes until the current group ends.
+% \begin{macrocode}
+\newcommand\SB@quotesactive{%
+ \catcode`'\active%
+ \catcode``\active%
+}
+\newcommand\shiftdblquotes[4]{}
+\newcommand\SB@ldqleft{}
+\newcommand\SB@ldqright{}
+\newcommand\SB@rdqleft{}
+\newcommand\SB@rdqright{}
+\newcommand\SB@scanlq{}
+\newcommand\SB@scanrq{}
+\newcommand\SB@dolq{}
+\newcommand\SB@dorq{}
+{
+ \SB@quotesactive
+ \gdef\shiftdblquotes#1#2#3#4{%
+ \def\SB@ldqleft{\kern#1}%
+ \def\SB@ldqright{\kern#2}%
+ \def\SB@rdqleft{\kern#3}%
+ \def\SB@rdqright{\kern#4}%
+ \SB@quotesactive%
+ \def`{\futurelet\SB@next\SB@scanlq}%
+ \def'{\futurelet\SB@next\SB@scanrq}%
+ }
+ \gdef\SB@scanlq{%
+ \ifx\SB@next`%
+ \expandafter\SB@dolq%
+ \else%
+ \expandafter\lq%
+ \fi%
+ }
+ \gdef\SB@scanrq{%
+ \ifx\SB@next'%
+ \expandafter\SB@dorq%
+ \else%
+ \expandafter\rq%
+ \fi%
+ }
+ \gdef\SB@dolq`{%
+ \ifvmode\leavevmode\else\/\fi%
+ \vadjust{}%
+ \SB@ldqleft\lq\lq\SB@ldqright%
+ \vadjust{}%
+ }
+ \gdef\SB@dorq'{%
+ \ifvmode\leavevmode\else\/\fi%
+ \vadjust{}%
+ \SB@rdqleft\rq\rq\SB@rdqright%
+ \vadjust{}%
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Transposition}
+%
+% The macros that transpose chords are contained in this section.
+%
+% \begin{macro}{\SB@transposefactor}
+% This counter identifies the requested number of halfsteps by which chords are
+% to be transposed (from $-11$ to $+11$).
+% \begin{macrocode}
+\SB@newcount\SB@transposefactor
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@convertnotes}
+% Even when transposition is not requested, the transposition logic can be
+% used to automatically convert note names to another form.
+% The following conditional turns that feature on or off.
+% \begin{macrocode}
+\newif\ifSB@convertnotes
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\notenameA}
+% \begin{macro}{\notenameB}
+% \begin{macro}{\notenameC}
+% \begin{macro}{\notenameD}
+% \begin{macro}{\notenameE}
+% \begin{macro}{\notenameF}
+% \begin{macro}{\notenameG}
+% Reserve a control sequence for each note of the diatonic scale.
+% These will be used to identify which token sequences the input file uses
+% to denote the seven scale degrees.
+% Their eventual definitions \emph{must} consist entirely of uppercase
+% letters, and they must be assigned using |\def|, but that comes later.
+% \begin{macrocode}
+\newcommand\notenameA{}
+\newcommand\notenameB{}
+\newcommand\notenameC{}
+\newcommand\notenameD{}
+\newcommand\notenameE{}
+\newcommand\notenameF{}
+\newcommand\notenameG{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\printnoteA}
+% \begin{macro}{\printnoteB}
+% \begin{macro}{\printnoteC}
+% \begin{macro}{\printnoteD}
+% \begin{macro}{\printnoteE}
+% \begin{macro}{\printnoteF}
+% \begin{macro}{\printnoteG}
+% These control sequences are what the transposition logic actually
+% outputs to denote each scale degree.
+% They can include any \LaTeX{} code that is legal in horizontal mode.
+% \begin{macrocode}
+\newcommand\printnoteA{}
+\newcommand\printnoteB{}
+\newcommand\printnoteC{}
+\newcommand\printnoteD{}
+\newcommand\printnoteE{}
+\newcommand\printnoteF{}
+\newcommand\printnoteG{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\notenamesin}\MainImpl{notenamesin}
+% Set the note names used by the input file.
+% \begin{macrocode}
+\newcommand\notenamesin[7]{%
+ \def\notenameA{#1}%
+ \def\notenameB{#2}%
+ \def\notenameC{#3}%
+ \def\notenameD{#4}%
+ \def\notenameE{#5}%
+ \def\notenameF{#6}%
+ \def\notenameG{#7}%
+ \SB@convertnotestrue%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\notenamesout}\MainImpl{notenamesout}
+% Set the note names that are output by the transposition logic.
+% \begin{macrocode}
+\newcommand\notenamesout[7]{%
+ \def\printnoteA{#1}%
+ \def\printnoteB{#2}%
+ \def\printnoteC{#3}%
+ \def\printnoteD{#4}%
+ \def\printnoteE{#5}%
+ \def\printnoteF{#6}%
+ \def\printnoteG{#7}%
+ \SB@convertnotestrue%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\notenames}\MainImpl{notenames}
+% Set an identical input name and output name for each scale degree.
+% \begin{macrocode}
+\newcommand\notenames[7]{%
+ \notenamesin{#1}{#2}{#3}{#4}{#5}{#6}{#7}%
+ \notenamesout{#1}{#2}{#3}{#4}{#5}{#6}{#7}%
+ \SB@convertnotesfalse%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\alphascale}\MainImpl{alphascale}
+% \begin{macro}{\solfedge}\MainImpl{solfedge}
+% Predefine scales for alphabetic names and solfedge names, and
+% set alphabetic scales to be the default.
+% \begin{macrocode}
+\newcommand\alphascale{\notenames ABCDEFG}
+\newcommand\solfedge{\notenames{LA}{SI}{DO}{RE}{MI}{FA}{SOL}}
+\alphascale
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@prefshrps}
+% When a transposed chord falls on a black key, the code must choose which
+% enharmonically equivalent name to give the new chord.
+% (For example, should C transposed by +1 be named C$\#$ or D$\flat$?)
+% A heuristic is used to guess which name is most appropriate.
+% The following conditional records whether the current key signature is
+% sharped or flatted according to this heuristic guess.
+% \begin{macrocode}
+\newif\ifSB@prefshrps
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@needkey}
+% The first chord seen is usually the best indicator of the key of the song.
+% (Even when the first chord isn't the tonic, it will often be the dominant
+% or subdominant, which usually has the same kind of accidental in its key
+% signatures as the actual key.) This conditional remembers whether the current
+% chord is the first one seen in the song, and should therefore be used to
+% guess the key of the song.
+% \begin{macrocode}
+\newif\ifSB@needkey
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\transpose}\MainImpl{transpose}
+% The |\transpose| macro sets the transposition adjustment factor and
+% informs the transposition logic that the next chord seen will be the first
+% one in the new key.
+% \begin{macrocode}
+\newcommand\transpose[1]{%
+ \advance\SB@transposefactor by#1\relax%
+ \SB@cnt\SB@transposefactor%
+ \divide\SB@cnt12 %
+ \multiply\SB@cnt12 %
+ \advance\SB@transposefactor-\SB@cnt%
+ \SB@needkeytrue%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\capo}\MainImpl{capo}
+% Specifying a |\capo| normally just causes a textual note to musicians to be
+% typeset, but if the |transposecapos| option is active, it activates
+% transposition of the chords.
+% \begin{macrocode}
+\newcommand\capo[1]{%
+ \iftranscapos\transpose{#1}\else\musicnote{capo #1}\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prefersharps}\MainImpl{prefersharps}
+% \begin{macro}{\preferflats}\MainImpl{preferflats}
+% One of these macros is called after the first chord has been seen to
+% register that we're transposing to a key with a sharped or flatted key
+% signature.
+% \begin{macrocode}
+\newcommand\prefersharps{\SB@prefshrpstrue\SB@needkeyfalse}
+\newcommand\preferflats{\SB@prefshrpsfalse\SB@needkeyfalse}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\transposehere}\MainImpl{transposehere}
+% If automatic transposition has been requested, yield the given chord
+% transposed by the requested amount.
+% Otherwise return the given chord verbatim.
+% \begin{macrocode}
+\newcommand\transposehere[1]{%
+ \ifnum\SB@transposefactor=\z@%
+ \ifSB@convertnotes%
+ \SB@dotranspose{#1}%
+ \the\SB@toks%
+ \else%
+ #1%
+ \fi%
+ \else%
+ \ifSB@convertnotes%
+ {\SB@transposefactor\z@%
+ \SB@dotranspose{#1}%
+ \xdef\SB@tempv{\the\SB@toks}}%
+ \else%
+ \def\SB@tempv{#1}%
+ \fi%
+ \SB@dotranspose{#1}%
+ \expandafter\trchordformat\expandafter{\SB@tempv}{\the\SB@toks}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\notrans}\MainImpl{notrans}
+% Suppress chord transposition without suppressing note name conversion.
+% When a |\notrans{|\Meta{text}|}| macro appears within text undergoing
+% transposition, the |\notrans| macro and the group will be preserved
+% verbatim by the transposition parser.
+% When it is then expanded after parsing, we must therefore re-invoke
+% the transposition logic on the argument, but in an environment where
+% the transposition factor has been temporarily set to zero.
+% This causes note name conversion to occur without actually transposing.
+% \begin{macrocode}
+\newcommand\notrans[1]{%
+ \begingroup%
+ \SB@transposefactor\z@%
+ \transposehere{#1}%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@dotranspose}
+% Parse the argument to a chord macro, yielding the transposed equivalent in
+% the |\SB@toks| token register.
+% \begin{macrocode}
+\newcommand\SB@dotranspose[1]{%
+ \SB@toks{}%
+ \let\SB@dothis\SB@trmain%
+ \SB@trscan#1\SB@trend%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\trchordformat}\MainImpl{trchordformat}
+% By default, transposing means replacing old chords with new chords in the
+% new key. However, sometimes the user may want to typeset something more
+% sophisticated, like old chords followed by new chords in parentheses so
+% that musicians who use capos and those who don't can play from the same
+% piece of music. Such typesetting is possible by redefining the following
+% macro to something like |#1 (#2)| instead of |#2|.
+% \begin{macrocode}
+\newcommand\trchordformat[2]{#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trscan}
+% This is the entrypoint to the code that scans over the list of tokens
+% comprising a chord and transposes note names as it goes.
+% Start by peeking ahead at the next symbol without consuming it.
+% \begin{macrocode}
+\newcommand\SB@trscan{\futurelet\SB@next\SB@dothis}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trmain}
+% Test to see whether the token was a begin-brace, end-brace, or space.
+% These tokens require special treatment because they cannot be
+% accepted as implicit arguments to macros.
+% \begin{macrocode}
+\newcommand\SB@trmain{%
+ \ifx\SB@next\bgroup%
+ \let\SB@donext\SB@trgroup%
+ \else\ifx\SB@next\egroup%
+ \SB@toks\expandafter{\the\SB@toks\egroup}%
+ \let\SB@donext\SB@trskip%
+ \else\ifcat\noexpand\SB@next\@sptoken%
+ \SB@appendsp\SB@toks%
+ \let\SB@donext\SB@trskip%
+ \else%
+ \let\SB@donext\SB@trstep%
+ \fi\fi\fi%
+ \SB@donext%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trgroup}
+% A begin-group brace lies next in the input stream.
+% Consume the entire group as an argument to this macro, and append it,
+% including the begin- and end-group tokens, to the list of tokens processed
+% so far.
+% No transposition takes place within a group; they are copied verbatim
+% because they probably contain macro code.
+% \begin{macrocode}
+\newcommand\SB@trgroup[1]{%
+ \SB@toks\expandafter{\the\SB@toks{#1}}%
+ \SB@trscan%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trskip}
+% A space or end-brace lies next in the input stream.
+% It has already been added to the token list, so skip over it.
+% \begin{macrocode}
+\newcommand\SB@trskip{%
+ \afterassignment\SB@trscan%
+ \let\SB@next= }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trstep}
+% A non-grouping token lies next in the input stream.
+% Consume it as an argument to this macro, and then test it to see whether
+% it's a note letter or some other recognized item.
+% If so, process it; otherwise just append it to the token list and continue
+% scanning.
+% \begin{macrocode}
+\newcommand\SB@trstep[1]{%
+ \let\SB@donext\SB@trscan%
+ \ifcat\noexpand\SB@next A%
+ \ifnum\uccode`#1=`#1%
+ \def\SB@temp{#1}%
+ \let\SB@dothis\SB@trnote%
+ \else%
+ \SB@toks\expandafter{\the\SB@toks#1}%
+ \fi%
+ \else\ifx\SB@next\SB@trend
+ \let\SB@donext\relax%
+ \else%
+ \SB@toks\expandafter{\the\SB@toks#1}%
+ \fi\fi%
+ \SB@donext%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trnote}
+% We're in the midst of processing a sequence of uppercase letters that
+% might comprise a note name.
+% Check to see whether the next token is an accidental (sharp or flat),
+% or yet another letter.
+% \begin{macrocode}
+\newcommand\SB@trnote{%
+ \ifcat\noexpand\SB@next A%
+ \let\SB@donext\SB@trnotestep%
+ \else\ifnum\SB@transposefactor=\z@%
+ \SB@cnt\z@%
+ \let\SB@donext\SB@trtrans%
+ \else\ifx\SB@next\flt%
+ \SB@cnt\m@ne%
+ \let\SB@donext\SB@tracc%
+ \else\ifx\SB@next\shrp%
+ \SB@cnt\@ne%
+ \let\SB@donext\SB@tracc%
+ \else%
+ \SB@cnt\z@%
+ \let\SB@donext\SB@trtrans%
+ \fi\fi\fi\fi%
+ \SB@donext%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trnotestep}
+% The next token is a letter.
+% Consume it and test to see whether it is an uppercase letter.
+% If so, add it to the note name being assembled; otherwise reinsert it into
+% the input stream and jump directly to the transposition logic.
+% \begin{macrocode}
+\newcommand\SB@trnotestep[1]{%
+ \ifnum\uccode`#1=`#1%
+ \SB@app\def\SB@temp{#1}%
+ \expandafter\SB@trscan%
+ \else%
+ \SB@cnt\z@%
+ \expandafter\SB@trtrans\expandafter#1%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@tracc}
+% We've encountered an accidental (sharp or flat) immediately following a
+% note name.
+% Peek ahead at the next token without consuming it, and then jump to the
+% transposition logic.
+% This is done because the transposition logic might need to infer the key
+% signature of the song, and if the next token is an m (for minor), then
+% that information can help.
+% \begin{macrocode}
+\newcommand\SB@tracc[1]{\futurelet\SB@next\SB@trtrans}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trtrans}
+% We've assembled a sequence of capital letters (in |\SB@temp|) that might
+% comprise a note name to be transposed.
+% If the letters were followed by a |\shrp| then |\SB@cnt| is 1; if they were
+% followed by a |\flt| then it is $-1$; otherwise it is 0.
+% If the assembled letters turn out to not match any valid note name, then
+% do nothing and return to scanning.
+% Otherwise compute a new transposed name.
+% \begin{macrocode}
+\newcommand\SB@trtrans{%
+ \advance\SB@cnt%
+ \ifx\SB@temp\notenameA\z@%
+ \else\ifx\SB@temp\notenameB\tw@%
+ \else\ifx\SB@temp\notenameC\thr@@%
+ \else\ifx\SB@temp\notenameD5 %
+ \else\ifx\SB@temp\notenameE7 %
+ \else\ifx\SB@temp\notenameF8 %
+ \else\ifx\SB@temp\notenameG10 %
+ \else-99 \fi\fi\fi\fi\fi\fi\fi%
+ \ifnum\SB@cnt<\m@ne%
+ \SB@toks\expandafter\expandafter\expandafter{%
+ \expandafter\the\expandafter\SB@toks\SB@temp}%
+ \else%
+ \advance\SB@cnt\SB@transposefactor%
+ \ifnum\SB@cnt<\z@\advance\SB@cnt12 \fi%
+ \ifnum\SB@cnt>11 \advance\SB@cnt-12 \fi%
+ \ifSB@needkey\ifnum\SB@transposefactor=\z@\else\SB@setkeysig\fi\fi%
+ \edef\SB@temp{%
+ \the\SB@toks%
+ \ifSB@prefshrps%
+ \ifcase\SB@cnt\printnoteA\or\printnoteA\noexpand\shrp\or%
+ \printnoteB\or\printnoteC\or\printnoteC\noexpand\shrp\or%
+ \printnoteD\or\printnoteD\noexpand\shrp\or\printnoteE\or%
+ \printnoteF\or\printnoteF\noexpand\shrp\or\printnoteG\or%
+ \printnoteG\noexpand\shrp\fi%
+ \else%
+ \ifcase\SB@cnt\printnoteA\or\printnoteB\noexpand\flt\or%
+ \printnoteB\or\printnoteC\or\printnoteD\noexpand\flt\or%
+ \printnoteD\or\printnoteE\noexpand\flt\or\printnoteE\or%
+ \printnoteF\or\printnoteG\noexpand\flt\or\printnoteG\or%
+ \printnoteA\noexpand\flt\fi%
+ \fi}%
+ \SB@toks\expandafter{\SB@temp}%
+ \fi%
+ \let\SB@dothis\SB@trmain%
+ \SB@trscan%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@setkeysig}
+% If this is the first chord of the song, assume that this is the tonic of the
+% key, and select whether to use a sharped or flatted key signature for the
+% rest of the song based on that.
+% Even if this isn't the tonic, it's probably the dominant or sub-dominant,
+% which almost always has a number of sharps or flats similar to the tonic.
+% If the bottom note of the chord turns out to be a black key, we choose the
+% enharmonic equivalent that is closest to C on the circle of fifths
+% (i.e., the one that has fewest sharps or flats).
+% \begin{macrocode}
+\newcommand\SB@setkeysig{%
+ \global\SB@needkeyfalse%
+ \ifcase\SB@cnt%
+ \global\SB@prefshrpstrue\or% A
+ \global\SB@prefshrpsfalse\or% Bb
+ \global\SB@prefshrpstrue\or% B
+ \ifx\SB@next m% C
+ \global\SB@prefshrpsfalse%
+ \else%
+ \global\SB@prefshrpstrue%
+ \fi\or%
+ \global\SB@prefshrpstrue\or% C#
+ \ifx\SB@next m% D
+ \global\SB@prefshrpsfalse%
+ \else%
+ \global\SB@prefshrpstrue%
+ \fi\or%
+ \global\SB@prefshrpsfalse\or% Eb
+ \global\SB@prefshrpstrue\or% E
+ \global\SB@prefshrpsfalse\or% F
+ \global\SB@prefshrpstrue\or% F#
+ \ifx\SB@next m% G
+ \global\SB@prefshrpsfalse%
+ \else%
+ \global\SB@prefshrpstrue%
+ \fi\or%
+ \global\SB@prefshrpsfalse\else% Ab
+ \global\SB@needkeytrue% non-chord
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@trend}
+% The following macro marks the end of chord text to be processed.
+% It should always be consumed and discarded by the chord-scanning
+% logic above, so generate an error if it is ever expanded.
+% \begin{macrocode}
+\newcommand\SB@trend{%
+ \SB@Error{Internal Error: Transposition failed}%
+ {This error should not occur.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Measure Bars}
+%
+% The following code handles the typesetting of measure bars.
+%
+% \begin{macro}{\SB@metertop}
+% \begin{macro}{\SB@meterbot}
+% These macros remember the current numerator and denominator of the meter.
+% \begin{macrocode}
+\newcommand\SB@metertop{}
+\newcommand\SB@meterbot{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\meter}\MainImpl{meter}
+% Set the current meter without producing an actual measure bar yet.
+% \begin{macrocode}
+\newcommand\meter[2]{\gdef\SB@metertop{#1}\gdef\SB@meterbot{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@measuremark}
+% Normally measure bar boxes should be as thin as possible so that they can be
+% slipped into lyrics without making them hard to read. But when two measure
+% bars appear consecutively, they need to be spaced apart more so that they
+% look like two separate lines instead of one thick line. To achieve this,
+% there needs to be a way to pull a vbox off the current list and determine
+% whether or not it is a box that contains a measure bar. The solution is to
+% insert a mark (|\SB@measuremark|) at the top of each measure bar vbox.
+% We can then see whether this measure bar immediately follows another measure
+% bar by using |\vsplit| on |\lastbox|.
+% \begin{macrocode}
+\newcommand\SB@measuremark{SB@IsMeasure}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@makembar}\MainImpl{mbar}
+% Typeset a measure bar. If provided, \argp{1} is the numerator and \argp{2} is
+% the denominator of the meter to be rendered above the bar. If those arguments
+% are left blank, render a measure bar without a meter marking.
+% \begin{macrocode}
+\newcommand\SB@makembar[2]{%
+ \ifSB@inverse\else%
+ \ifSB@inchorus\else\SB@errmbar\fi%
+ \fi%
+ \ifhmode%
+ \SB@skip\lastskip\unskip%
+ \setbox\SB@box\lastbox%
+ \copy\SB@box%
+ \ifvbox\SB@box%
+ \begingroup%
+ \setbox\SB@boxii\copy\SB@box%
+ \vbadness\@M\vfuzz\maxdimen%
+ \setbox\SB@boxii%
+ \vsplit\SB@boxii to\maxdimen%
+ \endgroup%
+ \long\edef\SB@temp{\splitfirstmark}%
+ \ifx\SB@temp\SB@measuremark%
+ \penalty100\hskip1em%
+ \else%
+ \penalty100\hskip\SB@skip%
+ \fi%
+ \else%
+ \penalty100\hskip\SB@skip%
+ \fi%
+ \fi%
+ \ifvmode\leavevmode\fi%
+ \setbox\SB@box\hbox{{\meterfont\relax#1}}%
+ \setbox\SB@boxii\hbox{{\meterfont\relax#2}}%
+ \SB@dimen\wd\ifdim\wd\SB@box>\wd\SB@boxii\SB@box\else\SB@boxii\fi%
+ \SB@dimenii\baselineskip%
+ \advance\SB@dimenii-2\p@%
+ \advance\SB@dimenii-\ht\SB@box%
+ \advance\SB@dimenii-\dp\SB@box%
+ \advance\SB@dimenii-\ht\SB@boxii%
+ \advance\SB@dimenii-\dp\SB@boxii%
+ \let\SB@temp\relax%
+ \ifdim\SB@dimen>\z@%
+ \advance\SB@dimenii-.75\p@%
+ \def\SB@temp{\kern.75\p@}%
+ \fi%
+ \SB@maxmin\SB@dimen<{.5\p@}%
+ \SB@maxmin\SB@dimenii<\z@%
+ \vbox{%
+ \mark{\SB@measuremark}%
+ \hbox to\SB@dimen{%
+ \hfil%
+ \box\SB@box%
+ \hfil%
+ }%
+ \nointerlineskip%
+ \hbox to\SB@dimen{%
+ \hfil%
+ \box\SB@boxii%
+ \hfil%
+ }%
+ \SB@temp%
+ \nointerlineskip%
+ \hbox to\SB@dimen{%
+ \hfil%
+ \vrule\@width.5\p@\@height\SB@dimenii%
+ \hfil%
+ }%
+ }%
+ \meter{}{}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mbar}
+% The |\mbar| macro invokes |\SB@mbar|, which gets redefined by macros and
+% options that turn measure bars on and off.
+% \begin{macrocode}
+\newcommand\mbar{\SB@mbar}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\measurebar}\MainImpl{measurebar}
+% Make a measure bar using the most recently defined meter.
+% Then set the meter to nothing so that the next measure bar will not
+% display any meter unless the meter changes.
+% \begin{macrocode}
+\newcommand\measurebar{%
+ \mbar\SB@metertop\SB@meterbot%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@repcolon}
+% Create the colon that preceeds or follows a repeat sign.
+% \begin{macrocode}
+\newcommand\SB@repcolon{{%
+ \usefont{OT1}{cmss}{m}{n}\selectfont%
+ \ifchorded%
+ \baselineskip.5\SB@dimen%
+ \vbox{\hbox{:}\hbox{:}\kern.5\p@}%
+ \else%
+ \raise.5\p@\hbox{:}%
+ \fi%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\lrep}\MainImpl{lrep}
+% Create a begin-repeat sign.
+% \begin{macrocode}
+\newcommand\lrep{%
+ \SB@dimen\baselineskip%
+ \advance\SB@dimen-2\p@%
+ \vrule\@width1.5\p@\@height\SB@dimen\@depth\p@%
+ \kern1.5\p@%
+ \vrule\@width.5\p@\@height\SB@dimen\@depth\p@%
+ \SB@repcolon%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\rrep}\MainImpl{rrep}
+% Create an end-repeat sign.
+% \begin{macrocode}
+\newcommand\rrep{%
+ \SB@dimen\baselineskip%
+ \advance\SB@dimen-2\p@%
+ \SB@repcolon%
+ \vrule\@width.5\p@\@height\SB@dimen\@depth\p@%
+ \kern1.5\p@%
+ \vrule\@width1.5\p@\@height\SB@dimen\@depth\p@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Lyric Scanning}\label{sec:lyricscan}
+%
+% The obvious way to create a chord macro is as a normal macro with
+% two arguments, one for the chord name and one for the lyrics to go
+% under the chord---e.g.~|\chord{|\Meta{chordname}|}{|\Meta{lyric}|}|.
+% However, in practice such a macro is extremely cumbersome and
+% difficult to use.
+% The problem is that in order to use such a macro properly, the user
+% must remember a bunch of complex style rules that govern what
+% part of the lyric text needs to go in the \Meta{lyric} parameter and
+% what part should be typed after the closing brace.
+% To avoid separating a word from its trailing punctuation, the
+% \Meta{lyric} parameter must often include punctuation but not certain
+% special punctuation like hyphens, should include the rest of the
+% word but not if there's another chord in the word, should omit
+% measure bars but only if measure bars are being shown, etc.
+% This is way too difficult for the average user.
+%
+% To avoid this problem, we define chords using a one-argument macro
+% (the argument is the chord name), but with no explicit argument for
+% the lyric part.
+% Instead, the macro scans ahead in the input stream, automatically
+% determining what portion of the lyric text that follows should be
+% sucked in as an implicit second argument.
+% The following code does this look-ahead scanning.
+%
+% \begin{macro}{\ifSB@wordends}
+% \begin{macro}{\ifSB@brokenword}
+% Chord macros must look ahead in the input stream to see whether this chord
+% is immediately followed by whitespace or the remainder of a word.
+% If the latter, hyphenation might need to be introduced.
+% These macros keep track of the need for hyphenation, if any.
+% \begin{macrocode}
+\newif\ifSB@wordends
+\newif\ifSB@brokenword
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@lyric}
+% Lyrics appearing after a chord are scanned into the following token list
+% register.
+% \begin{macrocode}
+\SB@newtoks\SB@lyric
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@numhyps}
+% Hyphens appearing in lyrics require special treatment.
+% The following counter counts the number of explicit hyphens ending
+% the lyric syllable that follows the current chord.
+% \begin{macrocode}
+\SB@newcount\SB@numhyps
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@lyricnohyp}
+% When a lyric syllable under a chord ends in exactly one hyphen, the
+% following token register is set to be the syllable without the hyphen.
+% \begin{macrocode}
+\SB@newtoks\SB@lyricnohyp
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@lyricbox}
+% \begin{macro}{\SB@chordbox}
+% The following two boxes hold the part of the lyric text that is to be
+% typeset under the chord, and the chord text that is to be typeset above.
+% \begin{macrocode}
+\SB@newbox\SB@lyricbox
+\SB@newbox\SB@chordbox
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chbstok}
+% \changes{v1.22}{2007/05/15}{Added.}
+% When |\MultiwordChords| is active, the following reserved control
+% sequence remembers the first (space) token not yet included into the
+% |\SB@lyricbox| box.
+% \begin{macrocode}
+\newcommand\SB@chbstok{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@setchord}
+% \changes{v2.3}{2007/09/23}{Support replayed chords over ligatures}
+% \changes{v2.7}{2009/01/08}{Extend rather than replace chordbox}
+% \changes{v3.0}{2017/04/19}{Fix transposition of replayed chord over ligature}
+% The following macro typesets its argument as a chord and stores the
+% result in box |\SB@chordbox| for later placement into the document.
+% The hat token (|^|) is redefined so that outside of math mode it
+% suppresses chord memorization, but inside of math mode it retains
+% its usual superscript meaning.
+% If memorization is active, the chord's token sequence is stored in
+% the current replay register.
+% If |\SB@chordbox| is non-empty, the new chord is appended to it
+% rather than replacing it.
+% This allows consecutive chords not separated by whitespace to be
+% typeset as a single chord sequence atop a common lyric.
+% \begin{macrocode}
+\newcommand\SB@setchord{}
+{
+ \catcode`^\active
+ \gdef\SB@setchord#1{%
+ \SB@gettabindtrue\SB@nohattrue%
+ \setbox\SB@chordbox\hbox{%
+ \unhbox\SB@chordbox%
+ \begingroup%
+ \ifSB@trackch%
+ \let\SB@activehat\SB@hat@tr%
+ \else%
+ \let\SB@activehat\SB@hat@notr%
+ \fi%
+ \let^\SB@activehat%
+ \printchord{%
+ \ifSB@firstchord\else\kern.15em\fi%
+ \vphantom/%
+ \transposehere{#1}%
+ \kern.2em%
+ }%
+ \endgroup%
+ }%
+ \SB@gettabindfalse%
+ \ifSB@trackch\ifSB@nohat%
+ \global\SB@creg\expandafter{\the\SB@creg#1\\}%
+ \fi\fi%
+ \let\SB@noreplay\@firstofone%
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@outertest}
+% \begin{macro}{\SB@otesta}
+% \begin{macro}{\SB@otestb}
+% The lyric-scanning code must preemptively determine whether the next token
+% is a macro declared |\outer| before it tries to accept that token as an
+% argument.
+% Otherwise \TeX{} will abort with a parsing error.
+% Macros declared |\outer| are not allowed in arguments, so determining
+% whether a token is |\outer| is a delicate process.
+% The following does so by consulting |\meaning|.
+% A macro can be identified as |\outer| if its meaning has the
+% word ``|\outer|'' before the first colon.
+% \begin{macrocode}
+\newcommand\SB@outertest{%
+ \expandafter\SB@otesta\meaning\SB@next:\SB@otesta%
+}
+\newcommand\SB@otesta{}
+\edef\SB@otesta#1:#2\SB@otesta{%
+ \noexpand\SB@otestb%
+ #1\string\outer%
+ \noexpand\SB@otestb%
+}
+\newcommand\SB@otestb{}
+\expandafter\def\expandafter\SB@otestb%
+\expandafter#\expandafter1\string\outer#2\SB@otestb{%
+ \def\SB@temp{#2}%
+ \ifx\SB@temp\@empty\SB@testfalse\else\SB@testtrue\fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@UTFtest}
+% \begin{macro}{\SB@U@two}
+% \begin{macro}{\SB@U@three}
+% \begin{macro}{\SB@U@four}
+% \begin{macro}{\SB@@UTFtest}
+% \changes{v1.22}{2007/05/15}{Added.}
+% To support UTF-8 encoded \LaTeX{} source files, we need to be able to
+% identify multibyte characters during the lyric scanning process.
+% Alas, the |utf8.def| file provides no clean way of identifying the
+% macros it defines for this purpose.
+% The best solution seems to be to look for any token named
+% |\UTFviii@|$\ldots$|@octets| in the top-level expansion of the macro.
+% \begin{macrocode}
+\newcommand\SB@UTFtest{}
+\edef\SB@UTFtest#1{%
+ \noexpand\expandafter%
+ \noexpand\SB@@UTFtest%
+ \noexpand\meaning#1%
+ \string\UTFviii@zero@octets%
+ \noexpand\SB@@UTFtest%
+}
+\newcommand\SB@U@two{\global\SB@cnt\tw@}
+\newcommand\SB@U@three{\global\SB@cnt\thr@@}
+\newcommand\SB@U@four{\global\SB@cnt4\relax}
+\newcommand\SB@@UTFtest{}
+{\escapechar\m@ne
+ \xdef\SB@temp{\string\@octets}}
+\edef\SB@temp{##1\string\UTFviii@##2\SB@temp}
+\expandafter\def\expandafter\SB@@UTFtest\SB@temp#3\SB@@UTFtest{%
+ \SB@cnt\z@%
+ {\csname SB@U@#2\endcsname}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareLyricChar}\MainImpl{DeclareLyricChar}
+% \begin{macro}{\DeclareNonLyric}\MainImpl{DeclareNonLyric}
+% \begin{macro}{\DeclareNoHyphen}\MainImpl{DeclareNoHyphen}
+% \begin{macro}{\SB@declare}
+% \changes{v1.22}{2007/05/15}{Added \cs{DeclareLyricChar}.}
+% \changes{v2.1}{2007/08/02}{Added \cs{DeclareNonLyric} and \cs{DeclareNoHyphen}.}
+% \changes{v2.6}{2008/03/27}{Macro tests made name-based instead of def-based}
+% When scanning the lyric text that follows a chord, it is necessary to
+% distinguish accents and other intra-word macros (which should be included
+% in the under-chord lyric text) from other macros (which should be pushed
+% out away from the text).
+% The following macros allow users to declare a token to be lyric-continuing
+% or lyric-ending.
+% \begin{macrocode}
+\newcommand\SB@declare[3]{%
+ \afterassignment\iffalse\let\SB@next= #3\relax\fi%
+ \SB@UTFtest\SB@next%
+ \ifcase\SB@cnt%
+ \ifcat\noexpand#3\relax%
+ \SB@addNtest\SB@macrotests#1#2#3%
+ \else\ifcat\noexpand#3.%
+ \SB@addDtest\SB@othertests#1#2%
+ \else\ifcat\noexpand#3A%
+ \SB@addDtest\SB@lettertests#1#2%
+ \else%
+ \SB@addDtest\relax0#2%
+ \fi\fi\fi%
+ \or%
+ \SB@addNtest\SB@macrotests#1#2#3%
+ \else%
+ \SB@addMtest\SB@multitests#1#2#3\relax\relax\relax%
+ \fi%
+}
+\newcommand\DeclareLyricChar{\SB@declare\SB@testtrue0}
+\newcommand\DeclareNonLyric{\SB@declare\SB@testfalse\SB@testfalse}
+\newcommand\DeclareNoHyphen{\SB@declare\SB@testfalse\SB@testtrue}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@lettertests}
+% \begin{macro}{\SB@macrotests}
+% \begin{macro}{\SB@multitests}
+% \begin{macro}{\SB@othertests}
+% For speed, token tests introduced by |\DeclareLyricChar| and friends
+% are broken out into separate macros based on category codes.
+% \begin{macrocode}
+\newcommand\SB@lettertests{}
+\newcommand\SB@macrotests{}
+\newcommand\SB@multitests{}
+\newcommand\SB@othertests{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% The following macros add tests to the test macros defined above.
+% In each, \argp{1} is the test macro to which the test should be added,
+% \argp{2} and \argp{3} is the code to be executed at scanning-time and
+% at hyphenation-time if the test succeeds (or ``0'' if no action is to
+% be performed), and \argp{4} is the token to which the currently scanned
+% token should be compared to determine whether it matches.
+%
+% \begin{macro}{\SB@addDtest}
+% A definition-test: The test succeeds if the next lyric token has the same
+% meaning (at test-time) of the non-macro, non-active character token that
+% was given to the |\Declare| macro.
+% \begin{macrocode}
+\newcommand\SB@addDtest[3]{%
+ \ifx0#2\else%
+ \def#1{{\csname SB@!\meaning\SB@next\endcsname}}%
+ \expandafter\def\csname SB@!\meaning\SB@next\endcsname{\global#2}%
+ \fi%
+ \ifx0#3\else%
+ \expandafter\def\csname SB@HT@\meaning\SB@next\endcsname{\global#3}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@addNtest}
+% A name-test: The test succeeds if the next token is a non-|\outer|
+% macro or active character and its |\string|ified name matches the
+% |\string|ified name of the control sequence that was given to the
+% |\Declare| macro.
+% \begin{macrocode}
+\newcommand\SB@addNtest[4]{%
+ \ifx0#2\else%
+ \def#1{{\csname SB@!\SB@nextname\endcsname}}%
+ \expandafter\def\csname SB@!\string#4\endcsname{\global#2}%
+ \fi%
+ \ifx0#3\else%
+ \expandafter\def\csname SB@HT@\string#4\endcsname{\global#3}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@addMtest}
+% A multibyte-test: The test succeeds if the next lyric token is the
+% beginning of a UTF-8 encoded multibyte character sequence that matches
+% the multibyte sequence given to the |\Declare| macro.
+% \begin{macrocode}
+\newcommand\SB@addMtest[7]{%
+ \edef\SB@temp{%
+ \string#4%
+ \ifx\relax#5\else\string#5\fi%
+ \ifx\relax#6\else\string#6\fi%
+ \ifx\relax#7\else\string#7\fi%
+ }%
+ \ifx0#2\else%
+ \def#1{{\csname SB@!\SB@nextname\endcsname}}%
+ \expandafter\def\csname SB@!\SB@temp\endcsname{\global#2}%
+ \fi%
+ \ifx0#3\else%
+ \expandafter\def\csname SB@HT@\SB@temp\endcsname{\global#3}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% The following code declares the common intra-word macros provided by
+% \TeX{} (as listed on p.~52 of The \TeX book) to be lyric-continuing.
+% \begin{macrocode}
+\DeclareLyricChar\`
+\DeclareLyricChar\'
+\DeclareLyricChar\^
+\DeclareLyricChar\"
+\DeclareLyricChar\~
+\DeclareLyricChar\=
+\DeclareLyricChar\.
+\DeclareLyricChar\u
+\DeclareLyricChar\v
+\DeclareLyricChar\H
+\DeclareLyricChar\t
+\DeclareLyricChar\c
+\DeclareLyricChar\d
+\DeclareLyricChar\b
+\DeclareLyricChar\oe
+\DeclareLyricChar\OE
+\DeclareLyricChar\ae
+\DeclareLyricChar\AE
+\DeclareLyricChar\aa
+\DeclareLyricChar\AA
+\DeclareLyricChar\o
+\DeclareLyricChar\O
+\DeclareLyricChar\l
+\DeclareLyricChar\L
+\DeclareLyricChar\ss
+\DeclareLyricChar\i
+\DeclareLyricChar\j
+\DeclareLyricChar\/
+\DeclareLyricChar\-
+\DeclareLyricChar\discretionary
+% \end{macrocode}
+%
+% We declare |\par| to be lyric-ending without introducing hyphenation.
+% The |\par| macro doesn't actually appear in most verses because we use
+% |\obeylines|, but we include a check for it in case the user says |\par|
+% explicitly somewhere.
+% \begin{macrocode}
+\DeclareNoHyphen\par
+% \end{macrocode}
+%
+% \begin{macro}{\SB@bracket}
+% This macro gets invoked by the |\[|\eat\] macro whenever a chord begins.
+% It gets redefined by code that turns chords on and off, so its initial
+% definition doesn't matter.
+% \begin{macrocode}
+\newcommand\SB@bracket{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chord}
+% Begin parsing a chord macro.
+% While parsing the chord name argument, we set some special catcodes so
+% that chord names can use |#| and |&| for sharps and flats.
+% \begin{macrocode}
+\newcommand\SB@chord{\SB@begincname\SB@@chord}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@begincname}
+% \begin{macro}{\SB@endcname}
+% While parsing a chord name, certain characters such as |#| and |&| are
+% temporarily set active so that they can be used as abbreviations for
+% sharps and flats.
+% To accomplish this, |\SB@begincname| must always be invoked before any
+% macro whose argument is a chord name, and |\SB@endcname| must be invoked
+% at the start of the body of any macro whose argument is a chord name.
+% To aid in debugging, we also temporarily set \Meta{return} characters and
+% chord macros |\outer|.
+% This will cause \TeX{} to halt with a runaway argument error on the correct
+% source line if the user forgets to type a closing end-brace (a common typo).
+% Colon characters are also set non-active to avoid a conflict between the
+% \textsf{Babel} French package and the |\gtab| macro.
+% \begin{macrocode}
+\newcommand\SB@begincname{}
+{\catcode`\^^M\active
+ \gdef\SB@begincname{%
+ \begingroup%
+ \catcode`##\active\catcode`&\active%
+ \catcode`:12\relax%
+ \catcode`\^^M\active\SB@outer\def^^M{}%
+ \SB@outer\def\[{}%
+ \chordlocals\relax%
+ }
+}
+\newcommand\SB@endcname{}
+\let\SB@endcname\endgroup
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@nbsp}
+% Non-breaking spaces (|~|) should be treated as spaces by the lyric-scanner
+% code that follows.
+% Although |~| is usually an active character that creates a non-breaking
+% space, some packages (e.g., the \textsf{Babel} package) redefine it to
+% produce accents, which are typically not lyric-ending.
+% To distinguish the real |~| from redefined |~|, we need to create a macro
+% whose definition is the non-breaking space definition normally assigned to
+% |~|.
+% \begin{macrocode}
+\newcommand*\SB@nbsp{\nobreakspace{}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@firstchord}
+% The following conditional is true when the current chord is the first
+% chord in a sequence of one or more chord macros.
+% \begin{macrocode}
+\newif\ifSB@firstchord\SB@firstchordtrue
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@@chord}
+% Finish processing the chord name and then begin scanning the implicit
+% lyric argument that follows it.
+% This is the main entrypoint to the lyric-scanner code.
+% \begin{macrocode}
+\newcommand*\SB@@chord{}
+\def\SB@@chord#1]{%
+ \SB@endcname%
+ \ifSB@firstchord%
+ \setbox\SB@lyricbox\hbox{\kern\SB@tabindent}%
+ \global\SB@tabindent\z@%
+ \SB@lyric{}%
+ \SB@numhyps\z@%
+ \SB@spcinit%
+ \setbox\SB@chordbox\box\voidb@x%
+ \fi%
+ \SB@setchord{#1}%
+ \SB@firstchordfalse%
+ \let\SB@dothis\SB@chstart%
+ \SB@chscan%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\MultiwordChords}\MainImpl{MultiwordChords}
+% \begin{macro}{\SB@spcinit}
+% \changes{v1.22}{2007/05/15}{Added.}
+% The |\SB@spcinit| macro is invoked at the beginning of the lyric
+% scanning process.
+% By default it does nothing, but if |\MultiwordChords| is invoked,
+% it initializes the lyric-scanner state to process spaces as part of
+% lyrics.
+% \begin{macrocode}
+\newcommand\SB@spcinit{}
+\newcommand\MultiwordChords{%
+ \def\SB@spcinit{%
+ \let\SB@chdone\SB@chlyrdone%
+ \let\SB@chimpspace\SB@chnxtdone%
+ \let\SB@chexpspace\SB@chnxtdone%
+ \let\SB@chespace\SB@chendspace%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chscan}
+% \begin{macro}{\SB@chmain}
+% This is the main loop of the lyric-scanner.
+% Peek ahead at the next token without consuming it, then execute
+% a loop body based on the current state (|\SB@dothis|), and finally
+% go to the next iteration (|\SB@donext|).
+% \begin{macrocode}
+\newcommand\SB@chscan{%
+ \let\SB@nextname\relax%
+ \futurelet\SB@next\SB@chmain%
+}
+\newcommand\SB@chmain{\SB@dothis\SB@donext}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chnxtrelax}
+% \begin{macro}{\SB@chnxtstep}
+% \begin{macro}{\SB@chnxtdone}
+% To shorten the lyric parser macros that follow and thereby improve their
+% speed, we here define some abbreviations for common logic in untaken
+% branches.
+% \begin{macrocode}
+\newcommand\SB@chnxtrelax{\let\SB@donext\relax}
+\newcommand\SB@chnxtstep{\let\SB@donext\SB@chstep}
+\newcommand\SB@chnxtdone{\let\SB@donext\SB@chdone}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Warning: In the lyric-scanner macros that follow, |\SB@next|
+% might be a macro declared |\outer|.
+% This means that it must \emph{never} be passed as an argument to
+% a macro and it must never explicitly appear in any untaken branch
+% of a conditional.
+% If it does, the \TeX{} parser will complain of a runaway argument
+% when it tries to skip over an |\outer| macro while consuming tokens
+% at high speed.
+%
+% \begin{macro}{\SB@chstart}
+% We begin lyric-scanning with two special cases:
+% (1) If the chord macro is immediately followed by another chord macro with
+% no intervening whitespace, drop out of the lyric scanner and reenter it when
+% the second macro is parsed.
+% The chord texts will get concatenated together above the lyric that follows.
+% (2) If the chord macro is immediately followed by one or more quote
+% tokens, then consume them all and output them \emph{before} the chord.
+% This causes the chord to sit above the actual word instead of the
+% left-quote or left-double-quote symbol, which looks better.
+% \begin{macrocode}
+\newcommand\SB@chstart{%
+ \ifx\SB@next\[\SB@chnxtrelax%
+ \else\ifx\SB@next\SB@activehat\SB@chnxtrelax%
+ \else\ifx\SB@next\ch\SB@chnxtrelax%
+ \else\ifx\SB@next\mch\SB@chnxtrelax%
+ \else\ifx\SB@next`\SB@chnxtstep%
+ \else\ifx\SB@next'\SB@chnxtstep%
+ \else\ifx\SB@next"\SB@chnxtstep%
+ \else%
+ \the\SB@lyric%
+ \SB@lyric{}%
+ \SB@firstchordtrue%
+ \let\SB@dothis\SB@chnorm%
+ \SB@chnorm%
+ \fi\fi\fi\fi\fi\fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \eat\]
+%
+% \begin{macro}{\SB@chnorm}
+% \changes{v2.0}{2007/06/18}{Rewritten for speed}
+% First, check to see whether the lyric token is a letter.
+% Since that's the most common case, we do this check first for speed.
+% \begin{macrocode}
+\newcommand\SB@chnorm{%
+ \ifcat\noexpand\SB@next A%
+ \SB@testtrue\SB@lettertests%
+ \ifSB@test%
+ \SB@chespace\SB@chnxtstep%
+ \else%
+ \SB@chnxtdone%
+ \fi%
+ \else%
+ \SB@chtrymacro%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chtrymacro}
+% Next, check to see whether it's a macro or active character.
+% We do these checks next because these are the only cases when the
+% token might be |\outer|.
+% Once we eliminate that ugly possibility, we can write the rest of
+% the code without having to worry about putting |\SB@next| in
+% places where |\outer| tokens are illegal.
+% \begin{macrocode}
+\newcommand\SB@chtrymacro{%
+ \ifcat\noexpand\SB@next\relax%
+ \SB@chmacro%
+ \else%
+ \SB@chother%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chother}
+% The token is not a letter, macro, or active character.
+% The only other cases of interest are spaces, braces, and hyphens.
+% If it's one of those, take the appropriate action; otherwise end the
+% lyric here.
+% Since we've eliminated the possibility of macros and active characters,
+% we can be sure that the token isn't |\outer| at this point.
+% \begin{macrocode}
+\newcommand\SB@chother{%
+ \ifcat\noexpand\SB@next\@sptoken%
+ \SB@chexpspace%
+ \else\ifcat\noexpand\SB@next\bgroup%
+ \SB@chespace\let\SB@donext\SB@chbgroup%
+ \else\ifcat\noexpand\SB@next\egroup%
+ \SB@chespace\let\SB@donext\SB@chegroup%
+ \else\ifx\SB@next-%
+ \SB@numhyps\@ne\relax%
+ \SB@lyricnohyp\expandafter{\the\SB@lyric}%
+ \let\SB@dothis\SB@chhyph%
+ \SB@chespace\SB@chnxtstep%
+ \else\ifcat\noexpand\SB@next.%
+ \SB@testtrue\SB@othertests%
+ \ifSB@test%
+ \SB@chespace\SB@chnxtstep%
+ \else%
+ \SB@chnxtdone%
+ \fi%
+ \else%
+ \SB@chespace\SB@chnxtstep%
+ \fi\fi\fi\fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chmacro}
+% \changes{v1.22}{2007/05/15}{Added support for UTF-8.}
+% The lyric-scanner has encountered a macro or active character.
+% If it's |\outer|, it should never be used in an argument, so stop here.
+% \begin{macrocode}
+\newcommand\SB@chmacro{%
+ \SB@outertest%
+ \ifSB@test%
+ \SB@chnxtdone%
+ \else%
+ \let\SB@donext\SB@chgetname%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chgetname}
+% We've encountered a non-|\outer| macro or active character.
+% Use |\string| to get its name, but insert the token back into the
+% input stream since we haven't decided whether to consume it yet.
+% \begin{macrocode}
+\newcommand\SB@chgetname[1]{%
+ \edef\SB@nextname{\string#1}%
+ \SB@@chmacro\SB@donext#1%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@@chmacro}
+% The lyric-scanner has encountered a non-|\outer| macro or active character.
+% Its |\string|ified name has been stored in |\SB@nextname|.
+% Test to see whether it's a known macro or the beginning of a
+% multibyte-encoded international character.
+% If the former, dispatch some macro-specific code to handle it.
+% If the latter, grab the full multibyte sequence and include it in the lyric.
+% \begin{macrocode}
+\newcommand\SB@@chmacro{%
+ \ifx\SB@next\SB@activehat%
+ \SB@chnxtdone%
+ \else\ifx\SB@next\SB@par%
+ \SB@chnxtdone%
+ \else\ifx\SB@next\measurebar%
+ \SB@chmbar%
+ \else\ifx\SB@next\mbar%
+ \SB@chmbar%
+ \else\ifx\SB@next\ch%
+ \SB@chespace\let\SB@donext\SB@chlig%
+ \else\ifx\SB@next\mch%
+ \SB@chespace\let\SB@donext\SB@mchlig%
+ \else\ifx\SB@next\ %
+ \SB@chimpspace%
+ \else\ifx\SB@next\SB@nbsp%
+ \SB@chimpspace%
+ \else%
+ \SB@UTFtest\SB@next%
+ \ifcase\SB@cnt\SB@chothermac%
+ \or\or\SB@chespace\let\SB@donext\SB@chsteptwo%
+ \or\SB@chespace\let\SB@donext\SB@chstepthree%
+ \or\SB@chespace\let\SB@donext\SB@chstepfour\fi%
+ \fi\fi\fi\fi\fi\fi\fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chothermac}
+% \changes{v2.6}{2008/03/26}{All active chars now included in lyrics by default.}
+% The lyric-scanner has encountered a macro or active character that is
+% not |\outer|, not a known macro that requires special treatment,
+% and not a multibyte international character.
+% First, check the macro's name (stored in |\SB@nextname|) to see whether it
+% begins with a non-escape character.
+% If so, it's probably an accenting or punctuation character made active
+% by the |inputenc| or |babel| packages.
+% Most such characters should be included in the lyric, so include it by
+% default; otherwise exclude it by default.
+% The user can override the defaults using |\DeclareLyricChar| and friends.
+% \begin{macrocode}
+\newcommand\SB@chothermac{%
+ \SB@testfalse%
+ \afterassignment\iffalse%
+ \SB@cnt\expandafter`\SB@nextname x\fi%
+ \ifnum\the\catcode\SB@cnt=\z@\else\SB@testtrue\fi%
+ \SB@macrotests%
+ \ifSB@test%
+ \SB@chespace\SB@chnxtstep%
+ \else%
+ \SB@chnxtdone%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chstep}
+% \begin{macro}{\SB@chsteptwo}
+% \begin{macro}{\SB@chstepthree}
+% \begin{macro}{\SB@chstepfour}
+% \begin{macro}{\SB@chmulti}
+% \begin{macro}{\SB@chmstop}
+% We've encountered one or more tokens that should be included in the
+% lyric text.
+% (More than one means we've encountered a multibyte encoding of an
+% international character.)
+% Consume them (as arguments to this macro) and add them to the list
+% of tokens we've already consumed.
+% \begin{macrocode}
+\newcommand\SB@chstep[1]{%
+ \SB@lyric\expandafter{\the\SB@lyric#1}%
+ \SB@chscan%
+}
+\newcommand\SB@chsteptwo[2]{\SB@chmulti{#1#2}{\string#1\string#2}}
+\newcommand\SB@chstepthree[3]{%
+ \SB@chmulti{#1#2#3}{\string#1\string#2\string#3}%
+}
+\newcommand\SB@chstepfour[4]{%
+ \SB@chmulti{#1#2#3#4}{\string#1\string#2\string#3\string#4}%
+}
+\newcommand\SB@chmulti[2]{%
+ \def\SB@next{#1}%
+ \edef\SB@nextname{#2}%
+ \SB@testtrue\SB@multitests%
+ \ifSB@test%
+ \SB@lyric\expandafter{\the\SB@lyric#1}%
+ \expandafter\SB@chscan%
+ \else%
+ \expandafter\SB@chmstop%
+ \fi%
+}
+\newcommand\SB@chmstop{\expandafter\SB@chdone\SB@next}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chhyph}
+% We've encountered a hyphen.
+% Continue to digest hyphens, but terminate as soon as we see anything
+% else.
+% \begin{macrocode}
+\newcommand\SB@chhyph{%
+ \ifx\SB@next-%
+ \advance\SB@numhyps\@ne\relax%
+ \SB@chnxtstep%
+ \else%
+ \SB@chnxtdone%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chimpspace}
+% \begin{macro}{\SB@chexpspace}
+% We've encountered an implicit or explicit space.
+% Normally this just ends the lyric, but if |\MultiwordChords| is
+% active, these macros both get redefined to process the space.
+% \begin{macrocode}
+\newcommand\SB@chimpspace{}
+\let\SB@chimpspace\SB@chnxtdone
+\newcommand\SB@chexpspace{}
+\let\SB@chexpspace\SB@chnxtdone
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chespace}
+% \begin{macro}{\SB@chendspace}
+% \changes{v1.22}{2007/05/15}{Added.}
+% The |\SB@chespace| macro gets invoked by the lyric-scanner just before a
+% non-space token is about to be accepted as part of an under-chord lyric.
+% Normally it does nothing; however, if |\MultiwordChords| is active, it
+% gets redefined to do one of three things:
+% (1) Initially it is set equal to |\SB@chendspace| so that if the very
+% first token following the chord macro is not a space, the lyric-scanner
+% macros are redefined to process any future spaces encountered.
+% Otherwise the very first token is a space, and the lyric ends immediately.
+% (2) While scanning non-space lyric tokens, it is set to nothing, since no
+% special action needs to be taken until we encounter a sequence of one or
+% more spaces.
+% (3) When a space token is encountered (but not the very first token after
+% the chord macro), it is set equal to |\SB@chendspace| again so that
+% |\SB@chendspace| is invoked once the sequence of one or more space tokens
+% is finished.
+% \begin{macrocode}
+\newcommand\SB@chespace{}
+\newcommand\SB@chendspace{%
+ \let\SB@chdone\SB@chlyrdone%
+ \def\SB@chexpspace{\SB@chbspace\SB@chexpspace}%
+ \def\SB@chimpspace{\SB@chbspace\SB@chimpspace}%
+ \def\SB@chespace{}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chbspace}
+% \begin{macro}{\SB@chgetspace}
+% \changes{v1.22}{2007/05/15}{Added.}
+% The |\SB@chbspace| macro gets invoked when |\MultiwordChords| is active
+% and the lyric-scanner has encountered a space token that was immediately
+% preceded by a non-space token.
+% Before processing the space, we add all lyrics seen so far to the
+% |\SB@lyricbox| and check its width.
+% If we've seen enough lyrics to match or exceed the width of the chord,
+% a space stops the lyric-scanning process.
+% (This is important because it minimizes the size of the chord box,
+% providing as many line breakpoints as possible to the paragraph-formatter.)
+%
+% Otherwise we begin scanning space tokens without adding them to the
+% lyric until we see what the next non-space token is.
+% If the next non-space token would have ended the lyric anyway, roll back
+% and end the lyric here, reinserting the space tokens back into the token
+% stream.
+% If the next non-space token would have been included in the lyric,
+% the lyric-scanner proceeds as normal.
+% \begin{macrocode}
+\newcommand\SB@chbspace{%
+ \setbox\SB@lyricbox\hbox{%
+ \unhbox\SB@lyricbox%
+ \the\SB@lyric%
+ }%
+ \SB@lyric{}%
+ \ifdim\wd\SB@lyricbox<\wd\SB@chordbox%
+ \let\SB@chbstok= \SB@next%
+ \def\SB@chexpspace{\let\SB@donext\SB@chgetspace}%
+ \let\SB@chimpspace\SB@chnxtstep%
+ \let\SB@chespace\SB@chendspace%
+ \let\SB@chdone\SB@chspcdone%
+ \else%
+ \let\SB@chimpspace\SB@chnxtdone%
+ \let\SB@chexpspace\SB@chnxtdone%
+ \fi%
+}
+\newcommand\SB@chgetspace{%
+ \SB@appendsp\SB@lyric%
+ \let\SB@nextname\relax%
+ \afterassignment\SB@chscan%
+ \let\SB@next= }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chmbar}
+% We've encountered a measure bar.
+% Either ignore it or end the lyric text, depending on whether
+% measure bars are being displayed.
+% \begin{macrocode}
+\newcommand\SB@chmbar{%
+ \ifmeasures%
+ \SB@chnxtdone%
+ \else%
+ \SB@chespace\SB@chnxtstep%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chbgroup}
+% We've encountered a begin-group brace.
+% Consume the entire group that it begins, and add it to the list
+% of tokens including the begin and end group tokens.
+% \begin{macrocode}
+\newcommand\SB@chbgroup[1]{%
+ \SB@lyric\expandafter{\the\SB@lyric{#1}}%
+ \SB@chscan%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chegroup}
+% \begin{macro}{\SB@chegrpscan}
+% \begin{macro}{\SB@chegrpmacro}
+% \begin{macro}{\SB@chegrpouter}
+% \begin{macro}{\SB@chegrpname}
+% \begin{macro}{\SB@chegrpdone}
+% We've encountered an end-group brace whose matching begin-group brace
+% must have come before the chord macro itself.
+% This forcibly ends the lyric text.
+% Before stopping, we must set |\SB@next| to the token following the brace
+% and |\SB@nextname| to its |\string|ified name so that |\SB@emitchord| will
+% know whether to add hyphenation.
+% Therefore, we temporarily consume the end-group brace, then scan the
+% next token without consuming it, and finally reinsert the end-group brace
+% and stop.
+% \begin{macrocode}
+\newcommand\SB@chegroup{%
+ \let\SB@nextname\relax%
+ \afterassignment\SB@chegrpscan%
+ \let\SB@next= }
+\newcommand\SB@chegrpscan{%
+ \futurelet\SB@next\SB@chegrpmacro%
+}
+\newcommand\SB@chegrpmacro{%
+ \ifcat\noexpand\SB@next\relax%
+ \expandafter\SB@chegrpouter%
+ \else%
+ \expandafter\SB@chegrpdone%
+ \fi%
+}
+\newcommand\SB@chegrpouter{%
+ \SB@outertest%
+ \ifSB@test%
+ \expandafter\SB@chegrpdone%
+ \else%
+ \expandafter\SB@chegrpname%
+ \fi%
+}
+\newcommand\SB@chegrpname[1]{%
+ \edef\SB@nextname{\string#1}%
+ \SB@chegrpdone#1%
+}
+\newcommand\SB@chegrpdone{\SB@chdone\egroup}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chlig}
+% \begin{macro}{\SB@mchlig}
+% We've encountered a |\ch| chord-over-ligature macro, or an
+% |\mch| measurebar-and-chord-over-ligature macro.
+% Consume it and all of its arguments, and load them into some
+% registers for future processing.
+% (Part of the ligature might fall into this lyric text or might
+% not, depending on whether we decide to add hyphenation.)
+% Then end the lyric text here.
+% \begin{macrocode}
+\newcommand\SB@chlig[5]{%
+ \gdef\SB@ligpre{{#3}}%
+ \gdef\SB@ligpost{\[#2]{#4}}%
+ \gdef\SB@ligfull{%
+ \[\SB@noreplay{\hphantom{{\lyricfont\relax#3}}}#2]{#5}%
+ }%
+ \SB@chdone%
+}
+\newcommand\SB@mchlig[5]{%
+ \SB@lyric\expandafter{\the\SB@lyric#3}%
+ \let\SB@next\measurebar%
+ \edef\SB@nextname{\string\measurebar}%
+ \gdef\SB@ligpost{\measurebar\[#2]{#4}}%
+ \gdef\SB@ligfull{\measurebar\[#2]{#4}}%
+ \SB@chdone%
+}
+% \end{macrocode}
+% \eat\]
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@chdone}
+% \begin{macro}{\SB@chlyrdone}
+% \begin{macro}{\SB@chspcdone}
+% The |\SB@chdone| macro is invoked when we've decided to end the lyric
+% text (usually because we've encountered a non-lyric token).
+% Normally this expands to |\SB@chlyrdone|, which adds any uncontributed
+% lyric material to the |\SB@lyricbox| and jumps to the main chord
+% formatting macro.
+% However, if |\MultiwordChords| is active and if the lyric ended with
+% a sequence of one or more space tokens, then we instead reinsert the
+% space tokens into the token stream without contributing them to the
+% |\SB@lyricbox|.
+% \begin{macrocode}
+\newcommand\SB@chlyrdone{%
+ \setbox\SB@lyricbox\hbox{%
+ \unhbox\SB@lyricbox%
+ \ifnum\SB@numhyps=\@ne%
+ \the\SB@lyricnohyp%
+ \else%
+ \the\SB@lyric%
+ \fi%
+ }%
+ \SB@emitchord%
+}
+\newcommand\SB@chspcdone{%
+ \let\SB@nextname\relax%
+ \let\SB@next= \SB@chbstok%
+ \expandafter\SB@emitchord\the\SB@lyric%
+}
+\newcommand\SB@chdone{}
+\let\SB@chdone\SB@chlyrdone
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@ligpre}
+% \begin{macro}{\SB@ligpost}
+% \begin{macro}{\SB@ligfull}
+% The following three macros record arguments passed to a |\ch| macro that
+% concludes the lyric text of the |\[]|\eat\] macro currently being processed.
+% \begin{macrocode}
+\newcommand\SB@ligpre{}
+\newcommand\SB@ligpost{}
+\newcommand\SB@ligfull{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@clearlig}
+% Clear all ligature-chord registers.
+% \begin{macrocode}
+\newcommand\SB@clearlig{%
+ \gdef\SB@ligpre{}%
+ \gdef\SB@ligpost{}%
+ \gdef\SB@ligfull{}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Chords}
+%
+% \begin{macro}{\SB@emitchord}\MainImpl{[}
+% \changes{v1.12}{2005/05/10}{Inhibited hyphenation of trailing punctuation}
+% \changes{v1.13}{2005/05/12}{Added code to preserve the spacefactor}
+% \changes{v1.16}{2005/07/23}{Chord macros massively reorganized to take lyrics as implicit rather than explicit arguments}
+% The |\SB@emitchord| macro does the actual work of typesetting chord text
+% over lyric text, introducing appropriate hyphenation when necessary.
+% We begin by consulting |\SB@next|, which should have been set by the
+% lyric-scanning code in \S\ref{sec:lyricscan} to the token that immediately
+% follows the lyric under this chord, to determine whether the lyric text
+% ends on a word boundary.
+% \begin{macrocode}
+\newcommand\SB@emitchord{%
+ \ifSB@inverse\else\ifSB@inchorus\else\SB@errchord\fi\fi%
+ \SB@testfalse%
+ \ifcat\noexpand\SB@next\@sptoken\SB@testtrue\fi%
+ \ifcat\noexpand\SB@next.\SB@testtrue\fi%
+ \ifx\SB@next\SB@par\SB@testtrue\fi%
+ \ifx\SB@next\egroup\SB@testtrue\fi%
+ \ifx\SB@next\endgroup\SB@testtrue\fi%
+ {\csname%
+ SB@HT@\ifx\SB@nextname\relax\meaning\SB@next\else\SB@nextname\fi%
+ \endcsname}%
+ \ifSB@test\SB@wordendstrue\else\SB@wordendsfalse\fi%
+% \end{macrocode}
+% Next, compare the width of the lyric to the width of the chord to
+% determine whether hyphenation might be necessary.
+% The original lyric text might have ended in a string of one or more
+% explicit hyphens, enumerated by |\SB@numhyps|.
+% If it ended in exactly one, the lyric-scanning code suppresses that hyphen
+% so that we can here add a new hyphen that floats out away from the word
+% when the chord above it is long.
+% If it ended in more than one (e.g., the encoding of an en- or em-dash) then
+% the lyric-scanner leaves it alone; we must not add any hyphenation or float
+% the dash away from the word.
+%
+% There is also code here to insert a penalty that discourages linebreaking
+% immediately before lyricless chords.
+% Beginning a wrapped line with a lyricless chord is undesirable because it
+% makes it look as though the wrapped line is extra-indented (due to the
+% empty lyric space below the chord).
+% It should therefore happen only as a last resort.
+% \begin{macrocode}
+ \SB@dimen\wd\SB@chordbox%
+ \ifvmode\leavevmode\fi%
+ \SB@brokenwordfalse%
+ \ifdim\wd\SB@lyricbox>\z@%
+ \ifdim\SB@dimen>\wd\SB@lyricbox%
+ \ifSB@wordends\else\SB@brokenwordtrue\fi%
+ \fi%
+ \else%
+ \SB@skip\lastskip%
+ \unskip\penalty200\hskip\SB@skip%
+ \fi%
+ \ifnum\SB@numhyps>\z@%
+ \ifnum\SB@numhyps>\@ne%
+ \SB@brokenwordfalse%
+ \else%
+ \SB@brokenwordtrue%
+ \fi%
+ \fi%
+% \end{macrocode}
+% If lyrics are suppressed on this line (e.g., by using |\nolyrics|), then just
+% typeset the chord text on the natural baseline.
+% \begin{macrocode}
+ \SB@testfalse%
+ \ifnolyrics\ifdim\wd\SB@lyricbox=\z@\SB@testtrue\fi\fi%
+ \ifSB@test%
+ \unhbox\SB@chordbox%
+ \gdef\SB@temp{\expandafter\SB@clearlig\SB@ligfull}%
+ \else%
+% \end{macrocode}
+% Otherwise, typeset the chord above the lyric on a double-height line.
+% \begin{macrocode}
+ \vbox{\clineparams\relax%
+ \ifSB@brokenword%
+ \global\setbox\SB@lyricbox\hbox{%
+ \unhbox\SB@lyricbox%
+ \SB@ligpre%
+ }%
+ \SB@maxmin\SB@dimen<{\wd\SB@lyricbox}%
+ \advance\SB@dimen.5em%
+ \hbox to\SB@dimen{\unhbox\SB@chordbox\hfil}%
+ \hbox to\SB@dimen{%
+ \unhcopy\SB@lyricbox\hfil
+ \ifnum\hyphenchar\font>\m@ne\char\hyphenchar\font\hfil\fi%
+ }%
+ \global\SB@cnt\@m%
+ \gdef\SB@temp{\expandafter\SB@clearlig\SB@ligpost}%
+ \else%
+ \box\SB@chordbox%
+ \hbox{%
+ \unhcopy\SB@lyricbox%
+ \global\SB@cnt\spacefactor%
+ \hfil%
+ }%
+ \gdef\SB@temp{\expandafter\SB@clearlig\SB@ligfull}%
+ \fi%
+ }%
+% \end{macrocode}
+% If the chord is lyricless, inhibit a linebreak immediately following it.
+% This prevents sequences of lyricless chords (which often end lines) from
+% being wrapped in the middle, which looks very unsightly and makes them
+% difficult to read.
+% If the chord has a lyric but it doesn't end on a word boundary, insert
+% an appropriate penalty to prevent linebreaking without hyphenation.
+% Also preserve the spacefactor in this case, which allows \LaTeX{} to
+% fine-tune the spacing between consecutive characters in the word that
+% contains the chord.
+% \begin{macrocode}
+ \ifSB@wordends%
+ \ifdim\wd\SB@lyricbox>\z@\else\nobreak\fi%
+ \else%
+ \penalty%
+ \ifnum\SB@numhyps>\z@\exhyphenpenalty%
+ \else\ifSB@brokenword\hyphenpenalty%
+ \else\@M\fi\fi%
+ \spacefactor\SB@cnt%
+ \fi%
+ \fi%
+% \end{macrocode}
+% Finally, end the macro with some code that handles the special case that
+% this chord is immediately followed by a chord-over-ligature macro.
+% The code above sets |\SB@temp| to the portion of the ligature that should
+% come after this chord but before the chord that tops the ligature.
+% This text must be inserted here.
+% \begin{macrocode}
+ \SB@temp%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@accidental}
+% Typeset an accidental symbol as a superscript within a chord.
+% Since chord names are often in italics but math symbols like sharp and
+% flat are not, we need to do some kerning adjustments before and after the
+% accidental to position it as if it were italicized.
+% The pre-adjustment is just a simple italic correction using |\/|.
+% The post-adjustment is based on the current font's slant-per-point metric.
+% \begin{macrocode}
+\newcommand\SB@accidental[1]{{%
+ \/%
+ \m@th#1%
+ \SB@dimen-\fontdimen\@ne\font%
+ \advance\SB@dimen.088142\p@%
+ \ifdim\SB@dimen<\z@%
+ \kern\f@size\SB@dimen%
+ \fi%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sharpsymbol}\MainImpl{sharpsymbol}
+% \begin{macro}{\flatsymbol}\MainImpl{flatsymbol}
+% When changing the sharp or flat symbol, change these macros rather than
+% changing |\shrp| or |\flt|.
+% This will ensure that other shortcuts like |#| and |&| will reflect your
+% change.
+% \begin{macrocode}
+\newcommand\sharpsymbol{\ensuremath{^\#}}
+\newcommand\flatsymbol{\raise.5ex\hbox{{\SB@flatsize$\flat$}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\shrp}\MainImpl{shrp}
+% \begin{macro}{\flt}\MainImpl{flt}
+% \changes{v2.10}{2009/08/18}{Font size made relative}
+% These macros typeset sharp and flat symbols.
+% \begin{macrocode}
+\newcommand\shrp{\SB@accidental\sharpsymbol}
+\newcommand\flt{\SB@accidental\flatsymbol}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareFlatSize}
+% The |\flat| math symbol is too small for properly typesetting
+% chord names.
+% (Its size was designed for staff notation not textual chord names.)
+% The correct size for the symbol should be approximately 30\% larger
+% than the current superscript size, or 90\% of the base font size $b$.
+% However, simply computing $0.9b$ does not work well because most fonts
+% do not render well in arbitrary sizes.
+% To solve the problem, we must therefore choose an appropriate size
+% individually for each possible base font size $b$.
+% This is the solution adopted by the rest of \LaTeX{} for such things.
+% For example, \LaTeX's |\DeclareMathSizes| macro defines an appropriate
+% superscript size for each possible base font size.
+% The macro below creates a similar macro that that defines an appropriate
+% flat-symbol size for each possible base font size.
+% \begin{macrocode}
+\newcommand\DeclareFlatSize[2]{%
+ \expandafter\xdef\csname SB@flatsize@#1\endcsname{#2}%
+}
+\DeclareFlatSize\@vpt\@vpt
+\DeclareFlatSize\@vipt\@vipt
+\DeclareFlatSize\@viipt\@vipt
+\DeclareFlatSize\@viiipt\@viipt
+\DeclareFlatSize\@ixpt\@viiipt
+\DeclareFlatSize\@xpt\@ixpt
+\DeclareFlatSize\@xipt\@xpt
+\DeclareFlatSize\@xiipt\@xipt
+\DeclareFlatSize\@xivpt\@xiipt
+\DeclareFlatSize\@xviipt\@xivpt
+\DeclareFlatSize\@xxpt\@xviipt
+\DeclareFlatSize\@xxvpt\@xxpt
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@flatsize}
+% Select the correct flat symbol size based on the current font size.
+% \begin{macrocode}
+\newcommand\SB@flatsize{%
+ \@ifundefined{SB@flatsize@\f@size}{}{%
+ \expandafter\fontsize%
+ \csname SB@flatsize@\f@size\endcsname\f@baselineskip%
+ \selectfont%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% In the following code, the |\ch|, |\mch|, |\[|\eat\], and |^| macros are
+% each defined to be a single macro that then expands to the real definition.
+% This is necessary because the top-level definitions of each must stay the
+% same in order to allow the lyric-scanning code to uniquely identify them,
+% yet their internal definitions must be redefined by code that turns
+% chords and/or measure bars on and off.
+% Such code redefines |\SB@ch|, |\SB@mch|, |\SB@bracket|, and |\SB@rechord|
+% to effect a change of mode without touching the top-level definitions.
+%
+% \begin{macro}{\ch}\MainImpl{ch}
+% \begin{macro}{\SB@ch}
+% \begin{macro}{\SB@ch@on}
+% \begin{macro}{\SB@@ch}
+% \begin{macro}{\SB@@@ch}
+% \begin{macro}{\SB@ch@off}
+% The |\ch| macro puts a chord atop a ligature without breaking the ligature.
+% Normally this just means placing the chord midway over the unbroken
+% ligature (ignoring the third argument completely).
+% However, when a previous chord macro encounters it while scanning ahead in
+% the input stream to parse its lyric, the |\ch| macro itself is not actually
+% expanded at all.
+% Instead, the chord macro scans ahead, spots the |\ch| macro, gobbles it,
+% and then steals its arguments, breaking the ligature with hyphenation.
+% Thus, the |\ch| macro is only actually expanded when the ligature
+% shouldn't be broken.
+% \begin{macrocode}
+\newcommand\ch{\SB@ch}
+\newcommand\SB@ch{}
+\newcommand\SB@ch@on{\SB@begincname\SB@@ch}
+\newcommand*\SB@@ch[1]{\SB@endcname\SB@@@ch{#1}}
+\newcommand*\SB@@@ch[4]{\[\SB@noreplay{\hphantom{#2}}#1]#4}
+\newcommand*\SB@ch@off[4]{#4}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \eat\]
+%
+% \begin{macro}{\mch}\MainImpl{mch}
+% \begin{macro}{\SB@mch}
+% \begin{macro}{\SB@mch@m}
+% \begin{macro}{\SB@mch@on}
+% \begin{macro}{\SB@@mch}
+% \begin{macro}{\SB@@@mch}
+% The |\mch| macro is like |\ch| except that it also introduces a measure
+% bar.
+% \begin{macrocode}
+\newcommand\mch{\SB@mch}
+\newcommand\SB@mch{}
+\newcommand*\SB@mch@m[4]{#2\measurebar#3}
+\newcommand\SB@mch@on{\SB@begincname\SB@@mch}
+\newcommand*\SB@@mch[1]{\SB@endcname\SB@@@mch{#1}}
+\newcommand*\SB@@@mch[4]{#2\measurebar\[#1]#3}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \eat\]
+%
+% \begin{macro}{\SB@activehat}
+% This macro must always contain the current definition of the |^|
+% chord-replay active character, in order for the lyric scanner to properly
+% identify it and insert proper hyphenation when necessary.
+% \begin{macrocode}
+\newcommand\SB@activehat{%
+ \ifmmode^\else\expandafter\SB@rechord\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@hat@tr}
+% In verses/choruses where chords are being memorized, |\SB@activehat|
+% gets set to this definition, which marks the current chord as immune to
+% memorization.
+% \begin{macrocode}
+\newcommand\SB@hat@tr{%
+ \ifmmode^\else\global\SB@nohatfalse\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@hat@notr}
+% In verses/choruses where chords are being replayed, |\SB@activehat|
+% get set to the following, which replays the next memorized chord and
+% subjects it to any required transposition and/or note conversion.
+% \begin{macrocode}
+\newcommand\SB@hat@notr{%
+ \ifmmode^\else%
+ \SB@lop\SB@ctail\SB@toks%
+ \expandafter\transposehere\expandafter{\the\SB@toks}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@loadactives}
+% It's cumbersome to have to type |\shrp|, |\flt|, and |\mbar| every time you
+% want a sharp, flat, or measure bar, so within verses and choruses we allow
+% the hash, ampersand, and pipe symbols to perform the those functions too.
+% It's also cumbersome to have to type something like |\chord{Am}{lyric}| to
+% produce each chord.
+% As an easier alternative, we here define |\[Am]|\eat\]
+% to typeset chords.
+% \begin{macrocode}
+\newcommand\SB@loadactives{}
+{
+ \catcode`&\active
+ \catcode`#\active
+ \catcode`|\active
+ \catcode`^\active
+ \global\let&\flt
+ \global\let#\shrp
+ \global\let|\measurebar
+ \global\let^\SB@activehat
+ \gdef\SB@loadactives{%
+ \catcode`^\ifchorded\active\else9 \fi%
+ \catcode`|\ifmeasures\active\else9 \fi%
+ \def\[{\SB@bracket}%
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Chord Replaying}
+%
+% \begin{macro}{\SB@trackch}
+% While inside a verse where the chord history is being remembered for future
+% verses, |\SB@trackch| is true.
+% \begin{macrocode}
+\newif\ifSB@trackch
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@cr@}
+% Reserve token registers to record a history of the chords seen in a verse.
+% \begin{macrocode}
+\SB@newtoks\SB@cr@
+\SB@newtoks\SB@ctail
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@creg}
+% The following control sequence equals the token register being memorized
+% into or replayed from.
+% \begin{macrocode}
+\newcommand\SB@creg{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newchords}\MainImpl{newchords}
+% \changes{v2.6}{2008/02/23}{Added}
+% Allocate a new chord-replay register to hold memorized chords.
+% \begin{macrocode}
+\newcommand\newchords[1]{%
+ \@ifundefined{SB@cr@#1}{%
+ \expandafter\SB@newtoks\csname SB@cr@#1\endcsname%
+ \global\csname SB@cr@#1\endcsname{\\}%
+ }{\SB@errdup{#1}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\memorize}\MainImpl{memorize}
+% \begin{macro}{\SB@memorize}
+% \changes{v2.6}{2008/02/23}{Optional argument added}
+% Saying |\memorize| throws out any previously memorized list of chords and
+% starts memorizing chords until the end of the current verse or chorus.
+% \begin{macrocode}
+\newcommand\memorize{%
+ \@ifnextchar[\SB@memorize{\SB@memorize[]}%
+}
+\newcommand\SB@memorize{}
+\def\SB@memorize[#1]{%
+ \@ifundefined{SB@cr@#1}{\SB@errreg{#1}}{%
+ \SB@trackchtrue%
+ \global\expandafter\let\expandafter\SB@creg%
+ \csname SB@cr@#1\endcsname%
+ \global\SB@creg{\\}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\replay}\MainImpl{replay}
+% \begin{macro}{\SB@replay}
+% \begin{macro}{\SB@@replay}
+% \changes{v2.6}{2008/02/23}{Added}
+% Saying |\replay| stops any memorization and begins replaying memorized
+% chords.
+% \begin{macrocode}
+\newcommand\replay{\@ifnextchar[\SB@replay\SB@@replay}
+\newcommand\SB@replay{}
+\def\SB@replay[#1]{%
+ \@ifundefined{SB@cr@#1}{\SB@errreg{#1}}{%
+ \SB@trackchfalse%
+ \global\expandafter\let\expandafter\SB@creg%
+ \csname SB@cr@#1\endcsname%
+ \global\SB@ctail\SB@creg%
+ }%
+}
+\newcommand\SB@@replay{%
+ \SB@trackchfalse%
+ \global\SB@ctail\SB@creg%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@rechord}
+% \begin{macro}{\SB@@rechord}
+% Replay the same chord that was in a previous verse.
+% \begin{macrocode}
+\newcommand\SB@rechord{}
+\newcommand\SB@@rechord{%
+ \SB@ifempty\SB@ctail{%
+ \SB@errreplay%
+ \SB@toks{}%
+ \let\SB@donext\@gobble%
+ }{%
+ \SB@lop\SB@ctail\SB@toks%
+ \let\SB@donext\SB@chord%
+ \let\SB@noreplay\@gobble%
+ }%
+ \expandafter\SB@donext\the\SB@toks]%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@nohat}
+% The |\ifSB@nohat| conditional is set to false when a chord macro contains
+% a |^| in its argument.
+% This suppresses the recording mechanism momentarily so that replays will
+% skip this chord.
+% \begin{macrocode}
+\newif\ifSB@nohat
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@noreplay}
+% Sometimes material must be added to a chord but omitted when the chord is
+% replayed.
+% We accomplish this by enclosing such material in |\SB@noreplay| macros,
+% which are set to |\@gobble| just before a replay and reset to
+% |\@firstofone| at other times.
+% \begin{macrocode}
+\newcommand\SB@noreplay{}
+\let\SB@noreplay\@firstofone
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Guitar Tablatures}
+%
+% The song book software not only supports chord names alone, but can also
+% typeset guitar tablature diagrams. The macros for producing these diagrams
+% are found here.
+%
+% \begin{macro}{\SB@fretwidth}
+% Set the width of each vertical string in the tablature diagram.
+% \begin{macrocode}
+\newlength\SB@fretwidth
+\setlength\SB@fretwidth{6\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@fretnum}
+% Typeset a fret number to appear to the left of the diagram.
+% \begin{macrocode}
+\newcommand\SB@fretnum[1]{{%
+ \sffamily\fontsize\@xpt\@xpt\selectfont#1%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@onfret}
+% Typeset one string of one fret with \argp{1} typeset overtop of it (usually
+% a dot or nothing at all).
+% \begin{macrocode}
+\newcommand\SB@onfret[1]{%
+ \kern.5\SB@fretwidth\kern-.2\p@%
+ \vrule\@height6\p@%
+ \kern-.2\p@\kern-.5\SB@fretwidth%
+ \hbox to\SB@fretwidth{\hfil#1\hfil}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@atopfret}
+% Typeset material (given by \argp{1}) to be placed above a string in the
+% tablature diagram.
+% \begin{macrocode}
+\newcommand\SB@atopfret[1]{%
+ \hbox to\SB@fretwidth{\hfil#1\hfil}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@fretbar}
+% Typeset a horizontal fret bar of width |\SB@dimen|.
+% \begin{macrocode}
+\newcommand\SB@fretbar{%
+ \nointerlineskip%
+ \hbox to\SB@dimen{%
+ \advance\SB@dimen-\SB@fretwidth%
+ \advance\SB@dimen.4\p@%
+ \hfil%
+ \vrule\@width\SB@dimen\@height.4\p@\@depth\z@%
+ \hfil%
+ }%
+ \nointerlineskip%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@topempty}
+% \begin{macro}{\SB@topX}
+% \begin{macro}{\SB@topO}
+% Above a string in a tablature diagram there can be nothing,
+% an $\times$, or an $\circ$.
+% \begin{macrocode}
+\newcommand\SB@topempty{\SB@atopfret\relax}
+\newcommand\SB@topX{\SB@atopfret{%
+ \hbox{%
+ \kern-.2\p@%
+ \fontencoding{OMS}\fontfamily{cmsy}%
+ \fontseries{m}\fontshape{n}%
+ \fontsize\@viipt\@viipt\selectfont\char\tw@%
+ \kern-.2\p@%
+ }%
+}}
+\newcommand\SB@topO{\SB@atopfret{%
+ \vrule\@width\z@\@height4.3333\p@\@depth.8333\p@%
+ \lower.74\p@\hbox{%
+ \fontencoding{OMS}\fontfamily{cmsy}%
+ \fontseries{m}\fontshape{n}%
+ \fontsize\@xpt\@xpt\selectfont\char14%
+ }%
+}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@doify}
+% \begin{macro}{\SB@@doify}
+% \begin{macro}{\SB@do}
+% Define the macro given in the first argument to equal the fully expanded
+% content of the second argument, but with |\SB@do| inserted before each token
+% or group.
+% \begin{macrocode}
+\newcommand\SB@do[1]{}
+\newcommand\SB@doify[2]{%
+ \SB@toks{}%
+ \edef#1{#2}%
+ \expandafter\SB@@doify#1\SB@@doify%
+ \edef#1{\the\SB@toks}%
+}
+\newcommand\SB@@doify[1]{%
+ \ifx#1\SB@@doify\else%
+ \SB@toks\expandafter{\the\SB@toks\SB@do{#1}}%
+ \expandafter\SB@@doify%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@allbarres}
+% \begin{macro}{\SB@dobarre}
+% Reserve a control sequence to remember all the stacks, start control
+% sequences, and end control sequences associated with barre delimiter pairs;
+% and a control sequence to perform an arbitrary action on them.
+% \begin{macrocode}
+\newcommand\SB@allbarres{}
+\newcommand\SB@dobarre{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@barreI}
+% \begin{macro}{\SB@barreN}
+% \begin{macro}{\SB@barreY}
+% As we process strings in order, barres in progress can be in one of three
+% states: initial (|\SB@barreI|), deactivated (|\SB@barreN|), or
+% tentatively activated (|\SB@barreY|).
+% \begin{macrocode}
+\newcommand\SB@barreI{\noexpand\SB@barreI}
+\newcommand\SB@barreN{\noexpand\SB@barreN}
+\newcommand\SB@barreY{\noexpand\SB@barreY}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@lowfret}
+% \begin{macro}{\SB@@lowfret}
+% If we see a lower numbered fret than the current fret within a barre,
+% deactivate the barre.
+% (It has already been shown on an earlier fret.)
+% \begin{macrocode}
+\newcommand\SB@lowfret{%
+ \let\SB@dobarre\SB@@lowfret\SB@allbarres%
+ \SB@fretempty%
+}
+\newcommand\SB@@lowfret[3]{{%
+ \let\SB@barreI\SB@barreN%
+ \let\SB@barreY\SB@barreN%
+ \xdef#1{#1}%
+}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@bactivate}
+% If we see the current fret within a barre, tentatively activate the barre
+% (unless it is already deactivated).
+% \begin{macrocode}
+\newcommand\SB@bactivate[3]{{%
+ \let\SB@barreI\SB@barreY%
+ \xdef#1{#1}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@bbarre}
+% Starting a barre group pushes it onto its stack in the initial state.
+% \begin{macrocode}
+\newcommand\SB@bbarre[1]{%
+ \xdef#1{\SB@barreI{\the\SB@cntii}#1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@ebarre}
+% \begin{macro}{\SB@@ebarre}
+% \begin{macro}{\SB@@@ebarre}
+% Ending a barre group pops it and draws it if it's active.
+% \begin{macrocode}
+\newcommand\SB@ebarre[3]{%
+ \ifx#1\@empty%
+ \ifnum\SB@cnt=\@ne\SB@errebar#2#3\fi%
+ \else%
+ \expandafter\SB@@ebarre#1\SB@@ebarre#1%
+ \fi%
+}
+\newcommand\SB@@ebarre{}
+\def\SB@@ebarre#1#2#3\SB@@ebarre#4{{%
+ \gdef#4{#3}%
+ \let\SB@barreI\@gobble%
+ \let\SB@barreN\@gobble%
+ \let\SB@barreY\SB@barre%
+ #1{#2}%
+}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@barreson}
+% \begin{macro}{\SB@barresoff}
+% Turn barre delimiters on or off, depending on whether we're typesetting
+% the interior or upper part of the tablature diagram.
+% \begin{macrocode}
+\newcommand\SB@barreson[3]{%
+ \def#2{\SB@bbarre#1}%
+ \def#3{\SB@ebarre#1#2#3}%
+}
+\newcommand\SB@barresoff[3]{\let#2\relax\let#3\relax}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@fretempty}
+% \begin{macro}{\SB@fretdot}
+% \begin{macro}{\SB@@fretdot}
+% On a string in a fret diagram there can be nothing or a filled circle.
+% \begin{macrocode}
+\newcommand\SB@fretempty{%
+ \advance\SB@cntii\@ne%
+ \SB@onfret\relax%
+}
+\newcommand\SB@fretdot{%
+ \advance\SB@cntii\@ne%
+ \let\SB@dobarre\SB@bactivate\SB@allbarres%
+ \SB@@fretdot%
+}
+\newcommand\SB@@fretdot{%
+ \SB@onfret{%
+ \fontencoding{OMS}\fontfamily{cmsy}%
+ \fontseries{m}\fontshape{n}%
+ \fontsize\@xiipt\@xiipt\selectfont\char15%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@barre}
+% Draw a barre.
+% \begin{macrocode}
+\newcommand\SB@barre[1]{{%
+ \SB@dimen\SB@fretwidth%
+ \multiply\SB@dimen\SB@cntii%
+ \advance\SB@dimen-#1\SB@fretwidth%
+ \kern-\SB@dimen%
+ \SB@@fretdot%
+ \kern-.5\SB@fretwidth%
+ \advance\SB@dimen-\SB@fretwidth%
+ \raise.7pt\hbox{\vrule\@height4.6\p@\@width\SB@dimen}%
+ \kern-.5\SB@fretwidth%
+ \SB@@fretdot%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@fretend}
+% At the end of a barred row in a tablature diagram, we auto-finish any
+% activated barres that weren't explicitly closed by the user.
+% \begin{macrocode}
+\newcommand\SB@fretend{{%
+ \let\SB@barreI\@gobble%
+ \let\SB@barreN\@gobble%
+ \let\SB@barreY\SB@barre%
+ \def\SB@dobarre##1##2##3{##1\gdef##1{}}\SB@allbarres%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@finger}
+% \begin{macro}{\SB@X}
+% \begin{macro}{\SB@Z}
+% \begin{macro}{\SB@O}
+% If we're including fingering info in the tablature diagram, then below
+% each string there might be a number.
+% \begin{macrocode}
+\newcommand*\SB@X{X}
+\newcommand*\SB@Z{0}
+\newcommand*\SB@O{O}
+\newcommand\SB@finger[1]{%
+ \def\SB@temp{#1}%
+ \ifx\SB@temp\SB@X\SB@topempty\else%
+ \ifx\SB@temp\SB@Z\SB@topempty\else%
+ \ifx\SB@temp\SB@O\SB@topempty\else%
+ \SB@atopfret{\sffamily\fontsize\@vipt\@vipt\selectfont#1}%
+ \fi\fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ifSB@gettabind}
+% \begin{macro}{\SB@tabindent}
+% Lyrics under tablature diagrams look odd if they aren't aligned with the
+% leftmost string of the diagram.
+% To accomplish this, the following two macros record the amount by which
+% a lyric under this tablature diagram must be indented to position it
+% properly.
+% \begin{macrocode}
+\newif\ifSB@gettabind\SB@gettabindfalse
+\SB@newdimen\SB@tabindent
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@targfret}
+% \begin{macro}{\SB@targstr}
+% \begin{macro}{\SB@targfing}
+% Reserve some macro names in which to store the three pieces of the
+% second argument to the |\gtab| macro.
+% The first is for the fret number, the second is for the \Meta{strings}
+% info, and the last is for the \Meta{fingering} info.
+% \begin{macrocode}
+\newcommand\SB@targfret{}
+\newcommand\SB@targstr{}
+\newcommand\SB@targfing{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% In general |\gtab| macros often appear inside chord macros, which means
+% that their arguments have already been scanned by the time the
+% |\gtab| macro itself is expanded.
+% This means that catcodes cannot be reassigned (without resorting to
+% $\varepsilon$-\TeX).
+%
+% We therefore adopt the alternative strategy of converting each token
+% in the \Meta{strings} and \Meta{fingering} arguments of a |\gtab| macro
+% into a control sequence (using |\csname|).
+% We can then temporarily assign meanings to those control sequences and
+% replay the arguments to achieve various effects.
+%
+% \begin{macro}{\SB@gtinit}
+% \begin{macro}{\SB@gtinc}
+% Different meanings are assigned to digits, |X|'s, and |O|'s
+% as we typeset each row of the interior of the diagram.
+% These meanings are set by |\SB@gtinit| and |\SB@gtinc|.
+% \begin{macrocode}
+\newcommand\SB@gtinit{%
+ \def\SB@do##1{\csname##1\endcsname}%
+ \let\O\0%
+ \let\3\2\let\4\2\let\5\2\let\6\2%
+ \let\7\2\let\8\2\let\9\2%
+}
+\newcommand\SB@gtinc{%
+ \advance\SB@cnt\@ne%
+ \let\9\8\let\8\7\let\7\6\let\6\5\let\5\4%
+ \let\4\3\let\3\2\let\2\1\let\1\SB@lowfret%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\BarreDelims}
+% \begin{macro}{\SB@bdelims}
+% Each pair of barre delimiters reserves a stack and augments the
+% initialization state to recognize those delimiters.
+% \begin{macrocode}
+\newcommand\BarreDelims[2]{%
+ \expandafter\SB@bdelims\csname SB@bs@#1#2\expandafter\endcsname%
+ \csname#1\expandafter\endcsname\csname#2\endcsname%
+}
+\newcommand\SB@bdelims[3]{%
+ \newcommand*#1{}%
+ \SB@app\def\SB@allbarres{\SB@dobarre#1#2#3}%
+}
+\BarreDelims()
+\BarreDelims[]
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\gtab}
+% \begin{macro}{\SB@gtab}
+% \changes{v2.9}{2009/03/27}{Fixed compatibility issue with Babel French}
+% A |\gtab| macro begins by setting catcodes suitable for parsing a chord
+% name as its first argument.
+% This allows tokens like |#| and |&| to be used for sharp and flat even
+% when |\gtab| is used outside a chord macro.
+% Colon is reset to a non-active character while processing the second
+% argument to avoid a potential conflict with \textsf{Babel} French.
+% \begin{macrocode}
+\newcommand\gtab{\SB@begincname\SB@gtab}
+\newcommand*\SB@gtab[1]{%
+ \SB@endcname%
+ \begingroup%
+ \catcode`:12\relax%
+ \SB@@gtab{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@@gtab}
+% If transposition is currently taking place, allow the user to customize
+% the behavior by redefining |\gtabtrans|.
+% Using |\gtab| within |\gtabtrans| should go directly to |\SB@@@gtab|
+% (otherwise an infinite loop would result!).
+% \begin{macrocode}
+\newcommand*\SB@@gtab[2]{%
+ \endgroup%
+ \ifnum\SB@transposefactor=\z@%
+ \SB@@@gtab{#1}{#2}%
+ \else%
+ \begingroup%
+ \let\gtab\SB@@@gtab%
+ \gtabtrans{#1}{#2}%
+ \endgroup%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\gtabtrans}\MainImpl{gtabtrans}
+% By default, transposed guitar tablatures just display the transposed
+% chord name and omit the diagram.
+% Transposing a tablature diagram requires manual judgment calls for most
+% stringed instruments, so we can't do it automatically.
+% \begin{macrocode}
+\newcommand\gtabtrans[2]{\transposehere{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@@@gtab}\MainImpl{gtab}
+% \changes{v2.13}{2011/04/16}{Added transposition for chord names}
+% Typeset a full tablature diagram.
+% Text \argp{1} is a chord name placed above the diagram.
+% Text \argp{2} consists of a colon-separated list of:
+% (1) an optional fret number placed to the left of the diagram;
+% (2) a sequence of tokens, each of which can be
+% |X| (to place an $\times$ above the string),
+% |0| or |O| (to place an $\circ$ above the string), or
+% one of |1| through |9| (to place a filled circle on that string at the
+% fret of the given number); and
+% (3) an optional sequence of tokens, each of which is either |0|
+% (no fingering information for that string),
+% or one of |1| through |4| (to place the given number under that string).
+% \begin{macrocode}
+\newcommand\SB@@@gtab[2]{%
+ \let\SB@targfret\@empty%
+ \let\SB@targstr\@empty%
+ \let\SB@targfing\@empty%
+ \SB@tabargs#2:::\SB@tabargs%
+ \ifx\SB@targstr\@empty%
+ \def\SB@targstr{\0\0\0\0\0\0}%
+ \fi%
+ \ifvmode\leavevmode\fi%
+ \vbox{%
+ \normalfont\normalsize%
+ \setbox\SB@box\hbox{%
+ \thinspace{\printchord{\transposehere{#1}\strut}}\thinspace%
+ }%
+ \setbox\SB@boxii\hbox{\SB@fretnum{\SB@targfret}}%
+ \setbox\SB@boxiii\hbox{{%
+ \let\X\SB@topX\let\0\SB@topO%
+ \let\1\SB@topempty\let\2\1%
+ \SB@gtinit%
+ \let\SB@dobarre\SB@barresoff\SB@allbarres%
+ \SB@targstr%
+ }}%
+ \hsize\wd\SB@box%
+ \ifSB@gettabind%
+ \global\SB@tabindent\wd\SB@boxii%
+ \global\advance\SB@tabindent.5\SB@fretwidth%
+ \global\advance\SB@tabindent-.5\p@%
+ \fi%
+ \SB@dimen\wd\SB@boxii%
+ \advance\SB@dimen\wd\SB@boxiii%
+ \ifdim\hsize<\SB@dimen%
+ \hsize\SB@dimen%
+ \else\ifSB@gettabind%
+ \SB@dimenii\hsize%
+ \advance\SB@dimenii-\SB@dimen%
+ \divide\SB@dimenii\tw@%
+ \global\advance\SB@tabindent\SB@dimenii%
+ \fi\fi%
+ \hbox to\hsize{\hfil\unhbox\SB@box\hfil}%
+ \kern-\p@\nointerlineskip%
+ \hbox to\hsize{%
+ \hfil%
+ \vtop{\kern\p@\kern2\p@\box\SB@boxii}%
+ \vtop{%
+ \SB@dimen\wd\SB@boxiii%
+ \box\SB@boxiii%
+ \let\X\SB@fretempty\let\0\X%
+ \let\1\SB@fretdot\def\2{\SB@fretempty\global\SB@testtrue}%
+ \SB@gtinit%
+ \let\SB@dobarre\SB@barreson\SB@allbarres%
+ \SB@cnt\@ne%
+ \loop%
+ \SB@testfalse%
+ \SB@fretbar\hbox{\SB@cntii\z@\SB@targstr\SB@fretend}%
+ \ifnum\SB@cnt<\minfrets\SB@testtrue\fi%
+ \ifSB@test\SB@gtinc\repeat%
+ \SB@fretbar%
+ \ifx\SB@targsfing\@empty\else%
+ \kern1.5\p@%
+ \hbox{\let\SB@do\SB@finger\SB@targfing}%
+ \fi%
+ }%
+ \hfil%
+ }%
+ \kern3\p@%
+ }%
+ \SB@gettabindfalse%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@tabargs}
+% \begin{macro}{\SB@@tabargs}
+% \begin{macro}{\SB@ctoken}
+% \changes{v3.1}{2017/06/23}{Allow macros within 2nd gtab arg}
+% Break the second argument to a |\gtab| macro into three sub-arguments.
+% The possible forms are:
+% (a) \Meta{strings},
+% (b) \Meta{fret}|:|\Meta{strings},
+% (c) \Meta{strings}|:|\Meta{fingering}, or
+% (d) \Meta{fret}|:|\Meta{strings}|:|\Meta{fingering}.
+% To distinguish forms (b) and (c), we count the number of tokens before
+% the first colon.
+% If there is only one token or group, we assume it must be form (b),
+% since frets larger than 9 and 1-stringed instruments are both rare.
+% Otherwise we assume form (c).
+% \begin{macrocode}
+\newcommand\SB@ctoken{} \def\SB@ctoken{:}
+\newcommand\SB@tabargs{}
+\def\SB@tabargs#1:#2:#3:#4\SB@tabargs{%
+ \def\SB@temp{#4}%
+ \ifx\SB@temp\@empty%
+ \SB@doify\SB@targstr{#1}%
+ \else\ifx\SB@temp\SB@ctoken%
+ \SB@@tabargs#1\SB@@tabargs%
+ \ifx\SB@temp\@empty%
+ \def\SB@targfret{#1}%
+ \SB@doify\SB@targstr{#2}%
+ \else%
+ \SB@doify\SB@targfing{#2}%
+ \SB@doify\SB@targstr{#1}%
+ \fi%
+ \else%
+ \def\SB@targfret{#1}%
+ \SB@doify\SB@targfing{#3}%
+ \SB@doify\SB@targstr{#2}%
+ \fi\fi%
+}
+\newcommand\SB@@tabargs{}
+\def\SB@@tabargs#1#2\SB@@tabargs{\def\SB@temp{#2}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Book Sectioning}
+%
+% The following macros divide the song book into distinct sections, each with
+% different headers, different song numbering styles, different indexes, etc.
+%
+% \begin{macro}{\songchapter}\MainImpl{songchapter}
+% \changes{v1.19}{2005/10/24}{Added}
+% Format the chapter header for a chapter in a song book.
+% By default, chapter headers on a song book omit the chapter number, but do
+% include an entry in the pdf index or table of contents.
+% Thus, the chapter has a number; it's just not displayed at the start of
+% the chapter.
+% \begin{macrocode}
+\newcommand\songchapter{%
+ \let\SB@temp\@seccntformat%
+ \def\@seccntformat##1{}%
+ \@startsection{chapter}{0}{\z@}%
+ {3.5ex\@plus1ex\@minus.2ex}%
+ {.4ex\let\@seccntformat\SB@temp}%
+ {\sffamily\bfseries\LARGE\centering}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\songsection}\MainImpl{songsection}
+% \changes{v1.19}{2005/10/24}{Section headers changed to omit numbers}
+% Format the section header for a section in a song book.
+% This is the same as for chapter headers except at the section level.
+% \begin{macrocode}
+\newcommand\songsection{%
+ \let\SB@temp\@seccntformat%
+ \def\@seccntformat##1{}%
+ \@startsection{section}{1}{\z@}%
+ {3.5ex\@plus1ex\@minus.2ex}%
+ {.4ex\let\@seccntformat\SB@temp}%
+ {\sffamily\bfseries\LARGE\centering}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{songs}\MainEnvImpl{songs}
+% \changes{v1.19}{2005/10/24}{Song numbers now starts at one instead of zero}
+% Begin and end a book section.
+% The argument is a list of indexes with which to associate songs in this
+% section.
+% \begin{macrocode}
+\newenvironment{songs}[1]{%
+ \ifSB@songsenv\SB@errnse\fi%
+ \gdef\SB@indexlist{#1}%
+ \SB@chkidxlst%
+ \stepcounter{SB@songsnum}%
+ \setcounter{songnum}{1}%
+ \let\SB@sgroup\@empty%
+ \ifinner\else\ifdim\pagetotal>\z@%
+ \null\nointerlineskip%
+ \fi\fi%
+ \songcolumns\SB@numcols%
+ \SB@songsenvtrue%
+}{%
+ \commitsongs%
+ \global\let\SB@indexlist\@empty%
+ \ifinner\else\clearpage\fi%
+ \SB@songsenvfalse%
+}
+% \end{macrocode}
+% \end{environment}
+%
+% Each |songs| section needs a unique number to aid in hyperlinking.
+% \begin{macrocode}
+\newcounter{SB@songsnum}
+% \end{macrocode}
+%
+% \subsection{Index Generation}
+% \label{sec:indexgen}
+%
+% The following macros generate the various types of indexes. At present there
+% are four types:
+% \begin{enumerate}
+% \item A ``large'' index has a separate section for each capital letter and
+% is printed in two columns.
+% \item A ``small'' index has only a single column, centered, and has no
+% sections.
+% \item A ``scripture'' index has three columns and each entry has a
+% comma-separated list of references.
+% \item An ``author'' index is like a large index except in bold and without
+% the sectioning.
+% \end{enumerate}
+% ``Large'' and ``small'' indexes will be chosen automatically based on the
+% number of index entries when building a song index. The other two types are
+% designated by the user.
+%
+% As is typical of \LaTeX{} indexes, generation of song book indexes requires
+% two passes of document compilation. During the first pass, data files are
+% generated with song titles, authors, and scripture references. An external
+% program is then used to produce \LaTeX{} source files from those data files.
+% During the second pass of document compilation, those source files are
+% imported to typeset all the indexes and display them in the document.
+%
+% Internally, this package code uses a \emph{four} step process to move
+% the index data from the source |.tex| file to the |.sxd| data files.
+% \begin{enumerate}
+% \item While the current song box is in the midst of construction,
+% the data is stored in a box of non-immediate write whatsit nodes.
+% \item The whatsits are migrated out to the top of the song box when
+% it is finalized at |\endsong|.
+% \item When the song box is shipped out to the output file, \TeX{} expands
+% the whatsits, causing the data to be written to the |.sxc| auxiliary file.
+% \item At the |\end{document}| line, the |.sxc| is processed multiple
+% times---once for each index---to split the data into the respective
+% |.sxd| files.
+% \end{enumerate}
+% The first and second steps allow index references to point to the
+% beginning of the song no matter where the indexing commands appear
+% within the song.
+% The third step allows \TeX{} to drop index entries that refer to
+% songs that do not actually appear in the output (e.g., because of
+% |\includeonlysongs|).
+% It also allows index entries to refer to information that is only decided
+% at shipout time, such as page numbers.
+% The fourth step allows all indexing to be accomplished with at most one
+% write register.
+% \LaTeX{} provides extremely few write registers, so using as
+% few as possible is essential for supporting books with many indexes.
+%
+% \begin{macro}{\songtarget}\MainImpl{songtarget}
+% This macro is invoked by each \mac{beginsong} environment with two arguments:
+% (1) a suggested pdf bookmark index level, and
+% (2) a target name to which hyperlinks for this song in the index will refer.
+% The macro is expected to produce a suitable pdf bookmark entry and/or
+% link target.
+% The default definition tries to use |\pdfbookmark| if generating a PDF,
+% and resorts to |\hypertarget| (if it exists) otherwise.
+% The user can redefine the macro to customize how and whether bookmarks
+% and/or links are created.
+% \begin{macrocode}
+\newcommand\songtarget[2]{%
+ \ifnum\@ne=0\ifSB@pdf\ifx\pdfbookmark\undefined\else%
+ \ifx\pdfbookmark\relax\else1\fi\fi\fi\relax%
+ \pdfbookmark[#1]{\thesongnum. \songtitle}{#2}%
+ \else\ifx\hypertarget\undefined%
+ \else\ifx\hypertarget\relax\else%
+ \hypertarget{#2}{\relax}%
+ \fi\fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\songlink}\MainImpl{songlink}
+% This macro is invoked by the index code to produce a link to a song target
+% created by \mac{songtarget}.
+% Its two arguments are:
+% (1) the target name (same as the second argument to \mac{songtarget}, and
+% (2) the text that is to be linked.
+% The default implementation uses |\hyperlink| if it exists; otherwise it
+% just leaves the text unlinked.
+% \begin{macrocode}
+\newcommand\songlink{%
+ \ifnum\@ne=0\ifx\hyperlink\undefined\else%
+ \ifx\hyperlink\relax\else1\fi\fi\relax%
+ \expandafter\hyperlink%
+ \else%
+ \expandafter\@gobble%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@indexlist}
+% This macro records the comma-separated list of the identifiers of indexes
+% associated with the current book section.
+% \begin{macrocode}
+\newcommand\SB@indexlist{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@allindexes}
+% This macro records a comma-separated list of all the index identifiers
+% for the entire document.
+% \begin{macrocode}
+\newcommand\SB@allindexes{}
+\let\SB@allindexes\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@out}
+% The |\SB@out| control sequence is reserved for the write register allocated
+% by the package code, if one is needed.
+% (It is allocated at the first index declaration.)
+% \begin{macrocode}
+\newcommand\SB@out{}
+\let\SB@out\relax
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@newindex}
+% Initialize a new title, author, or scripture index.
+% \begin{macrocode}
+\newcommand\SB@newindex[4]{%
+ \expandafter\newcommand\csname SB@idxfilename@#3\endcsname{#4}%
+ \expandafter\newcommand\csname SB@idxsel@#3\endcsname[3]{###1}%
+ \expandafter\newcommand\csname SB@idxref@#3\endcsname{\thesongnum}%
+ \xdef\SB@allindexes{%
+ \ifx\SB@allindexes\@empty\else\SB@allindexes,\fi#3%
+ }%
+ \if@filesw%
+ \ifx\SB@out\relax%
+ \SB@newwrite\SB@out%
+ \immediate\openout\SB@out=\jobname.sxc\relax%
+ \fi%
+ \immediate\write\SB@out{\noexpand\SB@iwrite{#3}{#2}}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newindex}\MainImpl{newindex}
+% Define a new title index.
+% The first argument is an identifier for the index (used in constructing
+% index-specific control sequence names).
+% The second argument is a filename root; auxiliary file \argp{2}|.sxd| is
+% where the index data is stored at the end of processing.
+% \begin{macrocode}
+\newcommand\newindex{\SB@newindex1{TITLE INDEX DATA FILE}}
+\@onlypreamble\newindex
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newscripindex}\MainImpl{newscripindex}
+% Define a new scripture index. This is exactly like |\newindex| except that
+% scripture references are added to the auxiliary file instead of titles.
+% \begin{macrocode}
+\newcommand\newscripindex{\SB@newindex2{SCRIPTURE INDEX DATA FILE}}
+\@onlypreamble\newscripindex
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newauthorindex}\MainImpl{newauthorindex}
+% Define a new author index. This is exactly like |\newindex| except that
+% author info is added to the auxiliary file instead of titles.
+% \begin{macrocode}
+\newcommand\newauthorindex{\SB@newindex3{AUTHOR INDEX DATA FILE}}
+\@onlypreamble\newauthorindex
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@cwrite}
+% Write index data to a Song indeX Combined (|.sxc|) auxiliary file.
+% The first argument is the identifier for the index to which the data
+% ultimately belongs.
+% The second argument is the data itself.
+% The write is non-immediate so that it is only output if its enclosing
+% song is ultimately shipped to the output file.
+% \begin{macrocode}
+\newcommand\SB@cwrite[2]{%
+ \ifx\SB@out\relax\else%
+ \protected@write\SB@out\SB@keepactive{\protect\SB@iwrite{#1}{#2}}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@keepactive}
+% By default, the |inputenc| package expands Unicode characters into macro
+% names when writing them to files.
+% This behavior must be inhibited when writing to the |.sxc| file, since
+% |songidx| needs the original Unicode characters for sorting.
+% To achieve this, we temporarily redefine most active characters so that
+% they expand to an unexpandable string version of themselves.
+% \begin{macrocode}
+\newcommand\SB@keepactive{}
+{\catcode`\~\active
+ \catcode`\.12
+ \def\\#1#2{%
+ \endgroup
+ \SB@app\gdef\SB@keepactive{\def#1{#2}}%
+ }
+ \def\SB@temp#1#2{%
+ \SB@cnt#1\relax
+ \loop
+ \begingroup
+ \uccode`\~\SB@cnt
+ \uccode`\.\SB@cnt
+ \uppercase{\\~.}
+ \ifnum\SB@cnt<#2\relax
+ \advance\SB@cnt\@ne
+ \repeat
+ }
+ \SB@temp{1}{8}
+ \SB@temp{11}{11}
+ \SB@temp{14}{91}
+ \SB@temp{93}{255}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@iwrite}
+% The line contributed by |\SB@cwrite| to the |.sxc| file is an |\SB@iwrite|
+% macro that re-outputs the data to an appropriate |.sxd| file.
+% \begin{macrocode}
+\newcommand\SB@iwrite[2]{%
+ \def\SB@tempii{#1}%
+ \ifx\SB@temp\SB@tempii%
+ \SB@toks{#2}%
+ \immediate\write\SB@out{\the\SB@toks}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@uncombine}
+% At the end of the document, the |.sxc| file can be processed multiple
+% times to produce all the |.sxd| files without resorting to multiple write
+% registers.
+% Each pass activates the subset of the |\SB@iwrite| commands that apply to
+% one index.
+% \begin{macrocode}
+\newcommand\SB@uncombine{%
+ \ifx\SB@out\relax\else%
+ \immediate\closeout\SB@out%
+ \ifsongindexes%
+ \@for\SB@temp:=\SB@allindexes\do{%
+ \immediate\openout\SB@out=%
+ \csname SB@idxfilename@\SB@temp\endcsname.sxd\relax%
+ \begingroup\makeatletter\catcode`\%12\relax%
+ \input{\jobname.sxc}\endgroup%
+ \immediate\closeout\SB@out%
+ }%
+ \fi%
+ \fi%
+}
+\AtEndDocument{\SB@uncombine}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@songwrites}
+% The following box register stores index data until it can be migrated to
+% the top of the song box currently under construction.
+% \begin{macrocode}
+\SB@newbox\SB@songwrites
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@addtoindex}
+% \changes{v2.8}{2009/02/03}{Writes made non-immediate}
+% Queue data \argp{2} associated with the current song for eventual writing
+% to the index whose identifier is given by \argp{1}.
+% \begin{macrocode}
+\newcommand\SB@addtoindex[2]{%
+ \protected@edef\SB@tempii{#2}%
+ \ifx\SB@tempii\@empty\else%
+ \global\setbox\SB@songwrites\vbox{%
+ \unvbox\SB@songwrites%
+ \SB@cwrite{#1}{#2}%
+ \SB@cwrite{#1}{\csname SB@idxref@#1\endcsname}%
+ \SB@cwrite{#1}{song\theSB@songsnum-\thesongnum.%
+ \ifnum\c@section=\z@1\else2\fi}%
+ }%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@addtoindexes}
+% Add \argp{1} to all title indexes, \argp{2} to all scripture indexes, and
+% \argp{3} to all author indexes.
+% \begin{macrocode}
+\newcommand\SB@addtoindexes[3]{%
+ \@for\SB@temp:=\SB@indexlist\do{%
+ \SB@addtoindex\SB@temp%
+ {\csname SB@idxsel@\SB@temp\endcsname{#1}{#2}{#3}}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@addtotitles}
+% Add \argp{1} to all title indexes, but leave other indexes unaffected.
+% \begin{macrocode}
+\newcommand\SB@addtotitles[1]{%
+ \@for\SB@temp:=\SB@indexlist\do{%
+ \csname SB@idxsel@\SB@temp\endcsname%
+ {\SB@addtoindex\SB@temp{#1}}{}{}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@chkidxlst}
+% \changes{v2.3}{2007/09/23}{Added.}
+% Check the current list of indexes and flag an error if any are undefined.
+% \begin{macrocode}
+\newcommand\SB@chkidxlst{%
+ \let\SB@temp\SB@indexlist%
+ \let\SB@indexlist\@empty%
+ \@for\SB@tempii:=\SB@temp\do{%
+ \@ifundefined{SB@idxsel@\SB@tempii}{\SB@errnoidx\SB@tempii}{%
+ \ifx\SB@indexlist\@empty%
+ \SB@toks\expandafter{\SB@tempii}%
+ \else%
+ \SB@toks\expandafter\expandafter\expandafter{%
+ \expandafter\SB@indexlist\expandafter,\SB@tempii}%
+ \fi%
+ \edef\SB@indexlist{\the\SB@toks}%
+ }%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\indexentry}\MainImpl{indexentry}
+% \changes{v2.3}{2007/09/23}{Optional argument added}
+% \begin{macro}{\SB@idxentry}
+% \begin{macro}{\SB@@idxentry}
+% |\SB@addtoindexes| will be called automatically for each song in a section.
+% However, |\indexentry| may be called by the user in order to add an
+% alternative index entry for the given song.
+% Usually this is done to index the song by its first line or some other
+% memorable line in a chorus or verse somewhere.
+% \begin{macrocode}
+\newcommand\indexentry{\@ifnextchar[{\SB@idxentry*}{\SB@@idxentry*}}
+\newcommand\SB@idxentry{}
+\def\SB@idxentry#1[#2]#3{{%
+ \def\SB@indexlist{#2}%
+ \SB@chkidxlst%
+ \SB@addtoindexes{#1#3}{#3}{#3}%
+}}
+\newcommand\SB@@idxentry[2]{\SB@addtotitles{#1#2}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\indextitleentry}\MainImpl{indextitleentry}
+% \changes{v2.3}{2007/09/23}{Optional argument added}
+% |\indextitleentry| may be used to add an alternate title for the song to
+% the index.
+% (The only difference between the effects of |\indexentry| and
+% |\indextitleentry| is that the latter are italicized in the rendered index
+% and the former are not.)
+% \begin{macrocode}
+\newcommand\indextitleentry{%
+ \@ifnextchar[{\SB@idxentry{}}{\SB@@idxentry{}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\indexsongsas}\MainImpl{indexsongsas}
+% \changes{v2.8}{2009/02/03}{Added.}
+% The following macro allows the user to change how songs are indexed on the
+% right side of index entries.
+% By default, the song's number is listed.
+% \begin{macrocode}
+\newcommand\indexsongsas[1]{%
+ \@ifundefined{SB@idxref@#1}%
+ {\SB@errnoidx{#1}\@gobble}%
+ {\expandafter\renewcommand\csname SB@idxref@#1\endcsname}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@idxcmd}
+% \begin{macro}{\SB@@idxcmd}
+% \begin{macro}{\authsepword}\MainImpl{authsepword}
+% \begin{macro}{\authbyword}\MainImpl{authbyword}
+% \begin{macro}{\authignoreword}\MainImpl{authignoreword}
+% \begin{macro}{\titleprefixword}\MainImpl{titleprefixword}
+% \changes{v2.0}{2007/06/18}{Added.}
+% The |songidx| index-generation script understands several different
+% directives that each dictate various aspects of how index entries are
+% parsed, sorted, and displayed.
+% Such directives should typically appear at the start of the |.sxd|
+% file just after the header line that identifies the type of index.
+% \begin{macrocode}
+\newcommand\SB@idxcmd[3]{%
+ \ifx\SB@allindexes\@empty%
+ \SB@warnnoidx%
+ \else\ifx\SB@out\relax\else%
+ \@for\SB@temp:=\SB@allindexes\do{%
+ \csname SB@idxsel@\SB@temp\endcsname%
+ {\SB@@idxcmd{#1}}{\SB@@idxcmd{#2}}{\SB@@idxcmd{#3}}%
+ }%
+ \fi\fi%
+}
+\newcommand\SB@@idxcmd[1]{%
+ \def\SB@tempii{#1}%
+ \ifx\SB@tempii\@empty\else%
+ \immediate\write\SB@out{%
+ \noexpand\SB@iwrite{\SB@temp}{#1}%
+ }%
+ \fi%
+}
+\newcommand\authsepword[1]{}
+\newcommand\authbyword[1]{}
+\newcommand\authignoreword[1]{}
+\newcommand\titleprefixword[1]{}
+{\catcode`\%=12
+ \gdef\authsepword#1{\SB@idxcmd{}{}{%sep #1}}
+ \gdef\authbyword#1{\SB@idxcmd{}{}{%after #1}}
+ \gdef\authignoreword#1{\SB@idxcmd{}{}{%ignore #1}}
+ \gdef\titleprefixword#1{\SB@idxcmd{%prefix #1}{}{}}}
+\@onlypreamble\authsepword
+\@onlypreamble\authbyword
+\@onlypreamble\authignoreword
+\@onlypreamble\titleprefixword
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@idxlineskip}
+% Set the spacing between lines in an index.
+% \begin{macrocode}
+\newcommand\SB@idxlineskip[1]{%
+ \vskip#1\p@\@plus#1\p@\@minus#1\p@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% When rendering an index entry $X\ldots Y$ that is too long to fit on one
+% physical line, we must break text $X$ and/or $Y$ up into multiple lines.
+% Text $X$ should be typeset as a left-justified paragraph with a right
+% margin of about 2em; however, its final line must not be so long that it
+% cannot fit even the first item of list $Y$.
+% Text $Y$ should be typeset as a right-justified paragraph whose first line
+% begins on the last line of $X$.
+% However, breaking $Y$ up the way paragraphs are normally broken up doesn't
+% work well because that causes most of $Y$ to be crammed into the first few
+% lines, leaving the last line very short.
+% This looks strange and is hard to read.
+% It looks much better to instead break $Y$ up in such a way that the portion
+% of $Y$ that is placed on each line is of approximately equal width (subject
+% to the constraint that we don't want to introduce any more lines than are
+% necessary).
+% This makes it visually clear that all of these lines are associated with $X$.
+% The following code performs the width computations that do this
+% horizontal-balancing of text.
+%
+% \begin{macro}{\SB@ellipspread}
+% Typeset an index entry of the form $X\ldots Y$.
+% In the common case, the entire entry fits on one line so we just typeset
+% it in the usual way.
+% If it doesn't fit on one line, we call |\SB@balancerows| for a more
+% sophisticated treatment.
+% \begin{macrocode}
+\newcommand\SB@ellipspread[2]{%
+ \begingroup%
+ \SB@dimen\z@%
+ \def\SB@temp{#1}%
+ \SB@toks{#2}%
+ \setbox\SB@box\hbox{{%
+ \SB@temp%
+ \leaders\hbox to.5em{\hss.\hss}\hskip2em\@plus1fil%
+ {\the\SB@toks}%
+ }}%
+ \ifdim\wd\SB@box>\hsize%
+ \SB@balancerows%
+ \else%
+ \hbox to\hsize{\unhbox\SB@box}\par%
+ \fi%
+ \endgroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@balancerows}
+% Typeset an index entry of the form $X\ldots Y$ that doesn't fit on one line,
+% where $X$ is the content of macro |\SB@temp| and
+% $Y$ is the content of token register |\SB@toks|.
+%
+% First, we must pre-compute the width $w_1$ of the final line of $X$ when
+% $X$ is typeset as a left-justified paragraph, storing it in |\SB@dimenii|.
+% This is necessary because in order to force \TeX{} to typeset the first
+% line of $Y$ at some chosen width $w_2$, we must insert leaders of width
+% $c-w_1-w_2$ into the paragraph between $X$ and $Y$, where $c$ is the column
+% width.
+%
+% Computing this width $w_1$ is a bit tricky.
+% We must tell \TeX{} that the last line of $X$ must not be so long that it
+% does not even have room for the first item of $Y$.
+% Thus, we must strip off the first item of $Y$ and add it (or a non-breaking
+% space of equivalent width) to the end of $X$ to typeset the paragraph.
+% Then we use |\lastbox| to pull off the final line and check its width.
+% \begin{macrocode}
+\newcommand\SB@balancerows{%
+ \edef\SB@tempii{\the\SB@toks}%
+ \setbox\SB@box\vbox{%
+ \SB@toks\expandafter{\expandafter\\\the\SB@toks\\}%
+ \SB@lop\SB@toks\SB@toks%
+ \settowidth\SB@dimen{\the\SB@toks}%
+ \advance\SB@dimen-.5em%
+ \leftskip.5cm%
+ {\hbadness\@M\hfuzz\maxdimen%
+ \hskip-.5cm\relax\SB@temp\unskip\nobreak%
+ \hskip\SB@dimen\nobreak%
+ \rightskip2em\@plus1fil\par}%
+ \setbox\SB@box\lastbox%
+ \setbox\SB@box\hbox{%
+ \unhbox\SB@box%
+ \unskip\unskip\unpenalty%
+ \unpenalty\unskip\unpenalty%
+ }%
+ \expandafter%
+ }%
+ \expandafter\SB@dimenii\the\wd\SB@box\relax%
+% \end{macrocode}
+% Next, compute the smallest width $w_2$ such that the index entry text
+% produced by |\SB@multiline| with |\SB@dimen|=$w_2$ has no more lines than
+% with |\SB@dimen| set to the maximum available width for the right-hand side.
+% This effectively horizontal-balances the right-hand side of the index entry
+% text, making all lines of $Y$ roughly equal in width without introducing
+% any extra lines.
+% \begin{macrocode}
+ \SB@dimen\hsize%
+ \advance\SB@dimen-.5cm%
+ \setbox\SB@box\vbox{%
+ \SB@multiline{\hbadness\@M\hfuzz\maxdimen}%
+ }%
+ \SB@dimeniii.5\SB@dimen%
+ \SB@dimeniv\SB@dimeniii%
+ \loop%
+ \SB@dimeniv.5\SB@dimeniv%
+ \setbox\SB@boxii\vbox{%
+ \SB@dimen\SB@dimeniii%
+ \SB@multiline{\hbadness\@M\hfuzz\maxdimen}%
+ }%
+ \ifnum\SB@cnt<\@M%
+ \ifdim\ht\SB@boxii>\ht\SB@box%
+ \advance\SB@dimeniii\SB@dimeniv%
+ \else%
+ \SB@dimen\SB@dimeniii%
+ \advance\SB@dimeniii-\SB@dimeniv%
+ \fi%
+ \else%
+ \advance\SB@dimeniii\SB@dimeniv%
+ \fi%
+ \ifdim\SB@dimeniv>2\p@\repeat%
+ \setbox\SB@box\box\voidb@x%
+ \setbox\SB@boxii\box\voidb@x%
+% \end{macrocode}
+% Finally, typeset the results based on the quantities computed above.
+% \begin{macrocode}
+ \SB@multiline\relax%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@multiline}
+% Create a paragraph containing text $X\ldots Y$
+% where $X$ is the content of |\SB@temp|, $Y$ is the content of |\SB@tempii|,
+% and $Y$ is restricted to width |\SB@dimen| (but may span multiple
+% lines of that width).
+% Dimen register |\SB@dimenii| must be set with the expected width of the
+% final line of $X$.
+% The first argument contains any parameter definitions that should be in
+% effect when $X$ is processed.
+%
+% Note that the expansion of |\SB@tempii|, which may contain |\SB@idxitemsep|,
+% depends on |\SB@dimen|.
+% Therefore, the redefinition of |\SB@dimen| at the start of this macro must
+% not be removed!
+% \begin{macrocode}
+\newcommand\SB@multiline[1]{%
+ \begingroup%
+ \SB@dimen-\SB@dimen%
+ \advance\SB@dimen\hsize%
+ \SB@dimenii-\SB@dimenii%
+ \advance\SB@dimenii\SB@dimen%
+ {#1\hskip-.5cm\relax\SB@temp\unskip\nobreak%
+ \SB@maxmin\SB@dimenii<{1.5em}%
+ \leftskip.5cm\rightskip2em\@plus1fil%
+ \interlinepenalty\@M%
+ \leaders\hbox to.5em{\hss.\hss}\hskip\SB@dimenii\@plus1fill%
+ \nobreak{\SB@tempii\kern-2em}%
+ \par\global\SB@cnt\badness}%
+ \endgroup%
+}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@idxitemsep}
+% \changes{v1.11}{2005/04/21}{Changed macro name to avoid a name clash}
+% If text $Y$ in index entry $X\ldots Y$ has multiple items in a list, those
+% items should be separated by |\\| macros instead of by commas.
+% The |\\| macro will be assigned the definition of |\SB@idxitemsep| during
+% index generation, which produces the comma along with the complex spacing
+% required if $Y$ ends up being broken into multiple lines.
+% In particular, it forces each wrapped line of $Y$ to be right-justified
+% with left margin at least |\SB@dimen|.
+% \begin{macrocode}
+\newcommand\SB@idxitemsep{%
+ ,\kern-2em\penalty-8\hskip2.33em\@minus.11em%
+ \hskip-\SB@dimen\@plus-1fill%
+ \vadjust{}\nobreak%
+ \hskip\SB@dimen\@plus1fill\relax%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% The following set of macros and environments are intended for use in the
+% |.sbx| files that are automatically generated by an index-generating
+% program; they shouldn't normally appear in the user's |.tex| or |.sbd|
+% files directly.
+% However, they are named as exported macros (no |@| symbols) since they are
+% used outside the package code and are therefore not stricly internal.
+%
+% \begin{environment}{idxblock}
+% Some indexes are divided into blocks (e.g., one for each letter of the
+% alphabet or one for each book of the bible).
+% Each such block should be enclosed between |\begin{idxblock}{X}| and
+% |\end{idxblock}| lines, where X is the title of the block. The actual
+% definition of the |idxblock| environment is set within the initialization
+% code for each type of index (below).
+% \begin{macrocode}
+\newenvironment{idxblock}[1]{}{}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\idxentry}
+% \begin{macro}{\idxaltentry}
+% Within each |idxblock| environment there should be a series of |\idxentry|
+% and/or |\idxaltentry| macros, one for each line of the index. Again, the
+% exact definitions of these macros will vary between index types.
+% \begin{macrocode}
+\newcommand\idxentry[2]{}
+\newcommand\idxaltentry[2]{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{SB@lgidx}
+% \begin{environment}{SB@smidx}
+% Some indexes actually have two definitions for each |idxblock|
+% environment---one for use when there are few enough entries to permit a
+% small style index, and another for use in a large style index. These macros
+% will be redefined appropriately within the initialization code for each
+% type of index.
+% \begin{macrocode}
+\newenvironment{SB@lgidx}[1]{}{}
+\newenvironment{SB@smidx}[1]{}{}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \begin{macro}{\SB@idxsetup}
+% Set various parameters for a column of an index environment.
+% \begin{macrocode}
+\newcommand\SB@idxsetup{%
+ \hsize\SB@colwidth%
+ \parskip\z@skip\parfillskip\z@skip\parindent\z@%
+ \baselineskip\f@size\p@\@plus\p@\@minus\p@%
+ \lineskiplimit\z@\lineskip\p@\@plus\p@\@minus\p@%
+ \hyphenpenalty\@M\exhyphenpenalty\@M%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@makeidxcolumn}
+% Break off enough material from |\SB@box| to create one column of the
+% index.
+% \begin{macrocode}
+\newcommand\SB@makeidxcolumn{%
+ \ifdim\ht\SB@box=\z@%
+ \hskip\hsize\relax%
+ \else%
+ \splittopskip\z@skip\splitmaxdepth\maxdepth%
+ \vsplit\SB@box to\SB@dimen%
+ \global\setbox\SB@box\vbox{%
+ \SB@idxsetup%
+ \splitbotmark%
+ \unvbox\SB@box%
+ }%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@oneidxpage}
+% Construct one full page of the index.
+% The definition of |\SB@oneidxpage| is generated dynamically based on the
+% type of index and number of columns.
+% \begin{macrocode}
+\newcommand\SB@oneidxpage{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@displayindex}
+% \changes{v1.11}{2005/04/21}{Item separator macro now localized in scope to the index file}
+% \changes{v2.0}{2007/06/18}{Removed hyperref dependency}
+% \changes{v2.6}{2008/02/16}{Balance columns on final page}
+% \changes{v2.8}{2009/03/06}{Changed argument order}
+% Create an index with title \argp{2} and with \argp{1} columns (must be a
+% literal constant). Input the index contents from external file \argp{3},
+% which is expected to be a \TeX{} file.
+% \begin{macrocode}
+\newcommand\SB@displayindex[3]{%
+ \ifsongindexes\begingroup%
+ \SB@colwidth\hsize%
+ \advance\SB@colwidth-#1\columnsep%
+ \advance\SB@colwidth\columnsep%
+ \divide\SB@colwidth#1%
+ \setbox\SB@envbox\vbox{%
+ \let\SB@temp\songsection%
+ \ifx\chapter\undefined\else%
+ \ifx\chapter\relax\else%
+ \let\SB@temp\songchapter%
+ \fi%
+ \fi%
+ \SB@temp{#2}%
+ }%
+% \end{macrocode}
+% The |.sbx| index file might not exist (e.g., if this is the first pass
+% through the \TeX{} compiler).
+% If it exists, first try typesetting its content as a small index
+% (one column, centered, with no divisions).
+% \begin{macrocode}
+ \IfFileExists{\csname SB@idxfilename@#3\endcsname.sbx}{%
+ \ifsepindexes%
+ \global\setbox\SB@box\vbox{%
+ \null%
+ \vfil%
+ \unvcopy\SB@envbox%
+ \vskip.5in\@minus.3in\relax%
+ \hbox to\hsize{%
+ \hfil%
+ \vbox{%
+ \SB@idxsetup%
+ \renewenvironment{idxblock}[1]%
+ {\begin{SB@smidx}{####1}}{\end{SB@smidx}}%
+ \let\\\SB@idxitemsep%
+ \input{\csname SB@idxfilename@#3\endcsname.sbx}%
+ }%
+ \hfil%
+ }%
+ \vskip\z@\@plus2fil\relax%
+ }%
+% \end{macrocode}
+% Test whether the resulting small index fits within one page.
+% If not, re-typeset it as a large index.
+% \begin{macrocode}
+ {\vbadness\@M\vfuzz\maxdimen%
+ \splitmaxdepth\maxdepth\splittopskip\z@skip%
+ \global\setbox\SB@boxii\vsplit\SB@box to\textheight}%
+ \ifvoid\SB@box%
+ \box\SB@boxii%
+ \else%
+ \SB@lgindex{#1}{#3}%
+ \fi%
+ \else%
+ \SB@lgindex{#1}{#3}%
+ \fi%
+ }%
+% \end{macrocode}
+% If the |.sbx| file doesn't exist, then instead typeset a page with a
+% message on it indicating that the document must be compiled a second
+% time in order to generate the index.
+% \begin{macrocode}
+ {%
+ \ifsepindexes%
+ \vbox to\textheight{%
+ \vfil%
+ \unvbox\SB@envbox%
+ \vskip1em\relax%
+ \hbox to\hsize{\hfil[Index not yet generated.]\hfil}%
+ \vskip\z@\@plus2fil\relax%
+ }%
+ \else%
+ \unvbox\SB@envbox%
+ \hbox to\hsize{\hfil[Index not yet generated.]\hfil}%
+ \fi%
+ }%
+ \ifsepindexes\clearpage\fi%
+ \endgroup\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@lgindex}
+% Typeset a large-style index.
+% We begin by typesetting the entire index into a box.
+% \begin{macrocode}
+\newcommand\SB@lgindex[2]{%
+ \global\setbox\SB@box\vbox{%
+ \renewenvironment{idxblock}[1]%
+ {\begin{SB@lgidx}{##1}}{\end{SB@lgidx}}%
+ \let\\\SB@idxitemsep%
+ \SB@idxsetup%
+ \input{\csname SB@idxfilename@#2\endcsname.sbx}%
+ \unskip%
+ }%
+% \end{macrocode}
+% Next, we split the box into columns and pages until the last page is reached.
+% \begin{macrocode}
+ \SB@toks{\SB@makeidxcolumn}%
+ \SB@cnt#1\relax%
+ \loop\ifnum\SB@cnt>\@ne%
+ \SB@toks\expandafter{\the\SB@toks%
+ \kern\columnsep\SB@makeidxcolumn}%
+ \advance\SB@cnt\m@ne%
+ \repeat%
+ \edef\SB@oneidxpage{\the\SB@toks}%
+ \unvbox\SB@envbox%
+ \vskip.2in\relax%
+ \nointerlineskip%
+ \null%
+ \nointerlineskip%
+ \SB@cnt\vbadness\vbadness\@M%
+ \SB@dimenii\vfuzz\vfuzz\maxdimen%
+ \loop%
+ \SB@dimen\textheight%
+ \ifinner\else\kern\z@\advance\SB@dimen-\pagetotal\fi%
+ \global\setbox\SB@boxii\copy\SB@box%
+ \global\setbox\SB@boxiii\hbox{\SB@oneidxpage}%
+ \ifdim\ht\SB@box>\z@%
+ \box\SB@boxiii%
+ \vfil\break%
+ \repeat%
+% \end{macrocode}
+% The final page of the index should have all equal-height columns instead
+% of a few full columns followed by some short or empty columns at the end.
+% To achieve this, we re-typeset the final page, trying different column
+% heights until we find one that causes the material to span an equal
+% percentage of all the columns on the page.
+% \begin{macrocode}
+ \SB@dimenii\ht\SB@boxii%
+ \divide\SB@dimenii#1\relax%
+ \SB@maxmin\SB@dimen>\SB@dimenii%
+ \loop%
+ \global\setbox\SB@box\copy\SB@boxii%
+ \global\setbox\SB@boxiii\hbox{\SB@oneidxpage}%
+ \ifdim\ht\SB@box>\z@%
+ \advance\SB@dimen\p@%
+ \repeat%
+ \box\SB@boxiii%
+ \global\setbox\SB@boxii\box\voidb@x%
+ \vbadness\SB@cnt\vfuzz\SB@dimenii%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\showindex}\MainImpl{showindex}
+% \changes{v2.8}{2009/03/06}{Added optional argument}
+% Create an index with title \argp{2} based on the data associated with index
+% identifier \argp{3} (which was passed to |\newindex|).
+% Optional argument \argp{1} specifies the number of columns.
+% This macro calls the appropriate index-creation macro depending on the type
+% of index that \argp{3} was declared to be.
+% \begin{macrocode}
+\newcommand\showindex[3][0]{%
+ \@ifundefined{SB@idxsel@#3}{\SB@errnoidx{#3}}{%
+ \expandafter\let\expandafter\SB@temp\csname SB@idxsel@#3\endcsname%
+ \SB@cnt#1\relax%
+ \ifnum\SB@cnt<\@ne\SB@cnt\SB@temp232\relax\fi%
+ \expandafter\SB@temp%
+ \expandafter\SB@maketitleindex%
+ \expandafter\SB@makescripindex%
+ \expandafter\SB@makeauthorindex%
+ \expandafter{\the\SB@cnt}%
+ {#2}{#3}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@maketitleindex}
+% \changes{v2.8}{2009/03/06}{Added columns argument}
+% Create a song title index.
+% \argp{1} is a column count,
+% \argp{2} is the title, and
+% \argp{3} is the index identifier (which was passed to |\newindex|).
+% \begin{macrocode}
+\newcommand\SB@maketitleindex{%
+ \ifnum\idxheadwidth>\z@%
+ \renewenvironment{SB@lgidx}[1]{
+ \hbox{\SB@colorbox\idxbgcolor{\vbox{%
+ \hbox to\idxheadwidth{{\idxheadfont\relax##1}\hfil}%
+ }}}%
+ \nobreak\vskip3\p@\@plus2\p@\@minus2\p@\nointerlineskip%
+ }{\penalty-50\vskip5\p@\@plus5\p@\@minus4\p@}%
+ \else%
+ \renewenvironment{SB@lgidx}[1]{}{}%
+ \fi%
+ \renewenvironment{SB@smidx}[1]{}{}%
+ \renewcommand\idxentry[2]{%
+ \SB@ellipspread{\idxtitlefont\relax\ignorespaces##1\unskip}%
+ {{\idxrefsfont\relax##2}}%
+ }%
+ \renewcommand\idxaltentry[2]{%
+ \SB@ellipspread{\idxlyricfont\relax\ignorespaces##1\unskip}%
+ {{\idxrefsfont\relax##2}}%
+ }%
+ \SB@displayindex%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@idxcolhead}
+% In a scripture index, this macro remembers the current book of the bible
+% we're in so that new columns can be headed with ``Bookname (continued)''.
+% \begin{macrocode}
+\newcommand\SB@idxcolhead{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@idxheadsep}
+% Add vertical space following the header line that begins (or continues) a
+% section of a scripture index.
+% \begin{macrocode}
+\newcommand\SB@idxheadsep{{%
+ \SB@dimen4\p@%
+ \advance\SB@dimen-\prevdepth%
+ \SB@maxmin\SB@dimen<\z@%
+ \SB@dimenii\SB@dimen%
+ \SB@maxmin\SB@dimenii>\p@%
+ \vskip\SB@dimen\@plus\p@\@minus\SB@dimenii%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@idxcont}
+% Typeset the ``Bookname (continued)'' line that continues a scripture
+% index section when it spans a column break.
+% \begin{macrocode}
+\newcommand\SB@idxcont[1]{%
+ \hbox to\hsize{{\idxcont{#1}}\hfil}%
+ \nobreak%
+ \SB@idxheadsep\nointerlineskip%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@makescripindex}
+% \changes{v2.4}{2007/10/08}{Scripture index spacing made more uniform}
+% \changes{v2.8}{2009/03/06}{Added columns argument}
+% Create a scripture index.
+% \argp{1} is a column count,
+% \argp{1} is the title, and
+% \argp{2} is the index identifier (which was passed to |\newscripindex|).
+% \begin{macrocode}
+\newcommand\SB@makescripindex{%
+ \renewenvironment{SB@lgidx}[1]{%
+ \gdef\SB@idxcolhead{##1}%
+ \hbox to\hsize{{\idxbook{##1}}\hfil}%
+ \nobreak%
+ \SB@idxheadsep\nointerlineskip%
+ }{%
+ \mark{\noexpand\relax}%
+ \penalty-20\vskip3\p@\@plus3\p@\relax%
+ }%
+ \renewenvironment{SB@smidx}[1]
+ {\begin{SB@lgidx}{##1}}{\end{SB@lgidx}}%
+ \renewcommand\idxentry[2]{%
+ \SB@ellipspread{\hskip.25cm\idxscripfont\relax##1}%
+ {{\idxrefsfont\relax##2}}%
+ \SB@toks\expandafter{\SB@idxcolhead}%
+ \mark{\noexpand\SB@idxcont{\the\SB@toks}}%
+ }%
+ \renewcommand\idxaltentry[2]{\SB@erridx{a scripture}}%
+ \SB@displayindex%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@makeauthorindex}
+% \changes{v2.8}{2009/03/06}{Added columns argument}
+% Create an author index.
+% \argp{1} is a column count,
+% \argp{2} is the title, and
+% \argp{2} is the index identifier (which was passed to |\newauthindex|).
+% \begin{macrocode}
+\newcommand\SB@makeauthorindex{%
+ \renewenvironment{SB@lgidx}[1]{}{}%
+ \renewenvironment{SB@smidx}[1]{}{}%
+ \renewcommand\idxentry[2]{%
+ \SB@ellipspread{{\idxauthfont\relax\sfcode`.\@m##1}}%
+ {{\idxrefsfont##2}}%
+ }%
+ \renewcommand\idxaltentry[2]{\SB@erridx{an author}}%
+ \SB@displayindex%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Error Messages}
+%
+% We break error messages out into separate macros here in order to reduce the
+% length (in tokens) of the more frequently used macros that do actual work.
+% This can result in a small speed improvement on slower machines.
+%
+% \begin{macro}{\SB@Error}
+% \begin{macro}{\SB@Warn}
+% All errors and warnings will be reported as coming from package ``songs''.
+% \begin{macrocode}
+\newcommand\SB@Error{\PackageError{songs}}
+\newcommand\SB@Warn{\PackageWarning{songs}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SB@errspos}
+% \begin{macrocode}
+\newcommand\SB@errspos{%
+ \SB@Error{Illegal \protect\songpos\space argument}{The argume%
+ nt to \protect\songpos\space must be a number from 0 to 3.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errnse}
+% \begin{macrocode}
+\newcommand\SB@errnse{%
+ \SB@Error{Nested songs environments are not supported}{End th%
+ e previous songs environment before beginning the next one.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errpl}
+% \begin{macrocode}
+\newcommand\SB@errpl{%
+ \SB@Error{\protect\includeonlysongs\space not permitted with%
+ in a songs environment}{\protect\includeonlysongs\space can o%
+ nly be used in the document preamble or between songs environ%
+ ments in the document body.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errrtopt}
+% \begin{macrocode}
+\newcommand\SB@errrtopt{%
+ \SB@Error{Cannot display chords in a rawtext dump}{You have u%
+ sed the rawtext option in the \protect\usepackage\space lin%
+ e and have either used the chorded option as well or have use%
+ d the \protect\chordson\space macro subsequently.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@warnrc}
+% \begin{macrocode}
+\newcommand\SB@warnrc{%
+ \SB@Warn{The \protect\repchoruses\space feature will not wor%
+ k when the number of columns is set to zero}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@warnnoidx}
+% \begin{macrocode}
+\newcommand\SB@warnnoidx{%
+ \SB@Warn{Index command has no effect since no indexes are ye%
+ t declared}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errboo}
+% \begin{macrocode}
+\newcommand\SB@errboo{%
+ \SB@Error{Encountered \protect\beginsong\space without seein%
+ g an \protect\endsong\space for the previous song}%
+ {Song \thesongnum\space might be missing a%
+ n \protect\endsong\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbor}
+% \begin{macrocode}
+\newcommand\SB@errbor{%
+ \SB@Error{Encountered \protect\beginsong\space without seein%
+ g an \protect\endscripture\space for the preceding scriptur%
+ e quotation}{A scripture quotation appearing after son%
+ g \thesongnum\space might be missing a%
+ n \protect\endscripture\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@erreov}
+% \begin{macrocode}
+\newcommand\SB@erreov{%
+ \SB@Error{Encountered \protect\endsong\space without seein%
+ g an \protect\endverse\space for the preceding verse}{Son%
+ g \thesongnum\space has a \protect\beginverse\space%
+ line with no matching \protect\endverse\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@erreoc}
+% \begin{macrocode}
+\newcommand\SB@erreoc{%
+ \SB@Error{Encountered \protect\endsong\space without seein%
+ g an \protect\endchorus\space for the preceding chorus}{Son%
+ g \thesongnum\space has a \protect\beginchorus\space%
+ line with no matching \protect\endchorus\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@erreor}
+% \begin{macrocode}
+\newcommand\SB@erreor{%
+ \SB@Error{Encountered \protect\endsong\space without seein%
+ g an \protect\endscripture for the preceding scripture quot%
+ e}{A scripture quote appearing before song \thesongnum\space%
+ ended with \protect\endsong\space instead of wit%
+ h \protect\endscripture.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@erreot}
+% \begin{macrocode}
+\newcommand\SB@erreot{%
+ \SB@Error{Encountered \protect\endsong\space with no matchin%
+ g \protect\beginsong}{Before song \thesongnum\space there wa%
+ s an \protect\endsong\space with no matchin%
+ g \protect\beginsong.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbvv}
+% \begin{macrocode}
+\newcommand\SB@errbvv{%
+ \SB@Error{Encountered \protect\beginverse\space without seein%
+ g an \protect\endverse\space for the preceding verse}{Son%
+ g \thesongnum\space might have a verse that has n%
+ o \protect\endendverse\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbvc}
+% \begin{macrocode}
+\newcommand\SB@errbvc{%
+ \SB@Error{Encountered \protect\beginverse\space without seein%
+ g an \protect\endchorus\space for the preceding chorus}{Son%
+ g \thesongnum\space might have a chorus that has n%
+ o \protect\endchorus\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbvt}
+% \begin{macrocode}
+\newcommand\SB@errbvt{%
+ \SB@Error{Encountered \protect\beginverse\space without firs%
+ t seeing a \protect\beginsong\space line}{Before son%
+ g \thesongnum, there is a \protect\beginverse\space line no%
+ t contained in any song.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errevc}
+% \begin{macrocode}
+\newcommand\SB@errevc{%
+ \SB@Error{Encountered \protect\endverse\space while process%
+ ing a chorus}{Song \thesongnum\space might hav%
+ e a \protect\beginchorus\space concluded by a%
+ n \protect\endverse\space instead of an \protect\endchorus.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errevo}
+% \begin{macrocode}
+\newcommand\SB@errevo{%
+ \SB@Error{Encountered \protect\endverse\space without firs%
+ t seeing a \protect\beginverse}{Song \thesongnum\space m%
+ ight have an \protect\endverse\space with no matchin%
+ g \protect\beginverse.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errevt}
+% \begin{macrocode}
+\newcommand\SB@errevt{%
+ \SB@Error{Encountered an \protect\endverse\space outside o%
+ f any song}{Before song \thesongnum, there is a%
+ n \protect\endverse\space line not preceded b%
+ y a \protect\beginsong\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@erretex}
+% \begin{macrocode}
+\newcommand\SB@erretex{%
+ \SB@Error{The \protect\repchoruses\space feature requires e-%
+ TeX compatibility}{Your version of LaTeX2e does not appear t%
+ o be e-TeX compatible. Find a distribution that includes e-T%
+ eX support in order to use this feature.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbcv}
+% \begin{macrocode}
+\newcommand\SB@errbcv{%
+ \SB@Error{Encountered \protect\beginchorus\space without see%
+ ing an \protect\endverse\space for the preceding verse}{Son%
+ g \thesongnum\space might hav%
+ e a \protect\beginverse\space with no match%
+ ing \protect\endverse.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbcc}
+% \begin{macrocode}
+\newcommand\SB@errbcc{%
+ \SB@Error{Encountered \protect\beginchorus\space without see%
+ ing an \protect\endchorus\space for the preceding chorus}%
+ {Song \thesongnum\space might have a \protect\beginchorus%
+ \space with no matching \protect\endchorus.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbct}
+% \begin{macrocode}
+\newcommand\SB@errbct{%
+ \SB@Error{Encountered \protect\beginchorus\space without see%
+ ing a \protect\beginsong\space line first}{After son%
+ g \thesongnum\space there is a \protect\beginchorus\space%
+ line outside of any song.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errecv}
+% \begin{macrocode}
+\newcommand\SB@errecv{%
+ \SB@Error{Encountered an \protect\endchorus\space while proc%
+ essing a verse}{Song \thesongnum\space might hav%
+ e a \protect\beginverse\space concluded by \protect\endchorus%
+ \space instead of \protect\endverse.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@erreco}
+% \begin{macrocode}
+\newcommand\SB@erreco{%
+ \SB@Error{Encountered \protect\endchorus\space without firs%
+ t seeing a \protect\beginchorus}{Song \thesongnum\space m%
+ ight have an \protect\endchorus\space with no match%
+ ing \protect\beginchorus.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errect}
+% \begin{macrocode}
+\newcommand\SB@errect{%
+ \SB@Error{Encountered an \protect\endchorus\space outside o%
+ f any song}{Before song \thesongnum, there is a%
+ n \protect\endchorus\space line not preceded b%
+ y a \protect\beginsong\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbro}
+% \begin{macrocode}
+\newcommand\SB@errbro{%
+ \SB@Error{Missing \protect\endsong}%
+ {Nested song and intersong environments are not supported%
+ . Song \thesongnum\space might be missing a%
+ n \protect\endsong\space line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errbrr}
+% \begin{macrocode}
+\newcommand\SB@errbrr{%
+ \SB@Error{Nested intersong environments are not supported}%
+ {A scripture quote or other intersong environment before s%
+ ong \thesongnum\space is missing its ending line.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errero}
+% \begin{macrocode}
+\newcommand\SB@errero{%
+ \SB@Error{Encountered an \protect\endscripture\space whil%
+ e processing a song}{Song \thesongnum\space ends wit%
+ h \protect\endscripture\space when it should end wit%
+ h \protect\endsong.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errert}
+% \begin{macrocode}
+\newcommand\SB@errert{%
+ \SB@Error{Encountered an \protect\endscripture\space with%
+ out first seeing a \protect\beginscripture}{Before son%
+ g \thesongnum, there is an \protect\endscripture\space w%
+ ith no matching \protect\beginscripture.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errscrip}
+% \begin{macrocode}
+\newcommand\SB@errscrip[1]{%
+ \SB@Error{Encountered a \protect#1\space outside a scriptu%
+ re quote}{\protect#1\space can only appear betwee%
+ n \protect\beginscripture\space an%
+ d \protect\endscripture\space lines.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errchord}
+% \begin{macrocode}
+\newcommand\SB@errchord{%
+ \SB@Error{Song \thesongnum\space seems to have chord%
+ s that appear outside of any verse or chorus}{All chords a%
+ nd lyrics should appear between \protect\beginverse\space%
+ and \protect\endverse, or between \protect\beginchorus\space%
+ and \protect\endchorus.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errreplay}
+% \begin{macrocode}
+\newcommand\SB@errreplay{%
+ \SB@Error{Replayed chord has no matching chord}{Son%
+ g \thesongnum\space uses \protect^ more times than the%
+ re are chords in the previously memorized verse.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errreg}
+% \begin{macrocode}
+\newcommand\SB@errreg[1]{%
+ \SB@Error{Unknown chord-replay register name: #1}{Chord-re%
+ play registers must be declared with \protect\newchords.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errdup}
+% \begin{macrocode}
+\newcommand\SB@errdup[1]{%
+ \SB@Error{Duplicate definition of chord-replay register%
+ : #1}{\protect\newchords\space was used to declare the sa%
+ me chord-replay register twice.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errmbar}
+% \begin{macrocode}
+\newcommand\SB@errmbar{%
+ \SB@Error{Song \thesongnum\space seems to have measur%
+ e bars that appear outside of any verse or chorus}{All mea%
+ sure bars (produced with \protect\mbar\space or |) must ap%
+ pear between \protect\beginverse\space an%
+ d \protect\endverse, or between \protect\beginchorus\space%
+ and \protect\endchorus.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errebar}
+% \begin{macrocode}
+\newcommand\SB@errebar[2]{%
+ \SB@Error{Ignoring unbalanced \expandafter\@gobble\string#2 i%
+ n \protect\gtab}{Found no \expandafter\@gobble\string#1 to ma%
+ tch the \expandafter\@gobble\string#2.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@errnoidx}
+% \begin{macrocode}
+\newcommand\SB@errnoidx[1]{%
+ \SB@Error{Unknown index identifier: #1}{This index identifie%
+ r was never declared using \protect\newindex.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SB@erridx}
+% \begin{macrocode}
+\newcommand\SB@erridx[1]{%
+ \SB@Error{\protect\idxaltentry\space not allowed in #1 index}%
+ {This error should not occur. The index generation routines ha%
+ ve malfunctioned. Try deleting all temporary files and then re%
+ compiling.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Option Processing}\label{sec:optproc}
+%
+% \begin{macro}{\ifchorded}
+% \begin{macro}{\iflyric}
+% \begin{macro}{\ifslides}
+% \begin{macro}{\ifmeasures}
+% \begin{macro}{\ifpartiallist}
+% \begin{macro}{\ifrepchorus}
+% \begin{macro}{\iftranscapos}
+% \begin{macro}{\ifnolyrics}
+% \begin{macro}{\ifrawtext}
+% \begin{macro}{\ifsongindexes}
+% \begin{macro}{\ifsepindexes}
+% \begin{macro}{\ifpagepreludes}
+% \begin{macro}{\ifSB@colorboxes}
+% \begin{macro}{\ifSB@omitscrip}
+% Reserve conditionals for all of the various option settings.
+% We wait to define these since if any are used earlier than this, it is
+% an error in the package code, and we'd rather get an error than continue.
+% \begin{macrocode}
+\newif\ifchorded
+\newif\iflyric\lyrictrue
+\newif\ifslides
+\newif\ifmeasures
+\newif\ifpartiallist
+\newif\ifrepchorus
+\newif\iftranscapos
+\newif\ifnolyrics
+\newif\ifrawtext
+\newif\ifsongindexes\songindexestrue
+\newif\ifsepindexes\sepindexestrue
+\newif\ifpagepreludes
+\newif\ifSB@colorboxes
+\IfFileExists{color.sty}\SB@colorboxestrue\SB@colorboxesfalse
+\newif\ifSB@omitscrip
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\nolyrics}
+% \begin{macro}{\pagepreludes}
+% The |\nolyrics| and |\pagepreludes| macros are just shorthand for
+% |\nolyricstrue| and |\pagepreludestrue|, respectively.
+% \begin{macrocode}
+\newcommand\nolyrics{}
+\let\nolyrics\nolyricstrue
+\newcommand\pagepreludes{\pagepreludestrue\songpos0}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Finally we're ready to process all of the package options.
+% This is delayed until near the end because the option processing code
+% needs to execute various macros found in the previous sections.
+% \begin{macrocode}
+\SB@chordson
+\ProcessOptions\relax
+% \end{macrocode}
+%
+% \begin{macro}{\SB@colorbox}
+% Include the colors package and define colors, if requested.
+% \begin{macrocode}
+\ifSB@colorboxes
+ \RequirePackage{color}
+ \definecolor{SongbookShade}{gray}{.80}
+ \newcommand\SB@colorbox[2]{%
+ \ifx\@empty#1%
+ \vbox{%
+ \kern3\p@%
+ \hbox{\kern3\p@{#2}\kern3\p@}%
+ \kern3\p@%
+ }%
+ \else%
+ \colorbox{#1}{#2}%
+ \fi%
+ }
+\else
+ \newcommand\SB@colorbox[2]{\vbox{%
+ \kern3\p@%
+ \hbox{\kern3\p@{#2}\kern3\p@}%
+ \kern3\p@%
+ }}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Rawtext Mode}
+%
+% If generating raw text, most of what has been defined previously is ignored
+% in favor of some very specialized macros that write all the song lyrics to
+% a text file.
+% \begin{macrocode}
+\ifrawtext
+ \SB@newwrite\SB@txtout
+ \immediate\openout\SB@txtout=\jobname.txt
+ \newif\ifSB@doEOL
+ {\catcode`\^^M12 %
+ \catcode`\^^J12 %
+ \gdef\SB@printEOL{\ifSB@doEOL^^M^^J\fi}}
+ {\catcode`#12\gdef\SB@hash{#}}
+ {\catcode`&12\gdef\SB@amp{&}}
+ \renewcommand\SB@@@beginsong{%
+ \begingroup%
+ \def\'{}\def\`{}\def\v{}\def\u{}\def\={}\def\^{}%
+ \def\.{}\def\H{}\def\~{}\def\"{}\def\t{}%
+ \def\copyright{(c)}%
+ \let~\space%
+ \let\par\SB@printEOL%
+ \let\#\SB@hash%
+ \let\&\SB@amp%
+ \catcode`|9 %
+ \catcode`*9 %
+ \catcode`^9 %
+ \def\[##1]{}%
+ \resettitles%
+ \immediate\write\SB@txtout{\thesongnum. \songtitle}%
+ \nexttitle%
+ \foreachtitle{\immediate\write\SB@txtout{(\songtitle)}}%
+ \ifx\songauthors\@empty\else%
+ \immediate\write\SB@txtout{\songauthors}%
+ \fi%
+ \ifx\SB@rawrefs\@empty\else%
+ \immediate\write\SB@txtout{\SB@rawrefs}%
+ \fi%
+ \immediate\write\SB@txtout{}%
+ \SB@doEOLfalse%
+ \obeylines%
+ }
+ \renewcommand\SB@endsong{%
+ \SB@doEOLtrue%
+ \immediate\write\SB@txtout{\songcopyright\space%
+ \songlicense\SB@printEOL}%
+ \endgroup%
+ \SB@insongfalse%
+ \stepcounter{songnum}%
+ }
+ \def\SB@parsesrefs#1{\def\songrefs{#1}}
+ \long\def\beginverse#1#2\endverse{%
+ \SB@doEOLtrue\begingroup%
+ \def\textnote##1{##1}%
+ \def\SB@temp{#1}%
+ \def\SB@star{*}%
+ \ifx\SB@temp\SB@star%
+ \immediate\write\SB@txtout{\@gobble#2}%
+ \else%
+ \immediate\write\SB@txtout{#2}%
+ \fi%
+ \endgroup\SB@doEOLfalse}
+ \long\def\beginchorus#1\endchorus{%
+ \SB@doEOLtrue\begingroup%
+ \def\textnote##1{##1}%
+ \immediate\write\SB@txtout{Chorus:#1}%
+ \endgroup\SB@doEOLfalse}
+ \long\def\beginscripture#1\endscripture{}
+ \def\musicnote#1{}
+ \def\textnote#1{%
+ \SB@doEOLtrue%
+ \immediate\write\SB@txtout{#1\SB@printEOL}%
+ \SB@doEOLfalse}
+ \def\brk{}
+ \def\rep#1{(x#1)}
+ \def\echo#1{(#1)}
+ \def\mbar#1#2{}
+ \def\lrep{}
+ \def\rrep{}
+ \def\nolyrics{}
+ \renewcommand\memorize[1][]{}
+ \renewcommand\replay[1][]{}
+\fi
+% \end{macrocode}
+%
+% \Finale
+\endinput
+