10

This question is part of a new package:
metrix. Typeset metric/prosodic symbols standalone and above syllables.

I’m wrinting a new package and I need to process a list (using etoolbox at the moment but that can change …). Everything works but I want the list to do two things that don’t work:

  1. Ignore spaces, because xstring doesn’t get the right strings otherwise.
  2. Process an empty list element. It is ignored at the moment.
\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}

The output is

  1. 1231
  2. 1231
  3. ????

but it should be the following in all three cases

12301


What I really wan’t to know ;-)

I’m implementing a package to typeset the metrics of (latin) verses, and I’d like to have a macro like

\metrics{_    u  u  _   }
        {quid co-me-dent}

that renders as

quid comedent

What I’ve got so far is a macro that works with this syntax

\metrics{_-\ -u-u-_}
        {quid-\ -co-me-dent}

Obviously there are two differences the space between two words must be separated with hyphen as if it is a syllable and it must be escaped with \. It would be great if the first list (the symbols) can be a space separated list and the second on a combination of hyphen and space separated.

You may download my full code from my web site: http://tweh.de/texsx/metrics.tex

9

You can first replace the space with a special marker, say -\q_tobi_space_marker- so you can split at hyphens and have a way to check whether the item was a space. Here's an implementation.

Plan of attack:

  1. We change spaces in the way outlined before
  2. The two lists are split into sequences
  3. The "syllables" sequence is mapped item by item, stepping a counter each time;
    1. if the item is the space marker, step back the counter and issue a space
    2. otherwise use the syllable and put over it the right marker, looking at the "measures" sequence.

The symbol corresponding to the brevis or longa is obtained by defining two functions \tobi_u_mark: and \tobi___mark: so we can build it by using the item in the "measures" sequence.

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

enter image description here

Probably one should add some error checks on whether the lengths of the sequences agree. See How to count the frequency of a token in a token list.

  • Thanks. Looks great. Can you tell me a resource where I can learn how to read you code ? ;-) I’m don’t know anything about the L3 syntax … – Tobi Jul 18 '13 at 9:40
  • @Tobi Start with texdoc expl3 – egreg Jul 18 '13 at 9:41
  • Hm … seems a little complex :-) I got two question: 1. When using this code in a new package, I’d replace the _tobis by _<packagename> since I’m building a new module, right? 2. Is it bad practice to mix up L2 and L3 syntax? – Tobi Jul 18 '13 at 10:37
  • @Tobi I used a "generic" prefix, you should use one more suited to your package. About mixing syntaxes, I'd say that it's preferable to stick to one, but it's not mandatory. – egreg Jul 18 '13 at 10:43
  • OK … next question: How can I start to implement a L3 package. Which documentclass can I use to document the package? I know how to use DocStrip with L2 packages but what are the difference in the new version? I found that some packages use l3doc but I didn’t found a documentation on that class. – Tobi Jul 18 '13 at 11:00
3
\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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.