Hello list,
if someone has loaded and tried my files on a windows machine, they
probably didn't compile.
So I uploaded a new version, which should compile on windows - well
it did not on an old W2k machine, I could use to test ... and so I
changed some things regarding the scheme-function (getcwd).
http://www.xn--schne-noten-tfb.de/lalily.tgz
Cheers, Jan-Peter
On 10.04.2012 13:52, Jan-Peter Voigt wrote:
On 06.04.2012 13:17, Janek Warchoł wrote:
On Thu, Apr 5, 2012 at 7:37 PM, Jan-Peter Voigt <address@hidden> wrote:
Dear community,
I bundled some extensions in a little package to try out. Some of these
ideas might be interesting to include in lily.
Here is a start of some docs, but just a little bit. I am working on it ...
http://www.xn--schne-noten-tfb.de/?tabs=3,1
I'm sorry that i don't have time to dig deeper, but my first
impression is that it's somewhat similar to OrchestralLily:
http://lac.linuxaudio.org/2010/papers/25.pdf
http://reinhold.kainhofer.com/orchestrallily/A-simple-example.html#A-simple-example
- it may give you some inspiration.
Yes, my template mechanism has a similar intention. And I think
OrchestraLily is a great tool.
But here are two points I wanted to solve differently:
1.: Orchestralily uses "normal" lilypond-variables to store and
organize the music. An advantage is a quite simple input.
But a question, I had and read several times on this list remains,
why and how to deal with the strict naming rules for lily-vars.
So I started storing music in scheme variables, to be able to use
vars with a name verse1. Then I thought about the tree-like
structure of music - Reinhold Kainhofer made a nice figure about
this in his paper.
2.: I want to use normal music-functions for templates, so
anything that fits in a music template, fits in a template. The
JSON-like template syntax for oly is not my taste ;-)
The music is stored in a hash-tree-structure, wich uses a
goops-class "tree" (found in lascm.scm):
--snip--
; ...
(define-class <tree> ()
(children #:accessor children #:init-thunk make-hash-table)
(key #:accessor key #:init-keyword #:key #:init-value 'node)
(value #:accessor value #:setter set-value! #:init-value #f)
)
(define-method (tree-set! (tree <tree>) (path <list>)
val)
(if (= (length path) 0)
(set! (value tree) val)
(let* ((ckey (car path))
(cpath (cdr path))
(child (hash-ref (children tree) ckey))
)
(if (not (is-a? child <tree>))
(begin (set! child (make <tree> #:key ckey))
(hash-set! (children tree) ckey child)
))
(tree-set! child cpath val)
))
val)
; ...
(define-method (tree-get-tree (tree <tree>) (path
<list>))
(if (= (length path) 0)
tree
(let* ((ckey (car path))
(cpath (cdr path))
(child (hash-ref (children tree) ckey))
)
(if (is-a? child <tree>)
(tree-get-tree child cpath)
#f)
)))
(define-method (tree-get (tree <tree>) (path <list>))
(let ((ctree (tree-get-tree tree path)))
(if (is-a? ctree <tree>) (value ctree) #f)))
; ...
--snip--
Hidden in a module '(lalily store) is a tree, to which music is
stored with the \putMusic command. Also there is a "current music
folder" var - I call it folder, because the term context is
already reserved in lily, and this tree forms a file-system-like
structure: \getMusic resolves the music stored in the tree in the
given path relative to the current folder.
A template is music-function with a defined signature also stored
in a tree:
\registerTemplate #'(generic) #(define-music-function (parser
location piece options)(list? list?)
; location parameter for error messages, if music is not found
(get-music piece location))
This tree-like structure allows several music pieces side by side.
A collection of songs might lead to a tree:
chor/alta-trinita/music/sop
chor/alta-trinita/text/sop
chor/alta-trinita/music/alt
chor/alta-trinita/text/alt
...
chor/horianna/music/sop
chor/hosianna/text/sop
...
Then, when calling a template for satb-choral music, you give
paths '(chor alta-trinita) and '(chor hosianna). This will fetch
the music from the store as needed.
If a template is called with \callTemplate, the current folder and
the current template are set accordingly on a path-stack and reset
when the template-function returns.
So writing a template means writing a scheme-function. That is not
simplifying input in the first place. And storing music means
using a scheme-list as a path. This also is not simplifying the
input - in the first shot.
But it divides input in storing music and calling a template. This
is an advantage for automation and it simplifies input, if one can
input scheme-values, which are used in several places in lily
(e.g. pairs in markup-overrides).
And a template can loop over the music - I use this in the
"choral-lied" templates to create a Lyrics-context for each verse.
Writing a template may get confusing, but if a template needed is
at hand, typesetting music can be reduced almost to input the
notes.
For a music folder, a template to use can be stored. A template
can call another template relative to its own path, so if you have
a template '(lead-sheet), it might recursively call a template
'(lead-sheet lyrics).
I also implemented some functions to automate the creation of the
actual scores. The one I use most times is \lalilyTest, wich
creates a bookpart with \layout- and \midi-block only if
parser-output matches the file referenced in location. So Output
is only generated if I compile the file directly. If this file is
included in another file, the "music store" is filled, but no
output is generated. So to test the input, I work directly on this
file, to generate a publication, I might use another file,
including all music needed and generating scores and bookparts
without midi.
There may also be more informations stored for a specific
'music-folder' like title, layout or paper, which will be used,
when generating a score or bookpart.
My template-collection is not a complete set, but it can be easily
extented for your own needs, if you are able to define a
music-function.
Generally speaking, i'd very much linke to simplify writing LilyPond
scores. Have you read my article "LilyPond's future"?
(http://news.lilynet.net/?The-LilyPond-Report-25&lang=en#lilypond_s_future)
...
\new
Staff = "tenor" { \music }
would be equivalent to:
\new
Staff = "tenor" \with {
\consists Ambitus_engraver
} {
\clef "G_8"
\set Staff.instrumentName = "Tenor"
\set Staff.shortInstrumentName = "T"
\set Staff.midiInstrument = "Choir Aahs"
\autoBeamOff
\music
}
...
I think, you will need one or two infos more, to distinguish the
multiple appearances of tenors.
But if you have a template #'(choral tenor), you can call it and
call it accordingly.
--snip--
\version "2.15.36"
\include "lalily.ly"
% if you have a template (this is not a simplification)
\registerTemplate #'(choral tenor) #(define-music-function (parser
location piece options)(list? list?)
#{
<<
\new Staff = "tenor" \with {
\consists Ambitus_engraver
} {
\clef "G_8"
\set Staff.instrumentName = "Tenor"
\set Staff.shortInstrumentName = "T"
\set Staff.midiInstrument = "Choir Aahs"
\autoBeamOff \dynamicUp
\new Voice = "tenor" \getMusic #'(music tenor)
}
\new Lyrics \lyricsto "tenor" \getMusic #'(text tenor)
>>
#})
% you can use it in these few lines (I think this is a
simplification, if one looses the fear regarding '#')
\setDefaultTemplate #'(my music) #'(choral tenor) #'()
\setTitle "My Music"
\putMusic #'(music tenor) \relative c' {
bes4 a c b
}
\putMusic #'(text tenor) \lyricmode {
B A C H
}
\lalilyTest
--snip--
The template might be found in either a file templates./myown/.ly
in the lalily folder of this bundle or a file lalily-templates.ly
in the current directory.
In the current templates.ly file are found:
#'(generic) returns the music found at the current path
#'(NOTFOUND) like generic, but also outputs a warning - used, when
template not found
#'(transpose) transpose the music, returned by named template -
used by \setTransposedTemplate pitch-from pitch-to #'(music path)
#'(template path) #'(options)
#'(lead-sheet) create lead-sheet uses: #'(meta) #'(chords)
#'(global) #'(melody) #'(lyrics /verse/)
#'(lead-sheet lyrics) called by #'(lead-sheet)
#'(choral group) create a choir staff with staffs named in options
(default is satb)
#'(choral group staff lyrics) create one choral staff with lyrics
- called by #'(choral group)
These expect music #'(noten voc) and #'(text voc)
The structure of the piece is defined in #'(meta)
Before each voice #'(global) is included
#'(choral lied staff) staff part
#'(choral lied staff lyrics) lyrics part
#'(choral lied satb4) layout music in 4 staves
#'(choral lied satb2) layout music in 2 staves with lyrics in the
middle
#'(choral lied satb2b) layout music in 2 staves with lyrics under
each stave
These #'(choral lied) templates look for #'(noten
/sop|alt|ten|bas/) and #'(text /verse/)
The options given need to be a list and most times are an a-list.
For example here a transposed one:
--snip--
\version "2.15.36"
\include "lalily.ly"
% options in an a-list, containing an a-list
\setTransposedTemplate c' bes #'(my music) #'(choral group)
#'((staffs . (
(sop . ((inst . "Sopran")
(sinst . "S")))
(alt . ((inst . "Alt")
(sinst . "A")))
(ten . ((clef . "G_8")
(inst . "Tenor")
(sinst . "T")))
(bas . ((clef . "bass")
(inst . "Bass")
(sinst . "B")))
)))
\putMusic #'(meta) { \key c \major \time 4/4 s1 \override
StaffGroup.SpanBar #'transparent = ##f \bar "|." }
\putMusic #'(global) { \autoBeamOff \dynamicUp }
\putMusic #'(noten sop) \relative c'' { c4 }
\putMusic #'(text sop) \lyricmode { do }
\putMusic #'(noten alt) \relative c'' { g4 }
\putMusic #'(text alt) \lyricmode { di }
\putMusic #'(noten ten) \relative c' { e4 }
\putMusic #'(text ten) \lyricmode { da }
\putMusic #'(noten bas) \relative c { c4 }
\putMusic #'(text bas) \lyricmode { dum }
\lalilyTest
--snip--
To make the options not to weird ... an a-list containing a-lists
... not nice and not *easy* ...
there is a command \setOption:
\setOption #'staffs #'(
(sop . ((inst . "Sopran")
(sinst . "S")))
(alt . ((inst . "Alt")
(sinst . "A")))
(ten . ((clef . "G_8")
(inst . "Tenor")
(sinst . "T")))
(bas . ((clef . "bass")
(inst . "Bass")
(sinst . "B")))
)
Still there is list-thing to write - that is not nice. So I will
probably rewrite the command \setOption #'(/path/)
Ok, enough for now ... so much to say about this, but only, if
there is anyone interested (Janek, you have to do your exams and
GSoC - so I don't expect you digging deep ;-) )
Cheers, Jan-Peter
_______________________________________________
lilypond-devel mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/lilypond-devel
|