Re: Creating LilyPond Object Models

2015-05-01 Thread Paul Morris
 On Apr 26, 2015, at 11:16 AM, Paul Morris p...@paulwmorris.com wrote:
 
 In short, “listeners” respond to particular stream events:
 http://lilypond.org/doc/v2.18/Documentation/internals/music-classes
 while “acknowledgers” respond to particular grobs that have been “announced” 
 by other engravers (that created the grobs based on the stream events that 
 they “listened” to).  This process of acknowledging grobs happens through 
 grob interfaces:
 http://lilypond.org/doc/v2.18/Documentation/internals/graphical-object-interfaces

Something else I thought I’d add to this thread.  You can access the stream 
event that is the cause of a grob using (event-cause grob).  So in many cases 
that can be used instead of listeners.  An example is below.

Cheers,
-Paul

\version 2.18.2

#(define Some_custom_engraver
   (make-engraver
(acknowledgers
 ((key-signature-interface engraver grob source-engraver)
  (display grob) (newline)
  (display (event-cause grob)) (newline)
  ;; do something with key-signature grobs
  )
 ((note-head-interface engraver grob source-engraver)
  (display grob)(newline)
  (display (event-cause grob)) (newline)
  ;; do something with note-head grobs
  

\new Staff \with {
  \consists \Some_custom_engraver
}{
  \key c \major
  c'1
}


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-28 Thread Henry Law
Is there a co-operative effort forming on this?  I'm pretty much a 
novice ponder (and not even that on Lisp/Scheme ... I know-a nothing) 
but a reasonable technician and a fairly experienced technical 
writer/editor and I'd be happy to join in.


reply-to address is valid.

--

Henry LawManchester, England

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-27 Thread Paul Morris
Hi Urs,

It was inspired mostly by Carl’s post and working on Jianpu notation.  A 
tutorial on this is not a bad idea.  That said: 

(1) it would benefit from fitting into, or coming after, a broader overview of 
LilyPond like Carl has written

(2) it sounds like the way we create scheme engravers may change in the near 
future (based on David Kastrup’s post from earlier today) so probably best to 
wait until after that

(3) it might be good to add some more documentation of this to the official 
extending manual first.

For now maybe I’ll just add my example with comments to the LSR as a quick 
temporary measure.

Cheers,
-Paul


 On Apr 26, 2015, at 12:08 PM, Urs Liska u...@openlilylib.org wrote:
 
 Hi Paul,
 
 I don't know if that's in any way related to our talk yesterday or if it has 
 exclusively been triggered by Carl starting it. But this is very much a 
 skeleton of what I was talking about!
 It would be absolutely great if you could pour that into a tutorial on the 
 basics of writing Scheme engravers.
 
 Maybe users will usually not need this kind of information, but OTOH users 
 often need solutions that can be provided using this technique. So having a 
 slow-paced introductions may well lead to a greater number of people daring 
 to dive into these waters.
 
 Best
 Urs


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-27 Thread Urs Liska



Am 27.04.2015 um 23:24 schrieb Paul Morris:

Hi Urs,

It was inspired mostly by Carl’s post and working on Jianpu notation.  A 
tutorial on this is not a bad idea.  That said:

(1) it would benefit from fitting into, or coming after, a broader overview of 
LilyPond like Carl has written

(2) it sounds like the way we create scheme engravers may change in the near 
future (based on David Kastrup’s post from earlier today) so probably best to 
wait until after that

(3) it might be good to add some more documentation of this to the official 
extending manual first.

For now maybe I’ll just add my example with comments to the LSR as a quick 
temporary measure.


All agreed
Urs


Cheers,
-Paul



On Apr 26, 2015, at 12:08 PM, Urs Liska u...@openlilylib.org wrote:

Hi Paul,

I don't know if that's in any way related to our talk yesterday or if it has 
exclusively been triggered by Carl starting it. But this is very much a 
skeleton of what I was talking about!
It would be absolutely great if you could pour that into a tutorial on the 
basics of writing Scheme engravers.

Maybe users will usually not need this kind of information, but OTOH users 
often need solutions that can be provided using this technique. So having a slow-paced 
introductions may well lead to a greater number of people daring to dive into these 
waters.

Best
Urs



___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-26 Thread Urs Liska

Hi Paul,

I don't know if that's in any way related to our talk yesterday or if it 
has exclusively been triggered by Carl starting it. But this is very 
much a skeleton of what I was talking about!
It would be absolutely great if you could pour that into a tutorial on 
the basics of writing Scheme engravers.


Maybe users will usually not need this kind of information, but OTOH 
users often need solutions that can be provided using this technique. So 
having a slow-paced introductions may well lead to a greater number of 
people daring to dive into these waters.


Best
Urs

Am 26.04.2015 um 17:16 schrieb Paul Morris:

Thanks Carl, Johannes, and David for working on this overview.


On Apr 23, 2015, at 4:25 AM, Johannes Rohrer s...@johannesrohrer.de wrote:

Translators selectively (based on assigned Event Classes) accept
Events from the stream that were sorted into their context and process
them. Typically, they will produce output objects (for Engravers:
layout objects, aka Grobs; for Performers: Audio_items) and announce
these. Other Translators can acknowledge certain types of announced
objects to process them further.


Thanks especially for this insight.  After a little digging into the source code I now 
understand the difference between “listeners” and “acknowledgers” in a scheme engraver 
created with the make-engraver macro.

In short, “listeners” respond to particular stream events:
http://lilypond.org/doc/v2.18/Documentation/internals/music-classes
while “acknowledgers” respond to particular grobs that have been “announced” by 
other engravers (that created the grobs based on the stream events that they 
“listened” to).  This process of acknowledging grobs happens through grob 
interfaces:
http://lilypond.org/doc/v2.18/Documentation/internals/graphical-object-interfaces

Basically like this:

[stream event] — [engraver A with listener] — [grob]

[grob] — [engraver B with acknowledger] — […]

but engravers can have both listeners and acknowledgers, and more than one of 
each.  Here’s an example:

%%
\version 2.18.2

#(define Some_custom_engraver
  (make-engraver
   (listeners
((key-change-event engraver event)
 (display event)(newline)
 ;; do something with key-change-event events
 )
((note-event engraver event)
 (display event)(newline)
 ;; do something with note-event events
 ))
(acknowledgers
 ((key-signature-interface engraver grob source-engraver)
  (display grob)(newline)
  ;; do something with key-signature grobs
  )
((note-head-interface engraver grob source-engraver)
(display grob)(newline)
;; do something with note-head grobs


\new Staff \with {
   \consists \Some_custom_engraver
}{
   \key c \major
   c'1
}
%%

As far as I can tell the order in which engravers are “consisted” in their 
given context determines the order in which they receive the incoming events 
and grobs.

It’s probably *very* rare that a user would ever need to create an engraver and 
need to know about listeners and acknowledgers.

For anyone wanting to go further there’s more that I don’t understand 
(initialize, start-translation-timestep, process-music, etc.), to quote from 
the doc string of the make-engraver macro at the bottom of scm/output-lib.scm:

Symbols mapping to a function would be @code{initialize},
@code{start-translation-timestep}, @code{process-music},
@code{process-acknowledged}, @code{stop-translation-timestep}, and
@code{finalize}.  Symbols mapping to another alist specified in the
same manner are @code{listeners} with the subordinate symbols being
event classes, and @code{acknowledgers} and @code{end-acknowledgers}
with the subordinate symbols being interfaces.”

Let me know if I’ve misrepresented anything.

Thanks again,
-Paul


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user




--
Urs Liska
www.openlilylib.org

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-26 Thread Paul Morris
Thanks Carl, Johannes, and David for working on this overview.

 On Apr 23, 2015, at 4:25 AM, Johannes Rohrer s...@johannesrohrer.de wrote:
 
 Translators selectively (based on assigned Event Classes) accept
 Events from the stream that were sorted into their context and process
 them. Typically, they will produce output objects (for Engravers:
 layout objects, aka Grobs; for Performers: Audio_items) and announce
 these. Other Translators can acknowledge certain types of announced
 objects to process them further.

Thanks especially for this insight.  After a little digging into the source 
code I now understand the difference between “listeners” and “acknowledgers” in 
a scheme engraver created with the make-engraver macro.  

In short, “listeners” respond to particular stream events:
http://lilypond.org/doc/v2.18/Documentation/internals/music-classes
while “acknowledgers” respond to particular grobs that have been “announced” by 
other engravers (that created the grobs based on the stream events that they 
“listened” to).  This process of acknowledging grobs happens through grob 
interfaces:
http://lilypond.org/doc/v2.18/Documentation/internals/graphical-object-interfaces

Basically like this:

[stream event] — [engraver A with listener] — [grob]

[grob] — [engraver B with acknowledger] — […]

but engravers can have both listeners and acknowledgers, and more than one of 
each.  Here’s an example:

%%
\version 2.18.2

#(define Some_custom_engraver
 (make-engraver
  (listeners
   ((key-change-event engraver event)
(display event)(newline)
;; do something with key-change-event events
)
   ((note-event engraver event)
(display event)(newline)
;; do something with note-event events
))
   (acknowledgers
((key-signature-interface engraver grob source-engraver)
 (display grob)(newline)
 ;; do something with key-signature grobs
 )
   ((note-head-interface engraver grob source-engraver)
   (display grob)(newline)
   ;; do something with note-head grobs
   

\new Staff \with {
  \consists \Some_custom_engraver
}{
  \key c \major
  c'1
}
%%

As far as I can tell the order in which engravers are “consisted” in their 
given context determines the order in which they receive the incoming events 
and grobs.  

It’s probably *very* rare that a user would ever need to create an engraver and 
need to know about listeners and acknowledgers.  

For anyone wanting to go further there’s more that I don’t understand 
(initialize, start-translation-timestep, process-music, etc.), to quote from 
the doc string of the make-engraver macro at the bottom of scm/output-lib.scm:

Symbols mapping to a function would be @code{initialize},
@code{start-translation-timestep}, @code{process-music},
@code{process-acknowledged}, @code{stop-translation-timestep}, and
@code{finalize}.  Symbols mapping to another alist specified in the
same manner are @code{listeners} with the subordinate symbols being
event classes, and @code{acknowledgers} and @code{end-acknowledgers}
with the subordinate symbols being interfaces.”

Let me know if I’ve misrepresented anything.

Thanks again,
-Paul


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-26 Thread Simon Albrecht

That’s really insightful. Thank you!
Regards, Simon

Am 26.04.2015 um 17:16 schrieb Paul Morris:

Thanks Carl, Johannes, and David for working on this overview.


On Apr 23, 2015, at 4:25 AM, Johannes Rohrer s...@johannesrohrer.de wrote:

Translators selectively (based on assigned Event Classes) accept
Events from the stream that were sorted into their context and process
them. Typically, they will produce output objects (for Engravers:
layout objects, aka Grobs; for Performers: Audio_items) and announce
these. Other Translators can acknowledge certain types of announced
objects to process them further.

Thanks especially for this insight.  After a little digging into the source code I now 
understand the difference between “listeners” and “acknowledgers” in a scheme engraver 
created with the make-engraver macro.

In short, “listeners” respond to particular stream events:
http://lilypond.org/doc/v2.18/Documentation/internals/music-classes
while “acknowledgers” respond to particular grobs that have been “announced” by 
other engravers (that created the grobs based on the stream events that they 
“listened” to).  This process of acknowledging grobs happens through grob 
interfaces:
http://lilypond.org/doc/v2.18/Documentation/internals/graphical-object-interfaces

Basically like this:

[stream event] — [engraver A with listener] — [grob]

[grob] — [engraver B with acknowledger] — […]

but engravers can have both listeners and acknowledgers, and more than one of 
each.  Here’s an example:

%%
\version 2.18.2

#(define Some_custom_engraver
  (make-engraver
   (listeners
((key-change-event engraver event)
 (display event)(newline)
 ;; do something with key-change-event events
 )
((note-event engraver event)
 (display event)(newline)
 ;; do something with note-event events
 ))
(acknowledgers
 ((key-signature-interface engraver grob source-engraver)
  (display grob)(newline)
  ;; do something with key-signature grobs
  )
((note-head-interface engraver grob source-engraver)
(display grob)(newline)
;; do something with note-head grobs


\new Staff \with {
   \consists \Some_custom_engraver
}{
   \key c \major
   c'1
}
%%

As far as I can tell the order in which engravers are “consisted” in their 
given context determines the order in which they receive the incoming events 
and grobs.

It’s probably *very* rare that a user would ever need to create an engraver and 
need to know about listeners and acknowledgers.

For anyone wanting to go further there’s more that I don’t understand 
(initialize, start-translation-timestep, process-music, etc.), to quote from 
the doc string of the make-engraver macro at the bottom of scm/output-lib.scm:

Symbols mapping to a function would be @code{initialize},
@code{start-translation-timestep}, @code{process-music},
@code{process-acknowledged}, @code{stop-translation-timestep}, and
@code{finalize}.  Symbols mapping to another alist specified in the
same manner are @code{listeners} with the subordinate symbols being
event classes, and @code{acknowledgers} and @code{end-acknowledgers}
with the subordinate symbols being interfaces.”

Let me know if I’ve misrepresented anything.

Thanks again,
-Paul


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user



___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-26 Thread Anthonys Lists

On 26/04/2015 17:08, Urs Liska wrote:

Hi Paul,

I don't know if that's in any way related to our talk yesterday or if 
it has exclusively been triggered by Carl starting it. But this is 
very much a skeleton of what I was talking about!
It would be absolutely great if you could pour that into a tutorial on 
the basics of writing Scheme engravers.


Maybe users will usually not need this kind of information, but OTOH 
users often need solutions that can be provided using this technique. 
So having a slow-paced introductions may well lead to a greater number 
of people daring to dive into these waters. 


Don't forget, also, that need to know may be great in wartime, to 
prevent secrets leaking, but it's not good for learning. And certainly, 
I find the best way of learning is to have stuff aimed at what I'm 
trying to do, but is full of snippets of bits of information that go 
that little bit deeper. That way, I have the incentive to study the 
teaching material, but it's actually teaching me at a deeper level than 
I need - so I can then progress to the next level with greater ease. So 
probably this information would work well as a footnote in a user 
tutorial - when it talks superficially about engravers it could point 
them at this somewhat deeper explanation of what an engraver actually is.


Cheers,
Wol

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-26 Thread David Nalesnik
On Sun, Apr 26, 2015 at 11:08 AM, Urs Liska u...@openlilylib.org wrote:


 Am 26.04.2015 um 17:16 schrieb Paul Morris:



 but engravers can have both listeners and acknowledgers, and more than
 one of each.


You can also use an end-acknowledger to catch the end of a spanner.



 It’s probably *very* rare that a user would ever need to create an
 engraver and need to know about listeners and acknowledgers.


But it's certainly helpful to know at least something so you don't have the
sense that you're blindly filling in slots :)



 For anyone wanting to go further there’s more that I don’t understand
 (initialize, start-translation-timestep, process-music, etc.), to quote
 from the doc string of the make-engraver macro at the bottom of
 scm/output-lib.scm:

 Symbols mapping to a function would be @code{initialize},
 @code{start-translation-timestep}, @code{process-music},
 @code{process-acknowledged}, @code{stop-translation-timestep}, and
 @code{finalize}.  Symbols mapping to another alist specified in the
 same manner are @code{listeners} with the subordinate symbols being
 event classes, and @code{acknowledgers} and @code{end-acknowledgers}
 with the subordinate symbols being interfaces.”


There is some material about these methods from a C++ standpoint in the
Contributor's Guide:
http://lilypond.org/doc/v2.19/Documentation/contributor/engraver-tutorial

Thanks!  This is all very useful.

David
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-24 Thread Carl Sorensen

On 4/24/15 3:58 PM, Simon Albrecht simon.albre...@mail.de wrote:

Hello Carl,

this is a good approach. Am I right in assuming that this is a
boiled-down, low-threshold version of the relevant parts in Erik
Sandberg¹s masters thesis(1) referenced in CG 10.1?


Perhaps.  It certainly should be compatible with that thesis.  But I'm
just trying to get a readily-understood model of key logical concepts
about lilypond that will help users (not developers) understand how to
figure out a tweak/override.

I made that up out of whole cloth, from my own understanding.

Thanks,

Carl




___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-24 Thread Simon Albrecht

Hello Carl,

this is a good approach. Am I right in assuming that this is a 
boiled-down, low-threshold version of the relevant parts in Erik 
Sandberg’s masters thesis(1) referenced in CG 10.1?


Yours, Simon

(1) http://lilypond.org/website/pdf/thesis-erik-sandberg.pdf

Am 23.04.2015 um 01:29 schrieb Carl Sorensen:

David Elaine Alt finds that a major obstacle to understanding lilypond is
the lack of a comprehensive (and/or comprehensible) object model.  The
question was asked: Does anyone really understand what a Voice is?

I think there are two levels at which object models need to be understood:
the user level and the developer level.  Users only need to know *what*
the object is; developers need to know *how* the object is implemented as
well.

I think I have a decent lilypond object model from the user level, and a
partial model (with some holes remaining) at the developer level.

I thought I'd raise the issues here, with the idea that maybe we can
develop some useful descriptions of the lilypond object model that can
help users.

There is a description of contexts and engravers in the Learning Manual
(Section 3.3), another one in the Notation Reference (Section 5.1), and a
third in the Contributor's Guide (Section 10.1).  Rather than try to edit
any of those, I'd like to propose my mental model.   Maybe we can get to
something simpler that will help explain things (but maybe not).

So here we go -- comments and suggestions are welcome.

%%% Start of model

Contexts are LilyPond objects that contain properties, music expressions,
and translators.  Some contexts, like Score and Staff, can contain other
contexts as well.  Other contexts, like Voice, are bottom contexts and
cannot contain other
contexts.

Contexts are responsible for controlling the output (printed or midi) of
the music they contain.  They do this by calling translators in the
environment of the context properties.

Translators are program elements that convert music expressions to output.
  Engravers are translators that create printed output.  Performers are
translators that create midi output.

Translators examine the music expressions that are contained in the
context, and create output elements.  For the case of engravers (which
create graphical output), the output elements are grobs.  The grobs have
properties that are used to create their appearance on the page.

After all the grobs are created, the spacing engine takes over and tries
to make an esthetically pleasing layout that fits in all the grobs.  These
are then committed to the page.

If we want to change the layout, we need to change the properties of
either grobs or contexts.  Changing these properties affects how the
layout engine tries to pack the grobs together.


  End of model

In my mind, this model explains how LilyPond works well enough that I can
make happen what I need to make happen.

If I've got something wrong, please let me know.  If you have questions
about this model, please let me know.

If you think this model isn't complete enough, please help me to
understand why.

Thanks,

Carl


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user



___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread PMA

On the piano I can play/think in voices or not.

Sorry, I've lost track as to who wrote that.
But just in case -- one might consider the
(single-musician) pianist accompanying a
(4-voiced) sunday school hymn.

Pete

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Kieren MacMillan
Hi Urs,

 If, as a musician, I get confused by thinking of a voice context I can't 
 use any technology of notating, including pen and paper.
 But if I can abstract my instrument - the piano - away and realize it uses 
 multiple voices, I can use that concept for all notation programs. I think 
 this isn't a problem with LilyPond.

As with so many of these issues, both on the list and in the documentation, 
this is a semantic issue that may never be adequately solved.

Cheers,
Kieren.


Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: i...@kierenmacmillan.info


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Marc Hohl

Am 23.04.2015 um 01:29 schrieb Carl Sorensen:

David Elaine Alt finds that a major obstacle to understanding lilypond is
the lack of a comprehensive (and/or comprehensible) object model.  The
question was asked: Does anyone really understand what a Voice is?

I think there are two levels at which object models need to be understood:
the user level and the developer level.  Users only need to know *what*
the object is; developers need to know *how* the object is implemented as
well.

I think I have a decent lilypond object model from the user level, and a
partial model (with some holes remaining) at the developer level.

I thought I'd raise the issues here, with the idea that maybe we can
develop some useful descriptions of the lilypond object model that can
help users.

There is a description of contexts and engravers in the Learning Manual
(Section 3.3), another one in the Notation Reference (Section 5.1), and a
third in the Contributor's Guide (Section 10.1).  Rather than try to edit
any of those, I'd like to propose my mental model.   Maybe we can get to
something simpler that will help explain things (but maybe not).

So here we go -- comments and suggestions are welcome.

%%% Start of model

Contexts are LilyPond objects that contain properties, music expressions,
and translators.  Some contexts, like Score and Staff, can contain other
contexts as well.  Other contexts, like Voice, are bottom contexts and
cannot contain other
contexts.

Contexts are responsible for controlling the output (printed or midi) of
the music they contain.  They do this by calling translators in the
environment of the context properties.

Translators are program elements that convert music expressions to output.
  Engravers are translators that create printed output.  Performers are
translators that create midi output.

Translators examine the music expressions that are contained in the
context, and create output elements.  For the case of engravers (which
create graphical output), the output elements are grobs.  The grobs have
properties that are used to create their appearance on the page.

After all the grobs are created, the spacing engine takes over and tries
to make an esthetically pleasing layout that fits in all the grobs.  These
are then committed to the page.

If we want to change the layout, we need to change the properties of
either grobs or contexts.  Changing these properties affects how the
layout engine tries to pack the grobs together.


  End of model


I like it! If this information were available at the time I started 
using lilypond, everything would have been *much* easier!


Thanks for sharing,

Marc


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Carl Sorensen


On 4/23/15 3:26 AM, Urs Liska u...@openlilylib.org wrote:


I think this is an excellent approach. Actually this is exactly one kind
of information that is lacking in the documentation (or at least not
accessible to the user). If one has the chance to get such a model it is
much more easy to guess where to find information or to make sense of
snippets of information found anywhere.

Combined with some of the comments this should really be made visible,
although I'm not sure where. Maybe even in the Learning Manual.

That's precisely why I'm doing this.  I want to make sure that my mental
models are 
 
a) Useful to users, and
b) Correct enough to not mislead users

Once I can get that straight, I plan to put it into the docs.

Thanks,

Carl


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Urs Liska



Am 23.04.2015 um 14:50 schrieb Kieren MacMillan:

Hi Urs,


On the piano I can play/think in voices or not.

But that’s exactly my point: you’re a single “musician”.
(I think everyone would agree on that semantic.)
But you can play multiple “voices”.

Hence “musician” != “voice”, and to try to conflate the two ideas (as one of 
the replies did) is potentially confusing.


Yes, but that's a confusion that is not related to LilyPond at all.
Urs

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Carl Sorensen
On 4/23/15 1:25 AM, Johannes Rohrer s...@johannesrohrer.de wrote:

* 2015-04-23 01:29 +0200:
 Translators are program elements that convert music expressions to
output.
  Engravers are translators that create printed output.  Performers are
 translators that create midi output.
 
 Translators examine the music expressions that are contained in the
 context, and create output elements.  For the case of engravers (which
 create graphical output), the output elements are grobs.  The grobs have
 properties that are used to create their appearance on the page.

This is very simplified.

Snip excellent explanation provided by Johannes

This is mostly undocumented I believe, although there are some
snippets in the contributor's guide

http://lilypond.org/doc/v2.19/Documentation/contributor/overview-of-lilyp
ond-architecture

and some helpful scattered mailing list posts.


Thank you very much for your addition.  It clarified some issues that I
understood in a muddy way, and so I didn't include them in my object
model.  I knew that I had left out iterators (it was a choice I made
because the user never sets iterator properties).

I'll get an updated description put together.

Thanks,

Carl


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Kieren MacMillan
Hi Urs,

 Hence “musician” != “voice”, and to try to conflate the two ideas (as one of 
 the replies did) is potentially confusing.
 
 Yes, but that's a confusion that is not related to LilyPond at all.

That confusion immediately becomes related to Lilypond if, as was 
suggested/implied, her documentation might say “Think of a Voice context as a 
‘musician’.”

Cheers,
Kieren.



Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: i...@kierenmacmillan.info


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Johannes Rohrer
* 2015-04-23 01:29 +0200:
 Translators are program elements that convert music expressions to output.
  Engravers are translators that create printed output.  Performers are
 translators that create midi output.
 
 Translators examine the music expressions that are contained in the
 context, and create output elements.  For the case of engravers (which
 create graphical output), the output elements are grobs.  The grobs have
 properties that are used to create their appearance on the page.

This is very simplified. Translators do not operate on music expressions
directly, and music expressions are not themselves contained in
contexts. This level of understanding may get you relatively far as a
user, but is not even sufficient for reading the Internals Reference.

It has been a while since I last tried to wrap my head around this, but
from memory:

Program elements called Iterators turn music expressions into a
time-ordered stream of Events sorted into contexts. The different types
of Events produced at this stage are listed here:

http://lilypond.org/doc/v2.18/Documentation/internals/music-expressions

Events are categorized in a hierarchy of Event Classes. These are listed
here:

http://lilypond.org/doc/v2.18/Documentation/internals/music-classes

Translators selectively (based on assigned Event Classes) accept
Events from the stream that were sorted into their context and process
them. Typically, they will produce output objects (for Engravers:
layout objects, aka Grobs; for Performers: Audio_items) and announce
these. Other Translators can acknowledge certain types of announced
objects to process them further.

This is mostly undocumented I believe, although there are some
snippets in the contributor's guide

http://lilypond.org/doc/v2.19/Documentation/contributor/overview-of-lilypond-architecture

and some helpful scattered mailing list posts.


Best regards,

Johannes

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Urs Liska



Am 23.04.2015 um 02:05 schrieb Kieren MacMillan:

Hi Harm,


Speaking as a user, I always thought about a Voice like a
_musician_, never had problems with that thinking.

But (he says, taking on the role of the average newbie user) a pianist is a 
musician.
So why can’t I write all of the piano music I need that musician to play in a 
single Voice?
;)

Ultimately, if you understand a MIDI “voice”, then you understand a Lilypond 
“Voice”.
If you don’t, I’m not sure there’s a real-world analogy that can be drawn 
clearly.


Hm, I'm not so sure about that.
As a pianist I do have a notion of voice that's quite close to LilyPond's.
On the piano I can play/think in voices or not. If I don't play voiced 
(i.e. polyphonic) music a usually can translate that to chords in LilyPond.
And with all these inconsistencies in piano writing that are so hard to 
translate to LilyPond I have already grasped before that this is because 
of the piano's abuse of voices.
I still often curse LilyPond that it can't mimick this abuse (for 
example by allowing slurs to go from one voice to another), but it's not 
an issue with the *concept* of Voice.


Urs



Cheers,
Kieren.


Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: i...@kierenmacmillan.info


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user



___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Urs Liska



Am 23.04.2015 um 01:29 schrieb Carl Sorensen:

David Elaine Alt finds that a major obstacle to understanding lilypond is
the lack of a comprehensive (and/or comprehensible) object model.  The
question was asked: Does anyone really understand what a Voice is?

I think there are two levels at which object models need to be understood:
the user level and the developer level.  Users only need to know *what*
the object is; developers need to know *how* the object is implemented as
well.

I think I have a decent lilypond object model from the user level, and a
partial model (with some holes remaining) at the developer level.

I thought I'd raise the issues here, with the idea that maybe we can
develop some useful descriptions of the lilypond object model that can
help users.

There is a description of contexts and engravers in the Learning Manual
(Section 3.3), another one in the Notation Reference (Section 5.1), and a
third in the Contributor's Guide (Section 10.1).  Rather than try to edit
any of those, I'd like to propose my mental model.   Maybe we can get to
something simpler that will help explain things (but maybe not).

So here we go -- comments and suggestions are welcome.

%%% Start of model

Contexts are LilyPond objects that contain properties, music expressions,
and translators.  Some contexts, like Score and Staff, can contain other
contexts as well.  Other contexts, like Voice, are bottom contexts and
cannot contain other
contexts.

Contexts are responsible for controlling the output (printed or midi) of
the music they contain.  They do this by calling translators in the
environment of the context properties.

Translators are program elements that convert music expressions to output.
  Engravers are translators that create printed output.  Performers are
translators that create midi output.

Translators examine the music expressions that are contained in the
context, and create output elements.  For the case of engravers (which
create graphical output), the output elements are grobs.  The grobs have
properties that are used to create their appearance on the page.

After all the grobs are created, the spacing engine takes over and tries
to make an esthetically pleasing layout that fits in all the grobs.  These
are then committed to the page.

If we want to change the layout, we need to change the properties of
either grobs or contexts.  Changing these properties affects how the
layout engine tries to pack the grobs together.


  End of model

In my mind, this model explains how LilyPond works well enough that I can
make happen what I need to make happen.

If I've got something wrong, please let me know.  If you have questions
about this model, please let me know.

If you think this model isn't complete enough, please help me to
understand why.

Thanks,

Carl


I think this is an excellent approach. Actually this is exactly one kind 
of information that is lacking in the documentation (or at least not 
accessible to the user). If one has the chance to get such a model it is 
much more easy to guess where to find information or to make sense of 
snippets of information found anywhere.


Combined with some of the comments this should really be made visible, 
although I'm not sure where. Maybe even in the Learning Manual.


Urs



___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user



___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Kieren MacMillan
Hi Urs,

 On the piano I can play/think in voices or not.

But that’s exactly my point: you’re a single “musician”.
(I think everyone would agree on that semantic.)
But you can play multiple “voices”.

Hence “musician” != “voice”, and to try to conflate the two ideas (as one of 
the replies did) is potentially confusing.

Cheers,
Kieren.


Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: i...@kierenmacmillan.info


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread David Nalesnik
On Thu, Apr 23, 2015 at 3:25 AM, Johannes Rohrer s...@johannesrohrer.de
wrote:

 * 2015-04-23 01:29 +0200:
  Translators are program elements that convert music expressions to
 output.
   Engravers are translators that create printed output.  Performers are
  translators that create midi output.
 
  Translators examine the music expressions that are contained in the
  context, and create output elements.  For the case of engravers (which
  create graphical output), the output elements are grobs.  The grobs have
  properties that are used to create their appearance on the page.

 This is very simplified. Translators do not operate on music expressions
 directly, and music expressions are not themselves contained in
 contexts. This level of understanding may get you relatively far as a
 user, but is not even sufficient for reading the Internals Reference.

 It has been a while since I last tried to wrap my head around this, but
 from memory:

 Program elements called Iterators turn music expressions into a
 time-ordered stream of Events sorted into contexts. The different types
 of Events produced at this stage are listed here:

 http://lilypond.org/doc/v2.18/Documentation/internals/music-expressions



The structure of LilyPond in this regard is thoroughly confusing, and the
Internals Reference does not clarify the relationships.  The naming is
particularly unhelpful for trying to figure out what's going on.  (I don't
want to go into that as it will confuse the goal of this thread!)

Lately, I've had occasion to try to piece together what's going on, so I'd
like to amend part of your helpful description.

This list you link to above not what is produced by iterators.  It
represents what is *fed* to the iterators, which convert music events, like
NoteEvent, DynamicEvent, etc., into stream events.  Stream events are what
is sent along to the translators, as you describe,  The list at

http://lilypond.org/doc/v2.18/Documentation/internals/music-classes

lists the various sorts of stream events which are input for translators.

There is a (admirably well-hidden)  section of the Contributor's Guide
which touches on this.  See

http://lilypond.org/doc/v2.19/Documentation/contributor/articulations-on-eventchord

If you look at the output of
\displayMusic { c' }
or
#(display #{ { c' } #})

you will see (as I understand it) the output of the parser.  In it you will
see NoteEvent.  It is this sort of expression which forms the input at the
iteration stage, which will derive stream-events which will be sent to
relevant contexts (created at this stage, if necessary).

Caveat: This all is mostly of interest from a developer's perspective!  It
is not something which a user need know to use LilyPond effectively.

--David
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread Urs Liska



Am 23.04.2015 um 15:13 schrieb Kieren MacMillan:

Hi Urs,


Hence “musician” != “voice”, and to try to conflate the two ideas (as one of 
the replies did) is potentially confusing.

Yes, but that's a confusion that is not related to LilyPond at all.

That confusion immediately becomes related to Lilypond if, as was 
suggested/implied, her documentation might say “Think of a Voice context as a 
‘musician’.”


Hm.
If, as a musician, I get confused by thinking of a voice context I 
can't use any technology of notating, including pen and paper.
But if I can abstract my instrument - the piano - away and realize it 
uses multiple voices, I can use that concept for all notation programs. 
I think this isn't a problem with LilyPond.


Urs

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-23 Thread David Nalesnik
On Thu, Apr 23, 2015 at 8:22 AM, David Nalesnik david.nales...@gmail.com
wrote:


 The list at

 http://lilypond.org/doc/v2.18/Documentation/internals/music-classes

 lists the various sorts of stream events which are input for translators.


Simply renaming this section Stream Events with an introductory blurb
would save a world of trouble for people investigating this stuff!

DN
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-22 Thread Kieren MacMillan
Hi Harm,

 Speaking as a user, I always thought about a Voice like a
 _musician_, never had problems with that thinking.

But (he says, taking on the role of the average newbie user) a pianist is a 
musician.
So why can’t I write all of the piano music I need that musician to play in a 
single Voice?
;)

Ultimately, if you understand a MIDI “voice”, then you understand a Lilypond 
“Voice”.
If you don’t, I’m not sure there’s a real-world analogy that can be drawn 
clearly.

Cheers,
Kieren.


Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: i...@kierenmacmillan.info


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-22 Thread Zoran Kesic
Carl Sorensen c_sorensen at byu.edu writes:


 %%% Start of model
 
 Contexts are LilyPond objects that contain properties, music expressions,
 and translators.  Some contexts, like Score and Staff, can contain other
 contexts as well.  Other contexts, like Voice, are bottom contexts and
 cannot contain other
 contexts.
 
 Contexts are responsible ...
 ...
 ...
 ...
   End of model
 

Hi Carl,

As a newbie user, I find your example very helpful and, at the same time,
very concise!

Cheers,
Zoran



___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Creating LilyPond Object Models

2015-04-22 Thread Carl Sorensen
David Elaine Alt finds that a major obstacle to understanding lilypond is
the lack of a comprehensive (and/or comprehensible) object model.  The
question was asked: Does anyone really understand what a Voice is?

I think there are two levels at which object models need to be understood:
the user level and the developer level.  Users only need to know *what*
the object is; developers need to know *how* the object is implemented as
well.

I think I have a decent lilypond object model from the user level, and a
partial model (with some holes remaining) at the developer level.

I thought I'd raise the issues here, with the idea that maybe we can
develop some useful descriptions of the lilypond object model that can
help users.

There is a description of contexts and engravers in the Learning Manual
(Section 3.3), another one in the Notation Reference (Section 5.1), and a
third in the Contributor's Guide (Section 10.1).  Rather than try to edit
any of those, I'd like to propose my mental model.   Maybe we can get to
something simpler that will help explain things (but maybe not).

So here we go -- comments and suggestions are welcome.

%%% Start of model

Contexts are LilyPond objects that contain properties, music expressions,
and translators.  Some contexts, like Score and Staff, can contain other
contexts as well.  Other contexts, like Voice, are bottom contexts and
cannot contain other
contexts.

Contexts are responsible for controlling the output (printed or midi) of
the music they contain.  They do this by calling translators in the
environment of the context properties.

Translators are program elements that convert music expressions to output.
 Engravers are translators that create printed output.  Performers are
translators that create midi output.

Translators examine the music expressions that are contained in the
context, and create output elements.  For the case of engravers (which
create graphical output), the output elements are grobs.  The grobs have
properties that are used to create their appearance on the page.

After all the grobs are created, the spacing engine takes over and tries
to make an esthetically pleasing layout that fits in all the grobs.  These
are then committed to the page.

If we want to change the layout, we need to change the properties of
either grobs or contexts.  Changing these properties affects how the
layout engine tries to pack the grobs together.


  End of model

In my mind, this model explains how LilyPond works well enough that I can
make happen what I need to make happen.

If I've got something wrong, please let me know.  If you have questions
about this model, please let me know.

If you think this model isn't complete enough, please help me to
understand why.

Thanks,

Carl


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Creating LilyPond Object Models

2015-04-22 Thread Thomas Morley
2015-04-23 1:29 GMT+02:00 Carl Sorensen c_soren...@byu.edu:
 David Elaine Alt finds that a major obstacle to understanding lilypond is
 the lack of a comprehensive (and/or comprehensible) object model.  The
 question was asked: Does anyone really understand what a Voice is?

Speaking as a user, I always thought about a Voice like a
_musician_, never had problems with that thinking.


 I think there are two levels at which object models need to be understood:
 the user level and the developer level.  Users only need to know *what*
 the object is; developers need to know *how* the object is implemented as
 well.

 I think I have a decent lilypond object model from the user level, and a
 partial model (with some holes remaining) at the developer level.

 I thought I'd raise the issues here, with the idea that maybe we can
 develop some useful descriptions of the lilypond object model that can
 help users.

 There is a description of contexts and engravers in the Learning Manual
 (Section 3.3), another one in the Notation Reference (Section 5.1), and a
 third in the Contributor's Guide (Section 10.1).  Rather than try to edit
 any of those, I'd like to propose my mental model.   Maybe we can get to
 something simpler that will help explain things (but maybe not).

 So here we go -- comments and suggestions are welcome.

 %%% Start of model

 Contexts are LilyPond objects that contain properties, music expressions,
 and translators.  Some contexts, like Score and Staff, can contain other
 contexts as well.  Other contexts, like Voice, are bottom contexts and
 cannot contain other
 contexts.

 Contexts are responsible for controlling the output (printed or midi) of
 the music they contain.  They do this by calling translators in the
 environment of the context properties.

 Translators are program elements that convert music expressions to output.
  Engravers are translators that create printed output.  Performers are
 translators that create midi output.

 Translators examine the music expressions that are contained in the
 context, and create output elements.  For the case of engravers (which
 create graphical output), the output elements are grobs.  The grobs have
 properties that are used to create their appearance on the page.

 After all the grobs are created, the spacing engine takes over and tries
 to make an esthetically pleasing layout that fits in all the grobs.  These
 are then committed to the page.

 If we want to change the layout, we need to change the properties of
 either grobs or contexts.  Changing these properties affects how the
 layout engine tries to pack the grobs together.


   End of model

Great!


 In my mind, this model explains how LilyPond works well enough that I can
 make happen what I need to make happen.

 If I've got something wrong, please let me know.  If you have questions
 about this model, please let me know.

 If you think this model isn't complete enough, please help me to
 understand why.

There are a few other possible things coming into play. Toplevel
settings like global-staff-size etc or paper-settings (fixed and
variable) like two-sided or system-system-spacing etc


 Thanks,

 Carl




Thanks,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user