> Hi all,

Hi Luca,

> I was looking into making some lead sheets, and it occurred to me a version
> of parallelMusic that would deal with chords/melody/lyrics would be really
> handy to have.
> 
> I'm thinking something like this (say for 2 bars of Amazing grace, skipping
> the pickup for brevity):
> 
> \parallelMusic #'(chords voiceA lyricsOne lyricsTwo) {
>   c2. |
>   c2 e8 c |
>   ma -- zing __ _ |
>   grace that __ _ |
> 
>   c2.:7/g |
>   e2 d4 |
>   grace how |
>   taught my |
> }
> 
> \score {
>   <<
>     \new ChordNames { \chordmode { \chords} }
>     \new Staff {
>       \new Voice = "voiceA" { \voiceA }
>     }
>     \new Lyrics \lyricsto "voiceA" { \lyricmode { \lyricsOne } }
>     \new Lyrics \lyricsto "voiceA" { \lyricmode { \lyricsTwo } }
> 
> }

It would very well be possible to parse the input as string, which would by 
the way remove a lot of the effort required to get \parallelMusic to work.

The appended file parses a string in the format

```
C[...]: ... |
C[...]: ... |
V[...]: ... |
V[...]: ... |
L[...]: ... |
L[...]@V[...]: ... |
...

C[...]: ... |
C[...]: ... |
V[...]: ... |
V[...]: ... |
L[...]: ... |
L[...]@V[...]: ... |
...

...
```

and transforms it into a sequence of blocks

<<
\context Chordnames = "C[...]" { ... }
...
>>

The function will match from Token (optionally with preceeding whitespace) to 
the next |, which means we can do multi line entries as well.

Cheers,
Tina
#(define parse-short-hands
   (let ((regex-subs
          (list
           ; Chords
           (cons (ly:make-regex "(^|\\n) *(C[a-zA-Z0-9]*)\\:([^\\|]*)\\|")
                 '(1 "\\context ChordNames = \"" 2 "\" \\chordmode { " 3 " } "))
           ; Voice
           (cons (ly:make-regex "(^|\\n) *(V[a-zA-Z0-9]*)\\:([^\\|]*)\\|")
                 '(1 "\\context Voice = \"" 2 "\" { " 3 " } "))
           ; Lyrics
           (cons (ly:make-regex "(^|\\n) *(L[a-zA-Z0-9]*)\\:([^\\|]*)\\|")
                 '(1 "\\context Lyrics = \"" 2 "\" \\lyricmode { " 3 " } "))
           ; Lyrics with voice
           (cons (ly:make-regex "(^|\\n) *(L[a-zA-Z0-9]*)@(V[a-zA-Z0-9])\\:([^\\|]*)\\|")
                 '(1 "\\context Lyrics = \"" 2 "\" \\lyricsto \"" 3 "\" { " 4 " } "))
           ; Blocks
           (cons (ly:make-regex "\\n *\\n")
                 '("\n>>\n\n<<\n")))))
     (lambda (string)
       (string-append
        "<<"
        (fold
         (lambda (pair string)
           (apply ly:regex-replace (car pair) string (cdr pair)))
         string
         regex-subs)
        ">>"))))

parallelize =
#(define-music-function (input) ((lambda (x) (or (string? x) (list? x))))
   (if (list? input)
       (apply
        (@@ (lily) read-lily-expression-internal)
        (parse-short-hands (list-ref input 1))
        (cddr input))
       ((@@ (lily) read-lily-expression-internal)
        (parse-short-hands input)
        (car (ly:input-file-line-char-column (*location*)))
        (cadr (ly:input-file-line-char-column (*location*)))
        (list))))


themusic = \parallelize #'#{
  C:      c2.             |
  V1:     c2    e8 c      |
  L1@V1:  ma -- zing __ _ |
  L2@V1:  grace that __ _ |

  C:      c2.:7/g   |
  V1:     e2    d4  |
  L1@V1:  grace how |
  L2@V1:  taught my |
#}


{ \time 3/4 \themusic }

{
  \parallelize #'#{
    V1: c''4 d'' e'' f'' |
    V1: g'4  b'  c'' d''  |
    V1: e'4  g'  g'  g'  |
  #}
}

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

Reply via email to