LaTeX for music

I explained this implementation in more detail in my blog: http://tobiw.de/tbdm/funktionssymbole (in German only)

Usage:

\function{<Function>}[<Bass Notes>][<Length>]{<Notes>}
  • <Funtion> = T, D, S, Sp, s, …
    The command allows also some special function symbols:
    • DD for double dominant (maybe the wrong english terms, sorry for that, I know only the german ones …)
    • /D for dominant without root
    • SS for double sub-dominant
  • <Length> = Length for space between and
  • <Notes> = comma separated list of changes in notes (from lower two higher voices). Note that the order is reversed compared to my fist implementation.
  • <Bass Notes> = changes in bass/lowest voice
  • In all note definitions:
    • - gets replaced by a dash
    • . gets replaced by a space
    • Numbers greater than 9 must be set in braces, e.g. {11} instead of 11

All notes/spaces/lines get the same with to make them align vertically.

The bass voice is always align at the same vertical position (kind of subscript). The first change in the list for the higher voices has a fixed vertical position too (kind of superscript) an all following changes get stacked above.

If you use another font (size) you must adjust all the ex and em values.

Results:

more or less complex voicings:

\function{T}{..7-8,3---4} \enskip
\function{D}{4---3, 6-5, ..7-8} \enskip
\function{D}{4----3, 6-5---, ..7-8-,{11}-----} \enskip
\function{s}{5,6}

complex voicings

special functions:

\function{DD}{8-7} \enskip \function{/D}{8-7} \enskip \function{SS}{5,6}

special functions

manually adjusted spacing between function symbol and note changes:

\function{D}[]{8-7} \enskip \function{D}[4-3]{} \enskip \function{D}[4-3]{8-7}
\par vs. \par
\function{D}[][-1pt]{8-7} \enskip \function{D}[4-3][-2.3pt]{} \enskip \function{D}[4-3][-1pt]{8-7} 

adjusted spacing

with guides to show the base line etc.:

\showAllLines\mbox{}\enskip
% single change in upper voice
\function{D}{8-7} \enskip
% single chane in bass voice
\function{D}[8-7]{} \enskip
% change in upper and bass voice
\function{D}[8-7]{4-3} \enskip
% multiple changes
\function{D}[8--7]{4-3,6-5}

result

Full Code:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

% width of the boxes containing the note numbers
\dim_new:N \l_palamas_boxwidth_dim
\dim_set:Nn \l_palamas_boxwidth_dim { 0.5em }

% token for the line betwwen two numbers
\tl_new:N \g_palamas_line_tl
\tl_set:Nn \g_palamas_line_tl { \rule [ 0.7ex ] { \l_palamas_boxwidth_dim } { 0.3pt } }

% token for a space between two numbers / befor a number
\tl_new:N \g_palamas_space_tl
\tl_set:Nn \g_palamas_space_tl { \hspace { \l_palamas_boxwidth_dim }  }

% function to place the numbers/lines/space in an equal width box
\cs_new_protected:Npn \palamas_makebox:n #1 {
   \makebox [ \l_palamas_boxwidth_dim ] [ c ] { #1 }
}
% function to porcess a change in notes (replace dash and dot)
\cs_new_protected:Npn \palamas_process_list:n #1 {
   \tl_set:Nn \l_tmpa_tl { #1 }
   \tl_replace_all:Nnn \l_tmpa_tl { - } { \g_palamas_line_tl }
   \tl_replace_all:Nnn \l_tmpa_tl { . } { \g_palamas_space_tl }
   \tl_map_function:NN \l_tmpa_tl \palamas_makebox:n
   \\
}

% some tokes for special function symbols
%% double dominat
\tl_new:N \g_double_dominat_tl
\tl_set:Nn \g_double_dominat_tl { \makebox[0.2em][l]{\raisebox{0.2em}{D}}D }
%% double dominat
\tl_new:N \g_dominat_without_root_tl
\tl_set:Nn \g_dominat_without_root_tl { \makebox[0em][l]{\raisebox{0.25ex}{\small\kern0.2em/}}D }
%% double dominat
\tl_new:N \g_double_subdominat_tl
\tl_set:Nn \g_double_subdominat_tl { \makebox[0.1em][l]{\raisebox{0.2em}{S}}S }

