相当于“in”运算符

相当于“in”运算符

我想编写一个命令来响应一组参考字符串或另一组参考字符串中的参数。

该参数采用(音乐)音符名称,并且命令将根据参数是否为或(a, h, c, d, e, f, g)(德语音符名称)来打印临时记号。(ces, des, es, fes, ges, as, b)(cis, dis, eis, fis, gis, ais, his)

在编程语言中我会使用in运算符来实现这一点,但我不知道如何在 LaTeX 中做到这一点。

我想写的是

\notewithacc{c}\\
\notewithacc{cis}\\
\notewithacc{des}

并得到

\natural c\\
\sharp cis\\
\flat des

作为输出。

答案1

下面的示例使用 来\in@{<substring>}{<string>}测试 是否<substring>是 的一部分<string>。测试完成后,结果由开关 提供\ifin@

\documentclass{article}

% List with notes
\newcommand*{\NotesNatural}{a, h, c, d, e, f, g}
\newcommand*{\NotesFlat}{ces, des, es, fes, ges, as, b}
\newcommand*{\NotesSharp}{cis, dis, eis, fis, gis, ais, his}

\makeatletter

% Sanitize note lists
\newcommand*{\NotesNormalize}[1]{%
  \edef#1{%
    ,\expandafter\zap@space#1 \@empty,%
  }%
}

\NotesNormalize{\NotesNatural}
\NotesNormalize{\NotesFlat}
\NotesNormalize{\NotesSharp}

% \NotesTest{<note>}{<note list>}{<yes>}{<no>}
\newcommand*{\NotesTest}[2]{%
  \edef\NotesTemp{%
    \noexpand\in@{,#1,}{#2}%
  }\NotesTemp
  \ifin@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\newcommand*{\notewithacc}[1]{%
  \in@{,}{#1}%
  \ifin@
    ?#1%
  \else
    \NotesTest{#1}{\NotesNatural}{%
      $\m@th\natural$#1%
    }{%
      \NotesTest{#1}{\NotesFlat}{%
        $\m@th\flat$#1%
      }{%
        \NotesTest{#1}{\NotesSharp}{%
          $\m@th\sharp$#1%  
        }{%
          ?#1%
        }%
      }%
    }%
  \fi   
}
\makeatother

\begin{document}
  \noindent
  \notewithacc{c}\\
  \notewithacc{cis}\\
  \notewithacc{des}\\
  \notewithacc{x}\\
  \notewithacc{dis,eis}
\end{document}

结果

评论:

  • \zap@space从注释列表中删除清理步骤中的空格。
  • 此外,列表都以逗号开头和结尾。这样,包含搜索注释的子字符串就被逗号包围。这确保了精确匹配。
  • 顺便说一句,我不知道为什么临时变音记号在 LaTeX 中是数学符号。如果设置了,\m@th则删除周围的空格。\mathsurround
  • \notewithacc更新后的解决方案还检查中的参数中是否有逗号\notewithacc{dis,eis}

答案2

采取类似的方法Heiko 的回答但使用 LaTeX3 编程层,expl3可能会导致类似这样的结果:

\documentclass{article}

\usepackage{expl3,xparse}
\ExplSyntaxOn
\makeatletter
% Comma lists of notes
\clist_const:Nn \c_ulinotes_natural_clist {a, h, c, d, e, f, g}
\clist_const:Nn \c_ulinotes_flat_clist {ces, des, es, fes, ges, as, b}
\clist_const:Nn \c_ulinotes_sharp_clist {cis, dis, eis, fis, gis, ais, his}

\cs_new_protected:Npn \ulinotes_note:n #1
  {
    \clist_if_in:NnT \c_ulinotes_natural_clist {#1}
      { \c_math_toggle_token \m@th \natural \c_math_toggle_token }
    \clist_if_in:NnT \c_ulinotes_flat_clist {#1}
      { \c_math_toggle_token \m@th \flat \c_math_toggle_token }
    \clist_if_in:NnT \c_ulinotes_sharp_clist {#1}
      { \c_math_toggle_token \m@th \sharp \c_math_toggle_token }
  #1
  }

\NewDocumentCommand { \notewithacc } { >{\TrimSpaces} m }
  { \ulinotes_note:n {#1} }
 \makeatother
\ExplSyntaxOff

\begin{document}
  \noindent
  \notewithacc{c}\\
  \notewithacc{cis}\\
  \notewithacc{des}\\
  \notewithacc{x}
\end{document}

这使用expl3逗号列表成员资格测试以及内置命令,在“抓取”时从参数中删除空格。与“标准”LaTeX2e 方法一样,我们必须考虑到符号需要数学模式,这目前意味着使用一些 LaTex2e 代码(\m@th)。

答案3

MWE使用\csname映射:

\documentclass{article}

\makeatletter
\@for\@n@te:=a,h,c,d,e,f,g\do{\expandafter\def\csname n@te(\@n@te)\endcsname{\natural}}
\@for\@n@te:=ces,des,es,fes,ges,as,b\do{\expandafter\def\csname n@te(\@n@te)\endcsname{\flat}}
\@for\@n@te:=cis,dis,eis,fis,gis,ais,his\do{\expandafter\def\csname n@te(\@n@te)\endcsname{\sharp}}

\def\notewithacc#1{%
\ifcsname n@te(#1)\endcsname%
\ensuremath{\csname n@te(#1)\endcsname}#1%
\else ?#1 %
\fi
}
\makeatother

\begin{document}

\makeatletter
\begin{itemize}
\item \@for\@n@te:=a,h,c,d,e,f,g\do{\notewithacc{\@n@te} }
\item \@for\@n@te:=ces,des,es,fes,ges,as,b\do{\notewithacc{\@n@te} }
\item \@for\@n@te:=cis,dis,eis,fis,gis,ais,his\do{\notewithacc{\@n@te} }
\item \@for\@n@te:=x,fi,{dis,eis}\do{\notewithacc{\@n@te} }
\end{itemize}
\makeatother

\notewithacc{des}

\end{document}

在此处输入图片描述

相关内容