Am So., 7. Okt. 2018 um 22:28 Uhr schrieb David Kastrup <d...@gnu.org>: > > Thomas Morley <thomasmorle...@gmail.com> writes: > > > Am So., 7. Okt. 2018 um 18:00 Uhr schrieb David Kastrup <d...@gnu.org>: > >> > >> Thomas Morley <thomasmorle...@gmail.com> writes: > >> > >> > If you have too much time, you may have a look at ‘scheme-engraver.ly’ > >> > from > >> > http://lilypond.org/doc/v2.13/input/regression/collated-files.html The > >> > newer file uses the great 'make-engraver'-macro (by David Kastrup). > >> > Otoh, this macro hides an engraver _is_ a list (which is obvious, if > >> > you look in the older file). > >> > >> An engraver is not a list, just like it isn't a string like > >> "Note_engraver". That's just how you _specify_ an engraver. If it's a > >> list, the Scheme_engraver type will be used for actually instantiating > >> an engraver (which is bound to a particular context), initialized using > >> the list contents. > > > > Hi David, > > > > I don't understand the subtleties. > > Could you elaborate a bit using the examples below. > > > > testI = > > #(list > > (cons 'initialize > > (lambda (trans) > > (write trans)))) > > > > testII = > > #(lambda (ctx) testI) > > > > \layout { > > \context { > > \Voice > > \consists #testI > > \consists #testII > > } > > } > > > > { R1 } > > > > testI is a list, testII a procedure using testI. > > Both return #<Translator Scheme_engraver >, though. > > They don't "return" the Translator but rather cause it to be created > when specified after \consists , like a Notehead_engraver instance is > created when specifying the string "Notehead_engraver". > > Basically there is the _specification_, \consists looks up (or in your > example creates) a suitable translator creator given a specification. > This translator creator is called with a suitable context to actually > create a translator instance when a context is instantiated, and that > creator instance is what you see listed rather unspecifically as > #<Translator Scheme_engraver > or #<Engraver Notehead_engraver> or > whatever else (to get to see those, create a suitable Scheme engraver > and look at the "source-engraver" argument of one of your grob > acknowledgers). > > One of the more problematic bits in history was making a > \consists/\removes pair work for ad-hoc defined engravers (rather than > those registered under a name) since at the time of the \removes call, > the translator creator did not carry information about its originating > expression (particularly so if its list expression was the result of > calling a lambda function) and creating a fresh translator creator from > the same expression led to a different translator creator unsuitable for > looking up the preexisting translator creator. > > -- > David Kastrup
Hi David, thanks a lot for your explanations. I try to repeat/summarize in my own words: Defining some code like #(define my-code ...) will not create a translator, before \consists has done its work in some context. But with (for example) \layout { \context { \Voice \consists #my-code } } an unnamed and unregistered translator is created. Assumed 'my-code' is suitable, ofcourse. Below some musing. Don't read unless you're very interested ;) So the two codings below will not create any engraver. testI = #(list (cons 'initialize (lambda (engraver) (newline) (pretty-print (list 'from-initialize: (cons 'engraver engraver))))) (cons 'acknowledgers (list (cons 'note-head-interface (lambda (engraver grob source-engraver) (pretty-print (list 'from-acknowledgers: (cons 'engraver engraver) (cons 'source-engraver source-engraver)))))))) testII = #(lambda (ctx) testI) But as soon as I do: \layout { \context { \Voice \consists #testI \consists #testII } } Two translators are created. Which can be checked with some code you once tailored for me http://lilypond.1069038.n5.nabble.com/catching-layout-content-tc213339.html Ofcourse adjusted to fit here, thanks again for it. #(define all-Voice-translators (assoc 'Voice (map (lambda (x) (if (ly:context-def? (cdr x)) (cons (car x) (ly:context-def-lookup (cdr x) 'consists)) x)) (sort (ly:module->alist (ly:output-def-scope $defaultlayout)) (lambda (p q) (symbol<? (car p) (car q))))))) #(newline) #(format #t "\nAll Voice-translator:\n~y" (cdr all-Voice-translators)) Though: #(pretty-print (ly:get-all-translators)) doesn't show them. Is this expected? %%%%% %%%%% Things are different for registered translators: #(ly:register-translator testI 'testI '((grobs-created . ()) (events-accepted . ()) (properties-read . ()) (properties-written . ()) (description . ""))) #(ly:register-translator testII 'testII '((grobs-created . ()) (events-accepted . ()) (properties-read . ()) (properties-written . ()) (description . ""))) Now (ly:get-all-translators) sees them as: testII: #<procedure #f (ctx)> testI: ((initialize . #<procedure #f (engraver)>) (acknowledgers (note-head-interface . #<procedure #f (engraver grob source-engraver)>))) Their names can be found with #(format #t "\nAll translator-names:\n~y" (sort (map ly:translator-name (ly:get-all-translators)) symbol<?)) So _registering_ them makes testI/II translators, \consists may look them up. Many thanks, Harm _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user