% main function
\NewDocumentCommand { \function } { m O{} O{0pt} m } {
   \tl_set:Nn \l_tmpa_tl { #1 }
   \tl_replace_all:Nnn \l_tmpa_tl { DD } { \g_double_dominat_tl }
   \tl_replace_all:Nnn \l_tmpa_tl { /D } { \g_dominat_without_root_tl }
   \tl_replace_all:Nnn \l_tmpa_tl { SS } { \g_double_subdominat_tl }
   \tl_use:N \l_tmpa_tl
   \clist_set:Nn \l_tmpa_clist { #4 }
   \clist_reverse:N \l_tmpa_clist
   \kern#3
   {
      \tiny
      \renewcommand { \arraystretch } { 0.75 }
      \raisebox { -0.68ex } {
         \begin{tabular}[b]{@{}l@{}}
            % upper voices
            \clist_map_function:NN \l_tmpa_clist \palamas_process_list:n
            % shift/gap
            \\[-1.2ex]
            % bass line
            \palamas_process_list:n { #2 }
         \end{tabular}
      }
   }
}

\ExplSyntaxOff

% following is only for the demo
\usepackage{parskip}
\usepackage{xcolor}
\newcommand{\showBaseLine}{\makebox[0pt][l]{\color{magenta}\rule{\textwidth}{0.1pt}}}
\newcommand{\showXHeightLine}{\makebox[0pt][l]{\color{yellow}\rule[1ex]{\textwidth}{0.1pt}}}
\newcommand{\showMidLine}{\makebox[0pt][l]{\color{cyan}\rule[0.785ex]{\textwidth}{0.1pt}}}
\newcommand{\showCapHeightLine}{\makebox[0pt][l]{\color{magenta}\rule[1.57ex]{\textwidth}{0.1pt}}}
\newcommand{\showAllLines}{\showBaseLine\showXHeightLine\showMidLine\showCapHeightLine}

\begin{document}
\showAllLines\mbox{}\enskip
% single change in upper voice
\function{D}{8-7} \enskip
% single chane in bass voice
\function{D}[8-7]{} \enskip
% change in upper and bass voice
\function{D}[8-7]{4-3} \enskip
% multiple changes
\function{D}[8--7]{4-3,6-5}

% more complex examples
\function{T}{..7-8,3---4} \enskip
\function{D}{4---3, 6-5, ..7-8} \enskip
\function{D}{4----3, 6-5---, ..7-8-,{11}-----} \enskip
\function{s}{5,6}

% special function symbols
\function{DD}{8-7} \enskip
\function{/D}{8-7} \enskip
\function{SS}{5,6}


% adjust the space between function letter and notes
\function{D}[]{8-7} \enskip
\function{D}[4-3]{} \enskip
\function{D}[4-3]{8-7}

vs.

\function{D}[][-1pt]{8-7} \enskip
\function{D}[4-3][-2.3pt]{} \enskip
\function{D}[4-3][-1pt]{8-7} 
\end{document}

You could use a matrix for this. I put everything in custom commands. Like this, you can adjust kerning, line thickness, arraystretch, font, and so on later.

% arara: pdflatex

\documentclass{article}
\usepackage{mathtools}
\newcommand{\mystack}[1]{\mspace{1mu}{\scriptsize\begin{matrix*}[l]#1\end{matrix*}}\mspace{4mu}}
\newcommand*{\myrule}[1]{~\rule[.5ex]{#1}{0.3pt}~}

\begin{document}    
\[D\mystack{7 \cr 6\myrule{2em}5  \cr 4\myrule{1.5em}3} T\mystack{5\\3}\]
\end{document}

enter image description here


Here I use \muse{Note}{space-separated-stack} where the space-separated-stack uses a syntax of x\-[y]z for individual lines. x and z are the numbers that display at the beginning and end of the left-aligned row, and y is the optional length of the bar (in multiples of 4ex, default multiple=1).

EDITED so that \- has optional rather than mandatory argument.

\documentclass{article}
\usepackage{stackengine}
\newcommand\sline[1][1]{~\rule[2pt]{4\dimexpr#1ex}{.6pt}~}
\newcommand\muse[2]{\let\-\sline\setstackgap{L}{.9\baselineskip}{\itshape%
  #1 \scriptsize\raisebox{1pt}{\Centerstack[l]{#2}}%
}}
\begin{document}
\muse{D}{7 6\-[2]5 4\-3}\quad\muse{T}{5 3}
\end{document}

enter image description here

The \muse macro is fully adjustable. Here, for example, I have revised it to reflect \tiny numbers, thinner \rule, less pre/post line rule spacing, narrower stacking gap...

\documentclass{article}
\usepackage{stackengine}
\newcommand\sline[1][1]{\,\,\rule[1.3pt]{4\dimexpr#1ex}{.4pt}\,\,}
\newcommand\muse[2]{\let\-\sline\setstackgap{L}{.85\baselineskip}{\itshape%
  #1 \tiny\raisebox{1.5pt}{\Centerstack[l]{#2}}%
}}
\begin{document}
\muse{D}{7 6\-[2]5 4\-3}\quad\muse{T}{5 3}
\end{document}

enter image description here