Hello Frédéric, hello all,

> I would use a little perl or python script to  do  this, not lilypond.
> This is just the sort of work that perl was intended for - munging text
> files. That is fine for Linux/Mac users, on Windows it may be more
> problematical. I don't touch Windows, so although I know it is possible,
> I don't know how easy/difficult it is.

why? The intent is not transforming text, but transforming information to a 
different form. Why not use Lilypond’s programming interface?

The easiest way to get this done would in fact be to not notate chords like

<c e> <d f> <e g>

but like

\new Voice << { c d e } { e f g } >>

This way the very same expression can be used as two voices by inserting a \\ 
in between. But if you really need <x y> notation you can easily do something 
like this:

%%%%%
notes = {
  <c e>-. <d f>-- <e g>-\f
}

{ \notes }

% Filter only n-th note from each chord
chordNth =
#(define-music-function (n music) (integer? ly:music?)
   ; Extract nth note event in chord.
   (define (filter-nth elts n count duration)
     (if (null? elts)
         (if (<= count n)
             ; less than n notes, add a skip
             (list (skip-of-moment-span (ly:make-moment 0 1) duration))
             '())
         (if (music-is-of-type? (car elts) 'note-event)
             (if (= count n)
                 (cons (car elts) (filter-nth (cdr elts) n (1+ count) 
duration))
                 (filter-nth (cdr elts) n (1+ count) duration))
             (cons (car elts) (filter-nth (cdr elts) n count duration)))))
   ; Loop over music to extract notes from each chord
   (define (loop music)
     (if (music-is-of-type? music 'event-chord)
         (ly:music-set-property!
          music 'elements
          (filter-nth (ly:music-property music 'elements) n 0 (ly:music-length 
music)))
         (let ((elt (ly:music-property music 'element))
               (elts (ly:music-property music 'elements)))
           (if (not (null? elt))
               (loop elt))
           (map loop elts))))
   (loop music)
   music)

<< \chordNth 1 \notes \\ \chordNth 0 \notes >>
%%%%%

This also saves you some massive headache getting around relative music. Take 
something like

notes = \relative {
  <c a'> <d b'> <e c'>
}

A simple text replacement would turn this into

<<
  \relative {
    a' b' c'
  }
  \\
  \relative {
    c d e
  }
>>

which is of course complete nonsense. The above function works well though, 
because the parser determines the octave when the music is defined.

I don‘t think you’ll get anything close to just 23 lines of code when trying 
to do this using an external script (and even that script will probably not be 
able to handle programmatically created chords such as

notes = \chordmode {
  c:maj7 d:m6 e:aug7
}

let alone chords created by custom functions. Also using an external script 
means you’ll have a much more complex build chain (file → script → tempfile → 
lilypond).

Also this function can easily be extended to be able to e.g. filter what types 
of articulation should be kept, or to filter notes by more complex rules.

Cheers,
Valentin

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to