撰写音乐音调

撰写音乐音调

是否有一个包或宏可以让我轻松排版音乐音调,如下所示:

在此处输入图片描述

? 我确实希望八度音程有下标。假设

$\mathrm{E}\flat_3$

当调用以下宏时,我该如何编写一个产生此输出的宏:

\note{Eb3}

喜欢:

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

我必须将字符串拆开,第一个字符放入\mathrm,然后是可选的第二个字符#b,后面跟着一个数字。

答案1

唯一的怪癖是您必须使用括号[]而不是大括号{}来括起参数。

\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}

在此处输入图片描述

如果您更喜欢使用大括号而不是方括号,那么可以进行以下修改。它将\note上述代码中的重命名为\xnote并创建一个新命令\note来执行参数转换。

\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}

由于 egreg 的回答似乎超出了 OP 的要求,在缺少参数 2、参数 3 或参数 2 和 3 时提供合理的行为,因此我觉得有责任做同样的事情(使用 Qrrbrrbr...brbrbrl 的建议进行编辑,将下标定义括在括号中,这将有助于显示两位数的八度数字,如输出的最后一行所示):

\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}

在此处输入图片描述

答案2

需要对该论点进行一些缓慢的扫描:

\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}

在此处输入图片描述


根据请求,这里有一个可能的 LaTeX3 实现:

\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}

一种利用其拆分功能的新实现l3regex。可以针对格式错误的输入实施某种错误检查。

临时记号取自 MusixTeX 字体,采用的方法与clemens 的回答

\documentclass{article}
\usepackage{xparse,l3regex}

\DeclareFontFamily{U}{musix}{}
\DeclareFontShape{U}{musix}{m}{n}{
  <-12>   s * [1.5] musix11
  <12-15> s * [1.5] musix13
  <15-18> s * [1.5] musix16
  <18-23> s * [1.5] musix20
  <23->   s * [1.5] musix29
}{}

\NewDocumentCommand{\musixsym}{m}{%
  \raisebox{.6ex}{\normalfont\usefont{U}{musix}{m}{n}\symbol{#1}}%
}

\newcommand\mflat{\musixsym{'62}}
\newcommand\mdoubleflat{\musixsym{'63}}
\newcommand\msharp{\musixsym{'64}}
\newcommand\mdoublesharp{\musixsym{'65}}
\newcommand\mnatural{\musixsym{'66}}

\ExplSyntaxOn
\NewDocumentCommand{\note}{m}
 {
  \tl_set:Nn \l_emit_note_tl { #1 }
  \regex_replace_all:nnN { \# } { S } \l_emit_note_tl
  \regex_split:nVN { ([A-G]+) ([Sbn]*) (\d*) } \l_emit_note_tl \l_emit_note_seq
  \seq_item:Nn \l_emit_note_seq { 2 }
  \str_case_x:nn { \seq_item:Nn \l_emit_note_seq { 3 } }
   {
    {S}{\msharp}
    {SS}{\,\mdoublesharp}
    {b}{\mflat}
    {bb}{\mdoubleflat}
    {n}{\mnatural}
   }
  \textsubscript{\seq_item:Nn \l_emit_note_seq { 4 }}
 }
\cs_generate_variant:Nn \regex_split:nnN { nVN }
\tl_new:N \l_emit_note_tl
\seq_new:N \l_emit_note_seq
\ExplSyntaxOff

\begin{document}

\note{A}
\note{B#}
\note{C##}
\note{Db}
\note{Ebb}
\note{F2}
\note{G#2}
\note{A##2}
\note{Bb2}
\note{Cbb2}
\note{Dn1}

\end{document}

在此处输入图片描述

请注意,自 2015/01/01 版本起,LaTeX\textsubscript已被纳入内核。

相关内容