Is it possible to count the number of a token in a token list?
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\tl_new:N \tobi_list_tl
\tl_set:Nn \tobi_list_tl {foo~bar~baz}
\begin{document}
'\tl_use:N \tobi_list_tl'~contains~?~spaces.
\end{document}
In a macro to typeset syllables and prosoidic symbols I need to count the number of spaces in a token list.
\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 }
% AT THIS POINT I WANT TO KNOW THE NUMBER OF SPACES <---------
% IN \l_tobi_words OR THE NUMBER OF \q_tobi_space_marker <------------
% IN \l_tobi_syllables_seq <---------
\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 }
}
}
}
See https://tex.stackexchange.com/a/124531/4918.
I need the number to check whether there are enaugh symbols in the list to by combined with syllables, this is my test so far:
\int_compare:nT
{
\seq_count:N \l_@@_syllables_seq - 1 != \seq_count:N \l_@@_symbols_seq
}
{
ERROR
}
The -1
must be replaced by the number of spaces.
Maybe I should add some information on the usage. This will be part of a macro
\metrics{_ u u _ _ _ | _ _ u u _ _ _ }
{flos ve-te-ris vi-ni | meis na-ri-bus ob-iec-tust}
The first argument is a space separated list of metric symbols (accesd by abbreviations like u
or _
) and the second list contains hyphenated words. I need to check if there is a symbol for every syllable but \seq_count:
doesn’t work here since spaces from the second list are treated specially. The test must be
# of symbols = # of syllables
lengt of symbol list = lengthh of syllablelist – # of spaces
This is the latest version of the complete processing macro:
\cs_new_protected:Npn \__metrix_metrics:nn #1 #2
{
\tl_set:Nn \l__metrix_words_tl { #2 }
\tl_replace_all:Nnn \l__metrix_words_tl { ~ } { - \q__metrix_space_marker - }
\seq_set_split:NnV \l__metrix_syllables_seq { - } \l__metrix_words_tl
\seq_set_split:Nnn \l__metrix_symbols_seq { ~ } { #1 }
\int_zero:N \l__metrix_process_int
\seq_map_inline:Nn \l__metrix_syllables_seq
{
\tl_if_eq:nnT { ##1 } { \q__metrix_space_marker }
{ \int_incr:N \l__metrix_process_int }
}
\int_compare:nTF
{
\seq_count:N \l__metrix_syllables_seq -
\seq_count:N \l__metrix_symbols_seq = \l__metrix_process_int
}
{
\int_zero:N \l__metrix_process_int
\seq_map_inline:Nn \l__metrix_syllables_seq
{
\int_incr:N \l__metrix_process_int
\tl_if_eq:nnTF { ##1 } { \q__metrix_space_marker }
{
\int_add:Nn \l__metrix_process_int { -1 }
\c_space_token
}
{
\str_case:nnn { ##1 }
{
{ | } { \__metrix_l_break: }
{ || } { \__metrix_ll_break: }
}
{
\__metrix_print_syllable:n { ##1 }
}
}
}
}
{
\__metrix_error_msg:n { Numbers~of~symbols~and~syllables~mismatch. }
}
}
Every works except when one or both of the lists end with a space, so it would be great if all spaces could be cut from the right side before start processing the lists.
\seq_set_split:NnV
looks like the best plan.flos ve-te-ris vi-ni | meis
, i.e. containing letters (latin1), spaces, hyphens and pipes.