Re: Creating LilyPond Object Models
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 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
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
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
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
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
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
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
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
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
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-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