这个问题是新方案的一部分:
metrix
. 在音节独立及以上排版韵律符号。
我正在编写一个新包,需要处理一个列表(etoolbox
目前正在使用,但可能会改变……)。一切正常,但我希望列表执行两件事,但不起作用:
- 忽略空格,因为
xstring
否则无法获得正确的字符串。 - 处理空列表元素。目前它被忽略。
\documentclass{article}
\usepackage{etoolbox}
\usepackage{xstring}
\setlength{\fboxsep}{0pt}
\DeclareListParser{\dolist}{-}
\newcommand{\mylist}[1]{%
\renewcommand{\do}[1]{%
\IfStrEqCase{##1}{%
{}{0}%
{a}{1}%
{b}{2}%
{c}{3}%
}[?]%
}%
\dolist{#1}%
}
\begin{document}
1. \mylist{a-b-c--a}
2. \mylist{ a- b- c- - a}
3. \mylist{ a - b - c - - a }
\end{document}
输出为
- 1231
- 1231
- ????
但在这三种情况下都应该是这样的
12301
我真正想知道的是 ;-)
我正在实现一个包来排版(拉丁)诗句的韵律,我想要一个像这样的宏
\metrics{_ u u _ }
{quid co-me-dent}
渲染为
到目前为止,我得到的是一个可以使用此语法的宏
\metrics{_-\ -u-u-_}
{quid-\ -co-me-dent}
显然,有两个区别:两个单词之间的空格必须用连字符分隔,就像它是一个音节一样;必须用 进行转义\
。如果第一个列表(符号)可以用空格分隔,而第二个列表可以用连字符和空格分隔,那就太好了。
您可以从我的网站下载我的完整代码:http://tweh.de/texsx/metrics.tex
答案1
您可以先用特殊标记替换空格,这样-\q_tobi_space_marker-
您就可以在连字符处拆分,并有办法检查该项目是否是空格。这是一个实现。
攻击计划:
- 我们按照之前概述的方式改变空间
- 两个列表被分成序列
- “音节”序列被逐项映射,每次增加一个计数器;
- 如果该项目是空间标记,则后退柜台并发出空间
- 否则,使用音节并在其上放置正确的标记,同时查看“小节”序列。
对应的符号短肌或者隆加是通过定义两个函数获得的\tobi_u_mark:
,\tobi___mark:
因此我们可以使用“措施”序列中的项目来构建它。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\metrics}{mm}
{
\tobi_metrics:nn { #1 } { #2 }
}
\tl_new:N \l_tobi_words_tl
\seq_new:N \l_tobi_syllables_seq
\seq_new:N \l_tobi_measures_seq
\quark_new:N \q_tobi_space_marker
\int_new:N \l_tobi_process_int
\cs_new_protected:Npn \tobi_metrics:nn #1 #2
{
\tl_set:Nn \l_tobi_words_tl { #2 }
% change spaces into -\q_tobi_space_marker-
\tl_replace_all:Nnn \l_tobi_words_tl { ~ } { - \q_tobi_space_marker - }
% split the (modified) second argument at -
\seq_set_split:NnV \l_tobi_syllables_seq { - } \l_tobi_words_tl
% split the first argument "at nothing"
\seq_set_split:Nnn \l_tobi_measures_seq { } { #1 }
\int_zero:N \l_tobi_process_int
\seq_map_inline:Nn \l_tobi_syllables_seq
{
\int_incr:N \l_tobi_process_int
\tl_if_eq:nnTF { ##1 } { \q_tobi_space_marker }
{% we had a space, step back the counter and issue a space
\int_add:Nn \l_tobi_process_int { -1 }
\c_space_token
}
{% print the syllable with the metric marker
\tobi_print_syllable:n { ##1 }
}
}
}
\cs_new_protected:Npn \tobi_print_syllable:n #1
{% Just a rough approximation, use your method
\leavevmode\vbox{\offinterlineskip
\halign{##\cr\hidewidth \tobi_print_meter: \hidewidth \cr #1 \cr}}
}
\cs_new_protected:Npn \tobi_print_meter:
{
\use:c {tobi_\seq_item:Nn \l_tobi_measures_seq { \l_tobi_process_int }_mark:}
}
\cs_new:Npn \tobi_u_mark: { \Large \u{} }
\cs_new:Npn \tobi___mark: { \Large -- }
\ExplSyntaxOff
\begin{document}
\metrics{_ u u _ }
{quid co-me-dent}
\end{document}
也许应该添加一些错误检查来确定序列的长度是否一致。参见如何计算 token 列表中 token 的频率。
答案2
\documentclass{article}
\usepackage{stringstrings}
\newcommand{\mylist}[1]{%
\edef\thestring{#1-}%
\noblanks[q]{\thestring}%
\convertword[q]{\thestring}{--}{-0}%
\convertword[q]{\thestring}{a-}{1}%
\convertword[q]{\thestring}{b-}{2}%
\convertword[q]{\thestring}{c-}{3}%
\convertword{\thestring}{d-}{4}%
}
\begin{document}
1. \mylist{a-b-c--a}
2. \mylist{ a- b- c- - a}
3. \mylist{ a - b - c - - a }
\end{document}