% Copied from ifnextok.sty.
% We use \providecommand instead of \newcommand and \def in order
% to avoid overriding ifnextok if it is already loaded.
\providecommand{\IfNextToken}[3]{%
\let\nextok@match= #1%
\def\nextok@if{#2}\def\nextok@else{#3}%
\futurelet\@let@token\nextok@decide%
}
\providecommand\nextok@decide{%
\ifx\@let@token\nextok@match
\expandafter\nextok@if
\else
\expandafter\nextok@else
\fi%
}
% How the filename of a score will look like (if printed)
\newcommand{\lyFilename}[1]{\noindent #1\par\bigskip}
% Appearance of verbatim 'intertext' (if printed)
\newcommand{\lyIntertext}[1]{\noindent #1\par\bigskip}
% Appearance of LilyPond version (if printed)
\newcommand{\lyVersion}[1]{\noindent {\footnotesize\emph{(GNU LilyPond #1)}\par}\bigskip}
% Retrieve the three main font families (rm, sf, tt)
% and store them as options. Additionally store the
% *current* font for optional use.
\newcommand{\ly@currentfonts}{%
\begingroup%
\setluaoption{ly}{current-font}{%
\directlua{ly.get_font_family(font.current())}
}
\rmfamily \edef\rmfamilyid{\fontid\font}%
\sffamily \edef\sffamilyid{\fontid\font}%
\ttfamily \edef\ttfamilyid{\fontid\font}%
% Set font families to those of the document
% that haven't been set explicitly as options.
\directlua{ly.set_fonts(\rmfamilyid, \sffamilyid, \ttfamilyid)}%
\endgroup%
}
% Inclusion of a .ly file
\newcommand*\includely[2][]{%
\directlua{ly.state = 'file'}%
\ly@compilescore{ly.file(
'\luatexluaescapestring{#2}', [[#1]]
)}%
}
% Inclusion of a musicxml file
\newcommand*\musicxmlfile[2][]{%
\directlua{ly.state = 'file'}%
\ly@compilescore{ly.file_musicxml(
'\luatexluaescapestring{#2}', [[#1]]
)}
}
% Base environments to include a LilyPond fragment integrated into
% the document.
\newcommand\lyscorebegin{\directlua{ly.buffenv_begin()}}
\newcommand\lyscoreend{\directlua{ly.buffenv_end()}}
\newenvironment{ly@bufferenv}{%
\directlua{
ly.insert_inline = string.match([[\options]], 'insert.*inline')
if ly.insert_inline then
if ly.varwidth_available then
tex.print([[
\string\begin{varwidth}{\string\linewidth}
]])
else
ly.insert_inline = false
ly.err(
[[You have required 'insert=inline' with lilypond environment,
but package 'varwidth' wasn't found; either install it, or disable
this option.]]
)
end
end
}
\lyscorebegin%
}{%
\lyscoreend%
\ly@compilescore{ly.fragment(ly.score_content, [[\options]])}%
\hspace{0pt}\\
\directlua{
if ly.insert_inline then tex.print([[\string\end{varwidth}]]) end
}%
}
% Commands to print verbatim content of the score
\newcommand\lysetverbenv[2]{%
\directlua{ly.verbenv = {
'\luatexluaescapestring{\detokenize{#1}}',
'\luatexluaescapestring{\detokenize{#2}}'
}}%
}
% Environments to record custom headers and footers to be included in fragments
\newenvironment{lysavefrag}[1]{%
\edef\filename{#1}
\lyscorebegin%
}{%
\lyscoreend%
\directlua{ly.write_to_file('\filename'..'.ly', table.concat(ly.score_content,'\string\n'))}%
}
% Commands to transform or define lilypond environments so that it isn't necessary to add empty [].
\def\lyenv#1{%
\expandafter\let\csname ly@env@#1\expandafter\endcsname\csname #1\endcsname%
\expandafter\let\csname ly@env@end#1\expandafter\endcsname\csname end#1\endcsname%
\expandafter\def\csname #1\endcsname{\IfNextToken[{\csname ly@env@#1\endcsname}{\csname ly@env@#1\endcsname[]}}%
}
\long\def\lynewenvironment#1{\@ifnextchar[{\ly@newenv@a{#1}}{\ly@newenv@a{#1}[0]}}
\long\def\ly@newenv@a#1[#2]{\@ifnextchar[{\ly@newenv@b{#1}{#2}}{\ly@newenv@b{#1}{#2}[]}}
\long\def\ly@newenv@b#1#2[#3]#4#5{%
\newenvironment{#1}[#2][#3]{#4}{#5}
\lyenv{#1}
}
% Parametrized command and environment for included LilyPond fragment
\lynewenvironment{ly}[1][noarg]{%
\edef\options{#1}%
\directlua{ly.state = 'env'}%
\ly@bufferenv%
}{%
\endly@bufferenv%
}