# Writing musical pitches

Is there a package or macro that allows me to easily typeset musical pitches, like the following:

? Indeed I would like to have subscripts for the octaves. Let's say

$\mathrm{E}\flat_3$

How would I write a macro producing this output, when the invocation is

\note{Eb3}

Like:

\newcommand{\note}[1]{???}

I would have to take the string apart, the first char goes into \mathrm, then there is an optional second char # or b, followed by a digit.

-
Do you know this ctan.org/pkg/musictex ? –  Sigur Dec 4 '13 at 15:37
I read about musictex. I don't want to typeset scores, I use Lilypond for that. Also it says it's for TeX not LaTeX. I just need to have some inline functions such as the note names above. –  Emit Taste Dec 4 '13 at 18:30

The only quirk is that you have to use brackets [] rather than braces {} to enclose the argument.

\documentclass{article}
\def\note[#1#2#3]{#1\if b#2$\flat_#3$\else\if#2##$\sharp_#3$\else$_#2$\fi\fi}
\begin{document}
\note[Eb3]
\note[A2]
\note[F#4]
\end{document}

If you would prefer the use of braces to brackets, then the following modification would do. It renames the \note from the above code as \xnote and creates a newcommand \note to do the argument translation.

\documentclass{article}
\newcommand\note[1]{\xnote[#1]}
\def\xnote[#1#2#3]{#1\if b#2$\flat_#3$\else\if#2##$\sharp_#3$\else$_#2$\fi\fi}
\begin{document}
\note{Eb3}
\note{A2}
\note{F#4}
\end{document}

Since egreg's answer seems to go beyond what the OP asked, providing reasonable behavior when either argument 2, argument 3, or arguments 2 and 3 are missing, I felt it incumbent to do the same (EDITED using Qrrbrrbr...brbrbrl's suggestion to enclose subscript definitions in braces, which will facilitate two-digit octave numbers, shown in last line of output):

\documentclass{article}
\newcommand\note[1]{\xnote#1\relax\relax\relax}
\def\xnote#1#2#3\relax{#1\if#2\relax\else\if b#2$\flat\if#3\relax% \else_{#3}\fi$\else\if###2$\sharp\if#3\relax\else_{#3}\fi$\else$_{#2}$\fi\fi\fi}
\begin{document}
\note{Eb3}
\note{A2}
\note{C#}
\note{A}
\note{Eb}
\note{F#4}

\note{F{14}}
\note{F#{14}}
\end{document}

-
How I like when an answer to a question asking for a package has only a few lines of code! :-) –  Przemysław Scherwentke Dec 4 '13 at 15:59
If you use _{#3} instead of _#3 (though I prefer \textsubscript) it would be possible to use \note{F#14} but 4 would be dropped if \node{F14} has been used. –  Qrrbrbirlbel Dec 4 '13 at 19:48
@Qrrbrbirlbel I revised, based on your suggestion. –  Steven B. Segletes Dec 5 '13 at 1:51

Some slow scanning of the argument is needed:

\documentclass{article}
\usepackage{fixltx2e} % for \textsubscript
\makeatletter
\newcommand{\note}[1]{\emit@note#1\@nil}
\def\emit@note#1#2\@nil{%
\textup{#1}%
\if\relax\detokenize{#2}\relax
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{\emit@@note#2\@nil}%
}
\def\emit@@note{\@ifnextchar##{\emit@sharp}{\emit@@@note}}
\def\emit@sharp#1{$\sharp$\emit@@@note}
\def\emit@@@note{\@ifnextchar b{$\flat$\emit@@@@note}{\emit@@@@note{}}}
\def\emit@@@@note#1#2\@nil{\textsubscript{#2}}
\makeatother

\begin{document}

\note{A}
\note{A#}
\note{Ab}
\note{A2}
\note{A#2}
\note{Ab2}

\end{document}

By kind request, here's a possible LaTeX3 implementation:

\documentclass{article}
\usepackage{fixltx2e} % for \textsubscript

\usepackage{xparse}
\ExplSyntaxOn
% user level command
\NewDocumentCommand{\note}{m}
{
\emit_note:n { #1 }
}

% a variable
\tl_new:N \l_emit_specs_tl

% internal main function
\cs_new_protected:Npn \emit_note:n #1
{% Get the first token
\emit_textup:x { \tl_head:n { #1 } }
% Get the rest and pass control to \emit_do_specs:n
\tl_set:Nx \l_emit_specs_tl { \tl_tail:n { #1 } }
\tl_if_empty:NF \l_emit_specs_tl
{
\emit_do_specs:o { \l_emit_specs_tl \q_stop }
}
}

% We can't use \textup{ \tl_head:n { #1 } } because of possible #
\cs_new_protected:Npn \emit_textup:n #1
{
\textup { #1 }
}
\cs_generate_variant:Nn \emit_textup:n { x }

% Check if the first token is # or b
% and take appropriate actions
% Then hand the remainder to \emit_range:w
\cs_new_protected:Npn \emit_do_specs:n #1
{
\peek_charcode_remove:NTF ##
{ $\sharp$ \emit_range:w }
{
\peek_charcode_remove:NTF b
{ $\flat$ \emit_range:w }
{ \emit_range:w }
}
#1
}
\cs_generate_variant:Nn \emit_do_specs:n { o }

\cs_new_protected:Npn \emit_range:w #1 \q_stop
{
\tl_if_empty:nF { #1 } { \textsubscript{#1} }
}
\ExplSyntaxOff

\begin{document}

\note{A}
\note{A#}
\note{Ab}
\note{A2}
\note{A#2}
\note{Ab2}

\end{document}
-
No L3 version? Pleeeease. :) –  Paulo Cereda Dec 4 '13 at 18:05
Can you tell me what slow-scanning is, and if this much longer version has any advantages over the solution of Steven B. Segletes? –  Emit Taste Dec 4 '13 at 18:32
@EmitTaste You can also do \note{A#12}, with this. It's slow in the sense that I use \@ifnextchar to look at the next token. –  egreg Dec 4 '13 at 18:54
Ok, thanks! I will use this if I need double accidentals or higher octaves. –  Emit Taste Dec 4 '13 at 20:42
@EmitTaste For double accidentals one needs to extend the macros, but it wouldn't be difficult. –  egreg Dec 4 '13 at 20:48