标记并解析单词

标记并解析单词

经过 10 多年的 LaTeX 中断之后,我回来了,并慢慢重新掌握了宏编写。

我现在想将字符串“fisis”解析为首字母“f”和后半部分“isis”。区分大小写其实不是问题。

有效令牌遵循以下规则:

  1. 第一个字母必须是 {a, b, c..., g} 之一
  2. 标记的第二部分由 0、1 或 2 个标记“es”或“is”组成

例如,“cesis”是无效的,因为根据规则 2,“es”后面不能跟“is”。

用例是通过宏创建音乐作品调性的多语言渲染,例如:\tonality{fis}{minor} 其将以德语、法语和英语渲染如下:{Fis-moll. {\emph Fa dièse mineur.} F sharp minor.}

例如,第一个例子“fisis”将被解析为(“f”;“is”x 2),其在英语中将被呈现为“F double sharp”(使用 \tonalityEN 宏),在法语中将被呈现为“Ré double dièse”(使用 \tonalityFR 宏)。

如何实现这一点?

答案1

我不完全明白你的问题,但如果你能够描述如何处理语言切换,下面的内容可以进行一些测试,并可以作为基础。我使用了方便的xstring它带有非常强大的字符串处理工具,如下所示。首先,我们删除第一个字符,然后测试单词的其余部分是否包含剩余部分的前两个字符。如果在删除检测到的两个字母后遗漏了某些内容,则会给出错误。之后就很简单了。

