Files
songbook/songbook-style.sty
shahondin1624 ab00b710b1 Fix rowcolors bleeding into chord tabulars
Reset \rowcolors after the TOC longtable to prevent alternating
gray backgrounds from affecting leadsheets' chord placement
tabulars, which was clipping/overlaying song lyrics.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:03:27 +02:00

244 lines
6.7 KiB
TeX

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{songbook-style}[2026/04/01 Pfadfinder Liederbuch Style]
% --- Core packages ---
\RequirePackage{fontspec}
\RequirePackage[ngerman]{babel}
\RequirePackage[
a5paper,
top=15mm,
bottom=20mm,
inner=20mm,
outer=12mm
]{geometry}
\RequirePackage[hidelinks]{hyperref}
\RequirePackage{fancyhdr}
\RequirePackage{xcolor}
\RequirePackage{longtable}
\RequirePackage{array}
\RequirePackage{colortbl}
\RequirePackage{rotating}
\RequirePackage{graphicx}
\RequirePackage{csquotes}
\RequirePackage[minimal]{leadsheets}
\ExplSyntaxOn
\cs_new:cpn {leadsheets-library-musicsymbols-loaded} {}
\ExplSyntaxOff
\useleadsheetslibraries{chordnames,chords,shorthands,properties,templates,translations,songs}
% --- Font setup ---
\setmainfont{TeX Gyre Heros}
\newfontfamily\frakfont{UnifrakturMaguntia-Book}[Path=fonts/,Extension=.ttf]
% --- Colors ---
\definecolor{tocrowgray}{gray}{0.92}
\definecolor{tocheadgray}{gray}{0.75}
% --- Page style ---
\pagestyle{fancy}
\fancyhf{}
\fancyfoot[LE]{\large\bfseries\thepage}
\fancyfoot[RO]{\large\bfseries\thepage}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
% --- Custom song properties ---
\definesongproperty{alias}
\definesongproperty{note}
\definesongproperty{mundorgel}
\definesongproperty{pfadfinderliederbuch}
% --- leadsheets settings ---
\setleadsheets{
title-template = songbook,
verse/numbered = false,
verse/named = false,
chorus/named = false,
chorus/numbered = false,
after-song = \songendsection,
}
\setchords{
format = \small,
}
% ==========================================================================
% Song TOC matrix
% ==========================================================================
\newcounter{songnumber}
\newcounter{tocrowcount}
\ExplSyntaxOn
\iow_new:N \g__sb_toc_iow
\tl_new:N \l__sb_title_tl
\tl_new:N \l__sb_mo_tl
\tl_new:N \l__sb_pflb_tl
\tl_new:N \l__sb_num_tl
\tl_new:N \l__sb_songid_tl
\bool_new:N \g__sb_toc_opened_bool
\seq_new:N \g__sb_written_seq
% Lazy-open: only truncate the file when first song writes to it
% This ensures the TOC reads the PREVIOUS run's data before truncation
\cs_new_protected:Npn \__sb_ensure_toc_open:
{
\bool_if:NF \g__sb_toc_opened_bool
{
\iow_open:Nn \g__sb_toc_iow { \c_sys_jobname_str .songtoc }
\bool_gset_true:N \g__sb_toc_opened_bool
}
}
\AtEndDocument{
\bool_if:NT \g__sb_toc_opened_bool
{ \iow_close:N \g__sb_toc_iow }
}
\cs_new_protected:Npn \writesongtoc
{
% Use leadsheets song ID to skip duplicate calls (measurement pass)
\tl_set:NV \l__sb_songid_tl \l_leadsheets_current_song_id_tl
\seq_if_in:NVF \g__sb_written_seq \l__sb_songid_tl
{
\seq_gput_right:NV \g__sb_written_seq \l__sb_songid_tl
\__sb_ensure_toc_open:
\stepcounter{songnumber}
\tl_set:Nx \l__sb_num_tl { \int_use:N \c@songnumber }
\tl_set:Nx \l__sb_title_tl { \songproperty{title} }
\tl_set:Nx \l__sb_mo_tl { \songproperty{mundorgel} }
\tl_set:Nx \l__sb_pflb_tl { \songproperty{pfadfinderliederbuch} }
\iow_now:Nx \g__sb_toc_iow
{
\exp_not:N \songtocrow
{ \l__sb_title_tl }
{ \l__sb_mo_tl }
{ \l__sb_pflb_tl }
{ \exp_not:N \pageref { song: \l__sb_num_tl } }
}
}
% Label MUST be outside guard: measurement pass label is discarded (inside vbox),
% but the real pass label survives and gets written to .aux
\tl_set:Nx \l__sb_num_tl { \int_use:N \c@songnumber }
\label{song:\tl_use:N \l__sb_num_tl}
}
\ExplSyntaxOff
% --- Render one TOC row ---
\newcommand{\songtocrow}[4]{%
#1 & #2 & #3 & \cellcolor{tocheadgray}\textbf{#4} \\
\hline
}
% --- Rotated column header ---
\newcommand{\rotheader}[1]{%
\begin{turn}{70}\footnotesize\textbf{#1}\end{turn}%
}
% --- Print the song TOC table ---
\newcommand{\printsongtoc}{%
\thispagestyle{fancy}%
{\Large\bfseries Inhaltsverzeichnis\par}%
\vspace{5mm}%
\footnotesize
\rowcolors{2}{tocrowgray}{white}%
\begin{longtable}{%
>{\raggedright\arraybackslash}p{0.52\textwidth}|%
>{\centering\arraybackslash}p{0.10\textwidth}|%
>{\centering\arraybackslash}p{0.10\textwidth}|%
>{\centering\arraybackslash\columncolor{tocheadgray}}p{0.12\textwidth}%
}
& \rotheader{MO} & \rotheader{PfLB}
& \rotheader{\normalsize Lieder-\newline\normalsize buch} \\
\hline
\endfirsthead
& \rotheader{MO} & \rotheader{PfLB}
& \rotheader{\normalsize Lieder-\newline\normalsize buch} \\
\hline
\endhead
\InputIfFileExists{\jobname.songtoc}{}{}%
\end{longtable}%
\rowcolors{1}{}{}%
}
% ==========================================================================
% Song end section
% ==========================================================================
\newcommand{\songendsection}{%
\vfill
\ifsongproperty{note}{%
{\footnotesize\songproperty{note}\par\smallskip}%
}{}%
\begingroup\footnotesize
\ifsongproperty{lyrics}{%
\ifsongproperty{composer}{%
Worte: \songproperty{lyrics}\par
Weise: \songproperty{composer}\par
}{%
Worte und Weise: \songproperty{lyrics}\par
}%
}{%
\ifsongproperty{composer}{%
Weise: \songproperty{composer}\par
}{}%
}%
\endgroup
\vspace{3mm}%
\begingroup\footnotesize\centering
\begin{tabular}{ccc}
MO & PfLB & Liederbuch \\
\ifsongproperty{mundorgel}{\songproperty{mundorgel}}{} &
\ifsongproperty{pfadfinderliederbuch}{\songproperty{pfadfinderliederbuch}}{} &
\thepage
\end{tabular}\par
\endgroup
\newpage
}
% ==========================================================================
% Song title template
% ==========================================================================
\definesongtitletemplate{songbook}{%
{\LARGE\frakfont\songproperty{title}\par}%
\writesongtoc
\vspace{4mm}%
}
% ==========================================================================
% Image placement
% ==========================================================================
% Full-page filler image (centered, scaled to fit, own page)
% Usage: \fillerpage{images/drawing.png}
\newcommand{\fillerpage}[1]{%
\clearpage
\thispagestyle{empty}%
\vspace*{\fill}%
\begin{center}%
\includegraphics[width=0.85\textwidth,height=0.85\textheight,keepaspectratio]{#1}%
\end{center}%
\vspace*{\fill}%
\clearpage
}
% Inline image within a page (e.g., at end of a song with remaining space)
% Usage: \songimage{images/landscape.png}
\newcommand{\songimage}[1]{%
\begin{center}%
\includegraphics[width=0.8\textwidth,keepaspectratio]{#1}%
\end{center}%
}
% Full-page image with no margins (bleeds to edges)
% Usage: \fullpageimage{images/cover.png}
\newcommand{\fullpageimage}[1]{%
\clearpage
\thispagestyle{empty}%
\newgeometry{margin=0pt}%
\noindent\includegraphics[width=\paperwidth,height=\paperheight]{#1}%
\restoregeometry
\clearpage
}