\documentclass{article}
\usepackage{xstring}
\def\parsethis#1{%
\if\relax#1\relax\else%
\StrLeft{#1}{1}[\myfirstletter]
\StrGobbleLeft{#1}{1}[\myrestofword]
\StrLeft{\myrestofword}{2}[\mysample]
\StrCount{\myrestofword}{\mysample}[\numofreps]
\StrDel{\myrestofword}{\mysample}[\remainingchars]
\if\relax\remainingchars\relax%
I found \numofreps\space copies of the string ``\mysample''.%
\else
There is a mixture of es and is.%
\fi
}

\begin{document}
\parsethis{cisis}\par
\parsethis{feseses}\par
\parsethis{dadadadad}\par
\parsethis{b}\par
\parsethis{basis}
\end{document}

在此处输入图片描述

答案2

您可以检查新的 LaTeX3 编程风格是否适合您:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand { \tonality } { m m }
 {
  \ton_tonality:nn { #1 } { #2 }
 }

\tl_new:N \l_ton_key_tl
\tl_new:N \l_ton_accidents_tl
\cs_new_protected:Npn \ton_tonality:nn #1 #2
 {
  % Normalize to uppercase
  \tl_to_uppercase:n
   {
    % Get the key
    \tl_set:Nx \l_ton_key_tl { \tl_head:n { #1 } }
    % Get the accidents
    \tl_set:Nx \l_ton_accidents_tl { \tl_tail:n { #1 } }
   }
  % check the key
  \str_case:onn { \l_ton_key_tl }
   {
    {A}{ \ton_print_key:n {A} }
    {B}{ \ton_print_key:n {B} }
    {C}{ \ton_print_key:n {C} }
    {D}{ \ton_print_key:n {D} }
    {E}{ \ton_print_key:n {E} }
    {F}{ \ton_print_key:n {F} }
    {G}{ \ton_print_key:n {G} }
   }
   { \msg_error:nn { tonality } { bad-key } !! }
  % check the accidents
  \str_case:onn { \l_ton_accidents_tl }
   {
    {}    { }
    {ES}  { \ton_print_flat: }
    {ESES}{ \ton_print_doubleflat: }
    {IS}  { \ton_print_sharp: }
    {ISIS}{ \ton_print_doublesharp: }
   }
   { \msg_error:nn { tonality } { bad-accidents } !! }
  \ton_print_mode:n { #2 }
 }

\cs_new:Npn \ton_print_mode:n #1 { \nobreakspace #1 }

\cs_new:Npn \ton_print_key:n #1 { #1 }
\cs_new:Npn \ton_print_flat: { \nobreakspace flat }
\cs_new:Npn \ton_print_doubleflat: { \nobreakspace doubleflat }
\cs_new:Npn \ton_print_sharp: { \nobreakspace sharp }
\cs_new:Npn \ton_print_doublesharp: {\nobreakspace doublesharp }

\msg_new:nnnn { tonality } { bad-key }
 { Key~not~in~range~A--G }
 { The~first~character~is~not~good }
\msg_new:nnnn { tonality } { bad-accidents }
 { Bad~accidents~specification }
 { The~string~for~the~accidents~is~wrong }

\ExplSyntaxOff

\begin{document}
\tonality{A}{minor}

\tonality{fis}{minor}

\tonality{fesis}{major}

\tonality{qisis}{major}
\end{document}

答案3

在此处输入图片描述

这个例子是普通的 tex,但当然可以在乳胶中起作用。

\def\zz#1{%
\edef\tmp{\noexpand\zzformat
\zzz#1\relax\relax\relax\relax\relax\relax}%
%show\tmp
\tmp}

\def\zzz#1#2#3#4#5#6#7{%
{#1}%
\ifx\relax#2{0}{}%
\else\ifx\relax#4{1}{#2#3}%
\else{2}{#2#3}\fi\fi}

\def\zzformat#1#2#3{%
#1 + #2 ( #3 )
}

\zz{a}

\zz{aes}

\zz{fisis}

\bye

答案4

感谢您的帮助,我终于找到了解决方案。下面是记录的调试版本 - 希望它对其他人有用。

\documentclass{article}
\usepackage{xstring}

\def\flatmodifier{es}
\def\sharpmodifier{is}
\def\naturalmodifier{}

\parindent 0cm

\def\parsethis#1{%
    {\bf{#1}\par}%
    \if\relax#1\relax\else%
    \StrLeft{#1}{1}[\myfirstletter]%                            \myfirstletter = root tone
    \StrPosition{abcdefg}{\myfirstletter}[\mynote]
    \ifnum\mynote=0%
        ERROR!!! Invalid note name (\myfirstletter)\par
    \else
        \StrGobbleLeft{#1}{1}[\myrestofword]%                       Eat first letter
        \StrLeft{\myrestofword}{2}[\mysample]%                      \mysample = 2 characters after the root tone
        \ifx\mysample\naturalmodifier%                                      (Natural)
            \def\mytonemodifier{Natural}%
        \else
            \ifx\mysample\flatmodifier%                                     (Flat)
                    \def\mytonemodifier{Flat}%
            \else
                \ifx\mysample\sharpmodifier%                                (Sharp)
                    \def\mytonemodifier{Sharp}%
                \else
                    \def\mytonemodifier{\relax}%                    (Invalid)
                \fi
            \fi
        \fi
        \if\mytonemodifier\relax
            ERROR!!! Invalid note pitch modifier (\mysample)\par
        \else
            Okay, we can proceed.\par
            \StrCount{\myrestofword}{\mysample}[\numofreps]%            \numofreps = # repetitions of \mysample
            \StrDel{\myrestofword}{\mysample}[\remainingchars]%         \remainingchars = remaining characters after removing \mysample from the front
            \if\relax\remainingchars\relax%                                 IF there are remaining characters
                {\small I found \numofreps\space copies of the string ``\mysample''.\par}%
                \ifnum\numofreps<3%
                    \myfirstletter\ %                                           Display note name
                    \ifnum\numofreps=0%                                         No modifier
                        \mytonemodifier\ %                                          Display note modifier
                    \else
                        \ifnum\numofreps=2%                                         Double flat/sharp
                            Double %
                        \fi
                        \mytonemodifier\ %                                          Display note modifier
                    \fi
                \else%                                                          ELSE
                    ERROR: Too many accidental modifiers (\numofreps).%
                \fi%                                                            ENDIF
            \else
                ERROR: There is a mixture of es and is.%
            \fi
        \fi
    \fi
}

\begin{document}
\parsethis{h}\par
\parsethis{b}\par
\parsethis{be}\par
\parsethis{bas}\par
\parsethis{bes}\par
\parsethis{bese}\par
\parsethis{beses}\par
\parsethis{cisis}\par
\parsethis{feseses}\par
\parsethis{fesesis}\par
\parsethis{dadadadad}\par
\parsethis{basis}\par
\parsethis{benhottentottententententoonstelling}\par
\end{document}

相关内容