@snippets
@lilypondfile[verbatim,lilyquote,ragged-right,texidoc,doctitle]
-{dot-count-override.ly}
+{changing-the-number-of-augmentation-dots-per-note.ly}
@seealso
--- /dev/null
+%% Translation of GIT committish: 0b55335aeca1de539bf1125b717e0c21bb6fa31b
+
+ texidoces = "
+Este ejemplo demuestra cómo se puede definir el grabador de ámbito en
+el espacio del usuario, con un grabador de Scheme.
+
+Esto es básicamente una reescritura en Scheme del código de
+@file{lily/ambitus-engraver.cc}.
+
+"
+
+ doctitlees = "Definir un grabador en Scheme: grabador de ámbito"
+++ /dev/null
-%% Translation of GIT committish: 0b55335aeca1de539bf1125b717e0c21bb6fa31b
-
- texidoces = "
-Este ejemplo demuestra cómo se puede definir el grabador de ámbito en
-el espacio del usuario, con un grabador de Scheme.
-
-Esto es básicamente una reescritura en Scheme del código de
-@file{lily/ambitus-engraver.cc}.
-
-"
-
- doctitlees = "Definir un grabador en Scheme: grabador de ámbito"
@lilypond[quote,verbatim,ragged-right]
#(define (my-callback grob)
- (let* (
- ; have we been split?
- (orig (ly:grob-original grob))
+ (let* (
+ ;; have we been split?
+ (orig (ly:grob-original grob))
- ; if yes, get the split pieces (our siblings)
- (siblings (if (ly:grob? orig)
- (ly:spanner-broken-into orig) '() )))
+ ;; if yes, get the split pieces (our siblings)
+ (siblings (if (ly:grob? orig)
+ (ly:spanner-broken-into orig)
+ '())))
- (if (and (>= (length siblings) 2)
- (eq? (car (last-pair siblings)) grob))
- (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
+ (if (and (>= (length siblings) 2)
+ (eq? (car (last-pair siblings)) grob))
+ (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
\relative c'' {
\override Tie #'after-line-breaking =
#my-callback
- c1 ~ \break c2 ~ c
+ c1 ~ \break
+ c2 ~ c
}
@end lilypond
@noindent
When applying this trick, the new @code{after-line-breaking} callback
-should also call the old one @code{after-line-breaking}, if there is
-one. For example, if using this with @code{Hairpin},
-@code{ly:hairpin::after-line-breaking} should also be called.
+should also call the old one, if such a default exists. For example,
+if using this with @code{Hairpin}, @code{ly:spanner::kill-zero-spanned-time}
+should also be called.
-@item Some objects cannot be changed with @code{\override} for
+@item
+Some objects cannot be changed with @code{\override} for
technical reasons. Examples of those are @code{NonMusicalPaperColumn}
and @code{PaperColumn}. They can be changed with the
@code{\overrideProperty} function, which works similar to @code{\once
@snippets
@lilypondfile[verbatim,lilyquote,texidoc,doctitle,ragged-right]
-{accidental-tie-overridden.ly}
+{hiding-accidentals-on-tied-notes-at-the-start-of-a-new-system.ly}
@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
{preventing-extra-naturals-from-being-automatically-added.ly}
@snippets
@lilypondfile[verbatim,lilyquote,ragged-right,texidoc,doctitle]
-{dot-count-override.ly}
+{changing-the-number-of-augmentation-dots-per-note.ly}
@seealso
+++ /dev/null
-% Do not edit this file; it is automatically
-% generated from Documentation/snippets/new
-% This file is in the public domain.
-%% Note: this file works from version 2.13.26
-\version "2.13.26"
-\header {
- lsrtags = "pitches"
- texidoc = "This shows how to hide accidentals on tied notes at the beginning of a
-new system."
- doctitle = "Hiding accidentals on tied notes at the beginning of a new system."
-} % begin verbatim
-
-
-\relative c'' {
- \override Accidental #'hide-tied-accidental-after-break = ##t
- cis1~ cis~
- \break
- cis
-}
-
--- /dev/null
+% Do not edit this file; it is automatically
+% generated from Documentation/snippets/new
+% This file is in the public domain.
+%% Note: this file works from version 2.13.26
+\version "2.13.26"
+\header {
+ lsrtags = "rhythms,expressive-marks"
+ texidoc = "This code demonstrates how to change the number of
+augmentation dots on a single note."
+ doctitle = "Changing the number of augmentation dots per note"
+} % begin verbatim
+
+
+\relative c' {
+ c4.. a16 r2 |
+ \override Dots #'dot-count = #4
+ c4.. a16 r2 |
+ \override Dots #'dot-count = #0
+ c4.. a16 r2 |
+ \revert Dots #'dot-count
+ c4.. a16 r2 |
+}
changing-time-signatures-inside-a-polymetric-section-using--scaledurations.ly
chant-or-psalms-notation.ly
creating-blank-staves.ly
+defining-an-engraver-in-scheme-ambitus-engraver.ly
engravers-one-by-one.ly
mensurstriche-layout-bar-lines-between-the-staves.ly
nesting-staves.ly
removing-bar-numbers-from-a-score.ly
-scheme-engraver-ambitus.ly
use-square-bracket-at-the-start-of-a-staff-group.ly
vocal-ensemble-template-with-lyrics-aligned-below-and-above-the-staves.ly
vocal-ensemble-template-with-verse-and-refrain.ly
--- /dev/null
+% Do not edit this file; it is automatically
+% generated from Documentation/snippets/new
+% This file is in the public domain.
+%% Note: this file works from version 2.13.15
+\version "2.13.20"
+
+\header {
+%% Translation of GIT committish: 0b55335aeca1de539bf1125b717e0c21bb6fa31b
+
+ texidoces = "
+Este ejemplo demuestra cómo se puede definir el grabador de ámbito en
+el espacio del usuario, con un grabador de Scheme.
+
+Esto es básicamente una reescritura en Scheme del código de
+@file{lily/ambitus-engraver.cc}.
+
+"
+
+ doctitlees = "Definir un grabador en Scheme: grabador de ámbito"
+
+
+ lsrtags = "contexts-and-engravers"
+
+
+ texidoc = "This example demonstrates how the ambitus engraver may be
+ defined on the user side, with a Scheme engraver.
+
+ This is basically a rewrite in Scheme of the code from
+ @file{lily/ambitus-engraver.cc}.
+"
+
+ doctitle = "Defining an engraver in Scheme: ambitus engraver"
+} % begin verbatim
+
+
+#(use-modules (oop goops))
+
+%%%
+%%% Grob utilities
+%%%
+%%% These are literal rewrites of some C++ methods used by the ambitus engraver.
+#(define (ly:event::in-event-class event class-name)
+ "Check if @var{event} the given class.
+Rewrite of @code{Stream_event::internal_in_event_class} from @file{lily/stream-event.cc}."
+ (memq class-name (ly:make-event-class (ly:event-property event 'class))))
+
+#(define (ly:separation-item::add-conditional-item grob grob-item)
+ "Add @var{grob-item} to the array of conditional elements of @var{grob}.
+Rewrite of @code{Separation_item::add_conditional_item} from @file{lily/separation-item.cc}."
+ (ly:pointer-group-interface::add-grob grob 'conditional-elements grob-item))
+
+#(define (ly:accidental-placement::accidental-pitch accidental-grob)
+ "Get the pitch from the grob cause of @var{accidental-grob}.
+Rewrite of @code{accidental_pitch} from @file{lily/accidental-placement.cc}."
+ (ly:event-property (ly:grob-property (ly:grob-parent accidental-grob Y) 'cause)
+ 'pitch))
+
+#(define (ly:accidental-placement::add-accidental grob accidental-grob)
+ "Add @var{accidental-grob}, an @code{Accidental} grob, to the
+list of the accidental grobs of @var{grob}, an @code{AccidentalPlacement}
+grob.
+Rewrite of @code{Accidental_placement::add_accidental} from @file{lily/accidental-placement.cc}."
+ (let ((pitch (ly:accidental-placement::accidental-pitch accidental-grob)))
+ (set! (ly:grob-parent accidental-grob X) grob)
+ (set! (ly:grob-property accidental-grob 'X-offset)
+ ly:grob::x-parent-positioning)
+ (let* ((accidentals (ly:grob-object grob 'accidental-grobs))
+ (handle (assq (ly:pitch-notename pitch) accidentals))
+ (entry (if handle (cdr handle) '())))
+ (set! (ly:grob-object grob 'accidental-grobs)
+ (assq-set! accidentals
+ (ly:pitch-notename pitch)
+ (cons accidental-grob entry))))))
+
+%%%
+%%% Ambitus data structure
+%%%
+
+%%% The <ambitus> class holds the various grobs that are created
+%%% to print an ambitus:
+%%% - ambitus-group: the grob that groups all the components of an ambitus
+%%% (Ambitus grob);
+%%% - ambitus-line: the vertical line between the upper and lower ambitus
+%%% notes (AmbitusLine grob);
+%%% - ambitus-up-note and ambitus-down-note: the note head and accidental
+%%% for the lower and upper note of the ambitus (see <ambitus-note> class
+%%% below).
+%%% The other slots define the key and clef context of the engraver:
+%%% - start-c0: position of middle c at the beginning of the piece. It
+%%% is used to place the ambitus notes according to their pitch;
+%%% - start-key-sig: the key signature at the beginning of the piece. It
+%%% is used to determine if accidentals shall be printed next to ambitus
+%%% notes.
+
+#(define-class <ambitus> ()
+ (ambitus-group #:accessor ambitus-group)
+ (ambitus-line #:accessor ambitus-line)
+ (ambitus-up-note #:getter ambitus-up-note
+ #:init-form (make <ambitus-note>))
+ (ambitus-down-note #:getter ambitus-down-note
+ #:init-form (make <ambitus-note>))
+ (start-c0 #:accessor ambitus-start-c0
+ #:init-value #f)
+ (start-key-sig #:accessor ambitus-start-key-sig
+ #:init-value '()))
+
+%%% Accessor for the lower and upper note data of an ambitus
+#(define-method (ambitus-note (ambitus <ambitus>) direction)
+ "If @var{direction} is @code{UP}, then return the upper ambitus note
+of @var{ambitus}, otherwise return the lower ambitus note."
+ (if (= direction UP)
+ (ambitus-up-note ambitus)
+ (ambitus-down-note ambitus)))
+
+%%% The <ambitus-note> class holds the grobs that are specific to ambitus
+%%% (lower and upper) notes:
+%%% - head: an AmbitusNoteHead grob;
+%%% - accidental: an AmbitusAccidental grob, to be possibly printed next
+%%% to the ambitus note head.
+%%% Moreover:
+%%% - pitch is the absolute pitch of the note
+%%% - cause is the note event that causes this ambitus note, i.e. the lower
+%%% or upper note of the considered music sequence.
+
+#(define-class <ambitus-note> ()
+ (head #:accessor ambitus-note-head
+ #:init-value #f)
+ (accidental #:accessor ambitus-note-accidental
+ #:init-value #f)
+ (cause #:accessor ambitus-note-cause
+ #:init-value #f)
+ (pitch #:accessor ambitus-note-pitch
+ #:init-value #f))
+
+%%%
+%%% Ambitus engraving logics
+%%%
+%%% Rewrite of the code from @file{lily/ambitus-engraver.cc}.
+
+#(define (make-ambitus translator)
+ "Build an ambitus object: initialize all the grobs and their relations.
+
+The Ambitus grob contain all other grobs:
+ Ambitus
+ |- AmbitusLine
+ |- AmbitusNoteHead for upper note
+ |- AmbitusAccidental for upper note
+ |- AmbitusNoteHead for lower note
+ |- AmbitusAccidental for lower note
+
+The parent of an accidental is the corresponding note head,
+and the accidental is set as the 'accidental-grob of the note head
+so that is printed by the function that prints notes."
+ ;; make the ambitus object
+ (let ((ambitus (make <ambitus>)))
+ ;; build the Ambitus grob, which will contain all other grobs
+ (set! (ambitus-group ambitus) (ly:engraver-make-grob translator 'Ambitus '()))
+ ;; build the AmbitusLine grob (line between lower and upper note)
+ (set! (ambitus-line ambitus) (ly:engraver-make-grob translator 'AmbitusLine '()))
+ ;; build the upper and lower AmbitusNoteHead and AmbitusAccidental
+ (for-each (lambda (direction)
+ (let ((head (ly:engraver-make-grob translator 'AmbitusNoteHead '()))
+ (accidental (ly:engraver-make-grob translator 'AmbitusAccidental '()))
+ (group (ambitus-group ambitus)))
+ ;; The parent of the AmbitusAccidental grob is the
+ ;; AmbitusNoteHead grob
+ (set! (ly:grob-parent accidental Y) head)
+ ;; The AmbitusAccidental grob is set as the accidental-grob
+ ;; object of the AmbitusNoteHead. This is later used by the
+ ;; function that prints notes.
+ (set! (ly:grob-object head 'accidental-grob) accidental)
+ ;; both the note head and the accidental grobs are added
+ ;; to the main ambitus grob.
+ (ly:axis-group-interface::add-element group head)
+ (ly:axis-group-interface::add-element group accidental)
+ ;; the note head and the accidental grobs are added to the
+ ;; ambitus object
+ (set! (ambitus-note-head (ambitus-note ambitus direction))
+ head)
+ (set! (ambitus-note-accidental (ambitus-note ambitus direction))
+ accidental)))
+ (list DOWN UP))
+ ;; The parent of the ambitus line is the lower ambitus note head
+ (set! (ly:grob-parent (ambitus-line ambitus) X)
+ (ambitus-note-head (ambitus-note ambitus DOWN)))
+ ;; the ambitus line is added to the ambitus main grob
+ (ly:axis-group-interface::add-element (ambitus-group ambitus) (ambitus-line ambitus))
+ ambitus))
+
+#(define-method (initialize-ambitus-state (ambitus <ambitus>) translator)
+ "Initialize the state of @var{ambitus}, by getting the starting
+position of middle C and key signature from @var{translator}'s context."
+ (if (not (ambitus-start-c0 ambitus))
+ (begin
+ (set! (ambitus-start-c0 ambitus)
+ (ly:context-property (ly:translator-context translator)
+ 'middleCPosition
+ 0))
+ (set! (ambitus-start-key-sig ambitus)
+ (ly:context-property (ly:translator-context translator)
+ 'keySignature)))))
+
+#(define-method (update-ambitus-notes (ambitus <ambitus>) note-grob)
+ "Update the upper and lower ambitus pithes of @var{ambitus}, using
+@var{note-grob}."
+ ;; Get the event that caused the note-grob creation
+ ;; and check that it is a note-event.
+ (let ((note-event (ly:grob-property note-grob 'cause)))
+ (if (ly:event::in-event-class note-event 'note-event)
+ ;; get the pitch from the note event
+ (let ((pitch (ly:event-property note-event 'pitch)))
+ ;; if this pitch is lower than the current ambitus lower
+ ;; note pitch (or it has not been initialized yet),
+ ;; then this pitch is the new ambitus lower pitch,
+ ;; and conversely for upper pitch.
+ (for-each (lambda (direction pitch-compare)
+ (if (or (not (ambitus-note-pitch (ambitus-note ambitus direction)))
+ (pitch-compare pitch
+ (ambitus-note-pitch (ambitus-note ambitus direction))))
+ (begin
+ (set! (ambitus-note-pitch (ambitus-note ambitus direction))
+ pitch)
+ (set! (ambitus-note-cause (ambitus-note ambitus direction))
+ note-event))))
+ (list DOWN UP)
+ (list ly:pitch<? (lambda (p1 p2)
+ (ly:pitch<? p2 p1))))))))
+
+#(define-method (typeset-ambitus (ambitus <ambitus>) translator)
+ "Typeset the ambitus:
+- place the lower and upper ambitus notes according to their pitch and
+ the position of the middle C;
+- typeset or delete the note accidentals, according to the key signature.
+ An accidental, if it is to be printed, is added to an AccidentalPlacement
+ grob (a grob dedicated to the placement of accidentals near a chord);
+- both note heads are added to the ambitus line grob, so that a line should
+ be printed between them."
+ ;; check if there are lower and upper pitches
+ (if (and (ambitus-note-pitch (ambitus-note ambitus UP))
+ (ambitus-note-pitch (ambitus-note ambitus DOWN)))
+ ;; make an AccidentalPlacement grob, for placement of note accidentals
+ (let ((accidental-placement (ly:engraver-make-grob
+ translator
+ 'AccidentalPlacement
+ (ambitus-note-accidental (ambitus-note ambitus DOWN)))))
+ ;; For lower and upper ambitus notes:
+ (for-each (lambda (direction)
+ (let ((pitch (ambitus-note-pitch (ambitus-note ambitus direction))))
+ ;; set the cause and the staff position of the ambitus note
+ ;; according to the associated pitch
+ (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
+ 'cause)
+ (ambitus-note-cause (ambitus-note ambitus direction)))
+ (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
+ 'staff-position)
+ (+ (ambitus-start-c0 ambitus)
+ (ly:pitch-steps pitch)))
+ ;; determine if an accidental shall be printed for this note,
+ ;; according to the key signature
+ (let* ((handle (or (assoc (cons (ly:pitch-octave pitch)
+ (ly:pitch-notename pitch))
+ (ambitus-start-key-sig ambitus))
+ (assoc (ly:pitch-notename pitch)
+ (ambitus-start-key-sig ambitus))))
+ (sig-alter (if handle (cdr handle) 0)))
+ (cond ((= (ly:pitch-alteration pitch) sig-alter)
+ ;; the note alteration is in the key signature
+ ;; => it does not have to be printed
+ (ly:grob-suicide!
+ (ambitus-note-accidental (ambitus-note ambitus direction)))
+ (set! (ly:grob-object (ambitus-note-head (ambitus-note ambitus direction))
+ 'accidental-grob)
+ '()))
+ (else
+ ;; otherwise, the accidental shall be printed
+ (set! (ly:grob-property (ambitus-note-accidental
+ (ambitus-note ambitus direction))
+ 'alteration)
+ (ly:pitch-alteration pitch)))))
+ ;; add the AccidentalPlacement grob to the
+ ;; conditional items of the AmbitusNoteHead
+ (ly:separation-item::add-conditional-item
+ (ambitus-note-head (ambitus-note ambitus direction))
+ accidental-placement)
+ ;; add the AmbitusAccidental to the list of the
+ ;; AccidentalPlacement grob accidentals
+ (ly:accidental-placement::add-accidental
+ accidental-placement
+ (ambitus-note-accidental (ambitus-note ambitus direction)))
+ ;; add the AmbitusNoteHead grob to the AmbitusLine grob
+ (ly:pointer-group-interface::add-grob
+ (ambitus-line ambitus)
+ 'note-heads
+ (ambitus-note-head (ambitus-note ambitus direction)))))
+ (list DOWN UP))
+ ;; add the AccidentalPlacement grob to the main Ambitus grob
+ (ly:axis-group-interface::add-element (ambitus-group ambitus) accidental-placement))
+ ;; no notes ==> suicide the grobs
+ (begin
+ (for-each (lambda (direction)
+ (ly:grob-suicide! (ambitus-note-accidental (ambitus-note ambitus direction)))
+ (ly:grob-suicide! (ambitus-note-head (ambitus-note ambitus direction))))
+ (list DOWN UP))
+ (ly:grob-suicide! ambitus-line))))
+
+%%%
+%%% Ambitus engraver definition
+%%%
+#(define ambitus-engraver
+ (lambda (context)
+ (let ((ambitus #f))
+ ;; when music is processed: make the ambitus object, if not already built
+ `((process-music . ,(lambda (translator)
+ (if (not ambitus)
+ (set! ambitus (make-ambitus translator)))))
+ ;; set the ambitus clef and key signature state
+ (stop-translation-timestep . ,(lambda (translator)
+ (if ambitus
+ (initialize-ambitus-state ambitus translator))))
+ ;; when a note-head grob is built, update the ambitus notes
+ (acknowledgers
+ (note-head-interface . ,(lambda (engraver grob source-engraver)
+ (if ambitus
+ (update-ambitus-notes ambitus grob)))))
+ ;; finally, typeset the ambitus according to its upper and lower notes
+ ;; (if any).
+ (finalize . ,(lambda (translator)
+ (if ambitus
+ (typeset-ambitus ambitus translator))))))))
+
+%%%
+%%% Example
+%%%
+
+\score {
+ \new StaffGroup <<
+ \new Staff { c'4 des' e' fis' gis' }
+ \new Staff { \clef "bass" c4 des ~ des ees b, }
+ >>
+ \layout { \context { \Staff \consists #ambitus-engraver } }
+}
+++ /dev/null
-% Do not edit this file; it is automatically
-% generated from Documentation/snippets/new
-% This file is in the public domain.
-%% Note: this file works from version 2.13.26
-\version "2.13.26"
-\header {
- lsrtags = "rhythms,expressive-marks"
- texidoc = "This code demonstrates how to change the number of
-augmentation dots on a single note."
- doctitle = "Changing the number of augmentation dots per note"
-} % begin verbatim
-
-
-\relative c' {
- c4.. a16 r2 |
- \override Dots #'dot-count = #4
- c4.. a16 r2 |
- \override Dots #'dot-count = #0
- c4.. a16 r2 |
- \revert Dots #'dot-count
- c4.. a16 r2 |
-}
changing-text-and-spanner-styles-for-text-dynamics.ly
changing-the-appearance-of-a-slur-from-solid-to-dotted-or-dashed.ly
changing-the-breath-mark-symbol.ly
+changing-the-number-of-augmentation-dots-per-note.ly
combining-dynamics-with-markup-texts.ly
contemporary-glissando.ly
controlling-spanner-visibility-after-a-line-break.ly
creating-simultaneous-rehearsal-marks.ly
creating-slurs-across-voices.ly
creating-text-spanners.ly
-dot-count-override.ly
double-glissando.ly
dynamics-custom-text-spanner-postfix.ly
dynamics-text-spanner-postfix.ly
--- /dev/null
+% Do not edit this file; it is automatically
+% generated from Documentation/snippets/new
+% This file is in the public domain.
+%% Note: this file works from version 2.13.26
+\version "2.13.26"
+\header {
+ lsrtags = "pitches"
+ texidoc = "This shows how to hide accidentals on tied notes at the beginning of a
+new system."
+ doctitle = "Hiding accidentals on tied notes at the beginning of a new system"
+} % begin verbatim
+
+
+\relative c'' {
+ \override Accidental #'hide-tied-accidental-after-break = ##t
+ cis1~ cis~
+ \break
+ cis
+}
+
+++ /dev/null
-\version "2.13.26"
-\header {
- lsrtags = "pitches"
- texidoc = "This shows how to hide accidentals on tied notes at the beginning of a
-new system."
- doctitle = "Hiding accidentals on tied notes at the beginning of a new system."
-}
-
-\relative c'' {
- \override Accidental #'hide-tied-accidental-after-break = ##t
- cis1~ cis~
- \break
- cis
-}
-
--- /dev/null
+\version "2.13.26"
+\header {
+ lsrtags = "rhythms,expressive-marks"
+ texidoc = "This code demonstrates how to change the number of
+augmentation dots on a single note."
+ doctitle = "Changing the number of augmentation dots per note"
+}
+
+\relative c' {
+ c4.. a16 r2 |
+ \override Dots #'dot-count = #4
+ c4.. a16 r2 |
+ \override Dots #'dot-count = #0
+ c4.. a16 r2 |
+ \revert Dots #'dot-count
+ c4.. a16 r2 |
+}
--- /dev/null
+\version "2.13.15"
+
+\header {
+
+ lsrtags = "contexts-and-engravers"
+
+
+ texidoc = "This example demonstrates how the ambitus engraver may be
+ defined on the user side, with a Scheme engraver.
+
+ This is basically a rewrite in Scheme of the code from
+ @file{lily/ambitus-engraver.cc}.
+"
+
+ doctitle = "Defining an engraver in Scheme: ambitus engraver"
+}
+
+#(use-modules (oop goops))
+
+%%%
+%%% Grob utilities
+%%%
+%%% These are literal rewrites of some C++ methods used by the ambitus engraver.
+#(define (ly:event::in-event-class event class-name)
+ "Check if @var{event} the given class.
+Rewrite of @code{Stream_event::internal_in_event_class} from @file{lily/stream-event.cc}."
+ (memq class-name (ly:make-event-class (ly:event-property event 'class))))
+
+#(define (ly:separation-item::add-conditional-item grob grob-item)
+ "Add @var{grob-item} to the array of conditional elements of @var{grob}.
+Rewrite of @code{Separation_item::add_conditional_item} from @file{lily/separation-item.cc}."
+ (ly:pointer-group-interface::add-grob grob 'conditional-elements grob-item))
+
+#(define (ly:accidental-placement::accidental-pitch accidental-grob)
+ "Get the pitch from the grob cause of @var{accidental-grob}.
+Rewrite of @code{accidental_pitch} from @file{lily/accidental-placement.cc}."
+ (ly:event-property (ly:grob-property (ly:grob-parent accidental-grob Y) 'cause)
+ 'pitch))
+
+#(define (ly:accidental-placement::add-accidental grob accidental-grob)
+ "Add @var{accidental-grob}, an @code{Accidental} grob, to the
+list of the accidental grobs of @var{grob}, an @code{AccidentalPlacement}
+grob.
+Rewrite of @code{Accidental_placement::add_accidental} from @file{lily/accidental-placement.cc}."
+ (let ((pitch (ly:accidental-placement::accidental-pitch accidental-grob)))
+ (set! (ly:grob-parent accidental-grob X) grob)
+ (set! (ly:grob-property accidental-grob 'X-offset)
+ ly:grob::x-parent-positioning)
+ (let* ((accidentals (ly:grob-object grob 'accidental-grobs))
+ (handle (assq (ly:pitch-notename pitch) accidentals))
+ (entry (if handle (cdr handle) '())))
+ (set! (ly:grob-object grob 'accidental-grobs)
+ (assq-set! accidentals
+ (ly:pitch-notename pitch)
+ (cons accidental-grob entry))))))
+
+%%%
+%%% Ambitus data structure
+%%%
+
+%%% The <ambitus> class holds the various grobs that are created
+%%% to print an ambitus:
+%%% - ambitus-group: the grob that groups all the components of an ambitus
+%%% (Ambitus grob);
+%%% - ambitus-line: the vertical line between the upper and lower ambitus
+%%% notes (AmbitusLine grob);
+%%% - ambitus-up-note and ambitus-down-note: the note head and accidental
+%%% for the lower and upper note of the ambitus (see <ambitus-note> class
+%%% below).
+%%% The other slots define the key and clef context of the engraver:
+%%% - start-c0: position of middle c at the beginning of the piece. It
+%%% is used to place the ambitus notes according to their pitch;
+%%% - start-key-sig: the key signature at the beginning of the piece. It
+%%% is used to determine if accidentals shall be printed next to ambitus
+%%% notes.
+
+#(define-class <ambitus> ()
+ (ambitus-group #:accessor ambitus-group)
+ (ambitus-line #:accessor ambitus-line)
+ (ambitus-up-note #:getter ambitus-up-note
+ #:init-form (make <ambitus-note>))
+ (ambitus-down-note #:getter ambitus-down-note
+ #:init-form (make <ambitus-note>))
+ (start-c0 #:accessor ambitus-start-c0
+ #:init-value #f)
+ (start-key-sig #:accessor ambitus-start-key-sig
+ #:init-value '()))
+
+%%% Accessor for the lower and upper note data of an ambitus
+#(define-method (ambitus-note (ambitus <ambitus>) direction)
+ "If @var{direction} is @code{UP}, then return the upper ambitus note
+of @var{ambitus}, otherwise return the lower ambitus note."
+ (if (= direction UP)
+ (ambitus-up-note ambitus)
+ (ambitus-down-note ambitus)))
+
+%%% The <ambitus-note> class holds the grobs that are specific to ambitus
+%%% (lower and upper) notes:
+%%% - head: an AmbitusNoteHead grob;
+%%% - accidental: an AmbitusAccidental grob, to be possibly printed next
+%%% to the ambitus note head.
+%%% Moreover:
+%%% - pitch is the absolute pitch of the note
+%%% - cause is the note event that causes this ambitus note, i.e. the lower
+%%% or upper note of the considered music sequence.
+
+#(define-class <ambitus-note> ()
+ (head #:accessor ambitus-note-head
+ #:init-value #f)
+ (accidental #:accessor ambitus-note-accidental
+ #:init-value #f)
+ (cause #:accessor ambitus-note-cause
+ #:init-value #f)
+ (pitch #:accessor ambitus-note-pitch
+ #:init-value #f))
+
+%%%
+%%% Ambitus engraving logics
+%%%
+%%% Rewrite of the code from @file{lily/ambitus-engraver.cc}.
+
+#(define (make-ambitus translator)
+ "Build an ambitus object: initialize all the grobs and their relations.
+
+The Ambitus grob contain all other grobs:
+ Ambitus
+ |- AmbitusLine
+ |- AmbitusNoteHead for upper note
+ |- AmbitusAccidental for upper note
+ |- AmbitusNoteHead for lower note
+ |- AmbitusAccidental for lower note
+
+The parent of an accidental is the corresponding note head,
+and the accidental is set as the 'accidental-grob of the note head
+so that is printed by the function that prints notes."
+ ;; make the ambitus object
+ (let ((ambitus (make <ambitus>)))
+ ;; build the Ambitus grob, which will contain all other grobs
+ (set! (ambitus-group ambitus) (ly:engraver-make-grob translator 'Ambitus '()))
+ ;; build the AmbitusLine grob (line between lower and upper note)
+ (set! (ambitus-line ambitus) (ly:engraver-make-grob translator 'AmbitusLine '()))
+ ;; build the upper and lower AmbitusNoteHead and AmbitusAccidental
+ (for-each (lambda (direction)
+ (let ((head (ly:engraver-make-grob translator 'AmbitusNoteHead '()))
+ (accidental (ly:engraver-make-grob translator 'AmbitusAccidental '()))
+ (group (ambitus-group ambitus)))
+ ;; The parent of the AmbitusAccidental grob is the
+ ;; AmbitusNoteHead grob
+ (set! (ly:grob-parent accidental Y) head)
+ ;; The AmbitusAccidental grob is set as the accidental-grob
+ ;; object of the AmbitusNoteHead. This is later used by the
+ ;; function that prints notes.
+ (set! (ly:grob-object head 'accidental-grob) accidental)
+ ;; both the note head and the accidental grobs are added
+ ;; to the main ambitus grob.
+ (ly:axis-group-interface::add-element group head)
+ (ly:axis-group-interface::add-element group accidental)
+ ;; the note head and the accidental grobs are added to the
+ ;; ambitus object
+ (set! (ambitus-note-head (ambitus-note ambitus direction))
+ head)
+ (set! (ambitus-note-accidental (ambitus-note ambitus direction))
+ accidental)))
+ (list DOWN UP))
+ ;; The parent of the ambitus line is the lower ambitus note head
+ (set! (ly:grob-parent (ambitus-line ambitus) X)
+ (ambitus-note-head (ambitus-note ambitus DOWN)))
+ ;; the ambitus line is added to the ambitus main grob
+ (ly:axis-group-interface::add-element (ambitus-group ambitus) (ambitus-line ambitus))
+ ambitus))
+
+#(define-method (initialize-ambitus-state (ambitus <ambitus>) translator)
+ "Initialize the state of @var{ambitus}, by getting the starting
+position of middle C and key signature from @var{translator}'s context."
+ (if (not (ambitus-start-c0 ambitus))
+ (begin
+ (set! (ambitus-start-c0 ambitus)
+ (ly:context-property (ly:translator-context translator)
+ 'middleCPosition
+ 0))
+ (set! (ambitus-start-key-sig ambitus)
+ (ly:context-property (ly:translator-context translator)
+ 'keySignature)))))
+
+#(define-method (update-ambitus-notes (ambitus <ambitus>) note-grob)
+ "Update the upper and lower ambitus pithes of @var{ambitus}, using
+@var{note-grob}."
+ ;; Get the event that caused the note-grob creation
+ ;; and check that it is a note-event.
+ (let ((note-event (ly:grob-property note-grob 'cause)))
+ (if (ly:event::in-event-class note-event 'note-event)
+ ;; get the pitch from the note event
+ (let ((pitch (ly:event-property note-event 'pitch)))
+ ;; if this pitch is lower than the current ambitus lower
+ ;; note pitch (or it has not been initialized yet),
+ ;; then this pitch is the new ambitus lower pitch,
+ ;; and conversely for upper pitch.
+ (for-each (lambda (direction pitch-compare)
+ (if (or (not (ambitus-note-pitch (ambitus-note ambitus direction)))
+ (pitch-compare pitch
+ (ambitus-note-pitch (ambitus-note ambitus direction))))
+ (begin
+ (set! (ambitus-note-pitch (ambitus-note ambitus direction))
+ pitch)
+ (set! (ambitus-note-cause (ambitus-note ambitus direction))
+ note-event))))
+ (list DOWN UP)
+ (list ly:pitch<? (lambda (p1 p2)
+ (ly:pitch<? p2 p1))))))))
+
+#(define-method (typeset-ambitus (ambitus <ambitus>) translator)
+ "Typeset the ambitus:
+- place the lower and upper ambitus notes according to their pitch and
+ the position of the middle C;
+- typeset or delete the note accidentals, according to the key signature.
+ An accidental, if it is to be printed, is added to an AccidentalPlacement
+ grob (a grob dedicated to the placement of accidentals near a chord);
+- both note heads are added to the ambitus line grob, so that a line should
+ be printed between them."
+ ;; check if there are lower and upper pitches
+ (if (and (ambitus-note-pitch (ambitus-note ambitus UP))
+ (ambitus-note-pitch (ambitus-note ambitus DOWN)))
+ ;; make an AccidentalPlacement grob, for placement of note accidentals
+ (let ((accidental-placement (ly:engraver-make-grob
+ translator
+ 'AccidentalPlacement
+ (ambitus-note-accidental (ambitus-note ambitus DOWN)))))
+ ;; For lower and upper ambitus notes:
+ (for-each (lambda (direction)
+ (let ((pitch (ambitus-note-pitch (ambitus-note ambitus direction))))
+ ;; set the cause and the staff position of the ambitus note
+ ;; according to the associated pitch
+ (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
+ 'cause)
+ (ambitus-note-cause (ambitus-note ambitus direction)))
+ (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
+ 'staff-position)
+ (+ (ambitus-start-c0 ambitus)
+ (ly:pitch-steps pitch)))
+ ;; determine if an accidental shall be printed for this note,
+ ;; according to the key signature
+ (let* ((handle (or (assoc (cons (ly:pitch-octave pitch)
+ (ly:pitch-notename pitch))
+ (ambitus-start-key-sig ambitus))
+ (assoc (ly:pitch-notename pitch)
+ (ambitus-start-key-sig ambitus))))
+ (sig-alter (if handle (cdr handle) 0)))
+ (cond ((= (ly:pitch-alteration pitch) sig-alter)
+ ;; the note alteration is in the key signature
+ ;; => it does not have to be printed
+ (ly:grob-suicide!
+ (ambitus-note-accidental (ambitus-note ambitus direction)))
+ (set! (ly:grob-object (ambitus-note-head (ambitus-note ambitus direction))
+ 'accidental-grob)
+ '()))
+ (else
+ ;; otherwise, the accidental shall be printed
+ (set! (ly:grob-property (ambitus-note-accidental
+ (ambitus-note ambitus direction))
+ 'alteration)
+ (ly:pitch-alteration pitch)))))
+ ;; add the AccidentalPlacement grob to the
+ ;; conditional items of the AmbitusNoteHead
+ (ly:separation-item::add-conditional-item
+ (ambitus-note-head (ambitus-note ambitus direction))
+ accidental-placement)
+ ;; add the AmbitusAccidental to the list of the
+ ;; AccidentalPlacement grob accidentals
+ (ly:accidental-placement::add-accidental
+ accidental-placement
+ (ambitus-note-accidental (ambitus-note ambitus direction)))
+ ;; add the AmbitusNoteHead grob to the AmbitusLine grob
+ (ly:pointer-group-interface::add-grob
+ (ambitus-line ambitus)
+ 'note-heads
+ (ambitus-note-head (ambitus-note ambitus direction)))))
+ (list DOWN UP))
+ ;; add the AccidentalPlacement grob to the main Ambitus grob
+ (ly:axis-group-interface::add-element (ambitus-group ambitus) accidental-placement))
+ ;; no notes ==> suicide the grobs
+ (begin
+ (for-each (lambda (direction)
+ (ly:grob-suicide! (ambitus-note-accidental (ambitus-note ambitus direction)))
+ (ly:grob-suicide! (ambitus-note-head (ambitus-note ambitus direction))))
+ (list DOWN UP))
+ (ly:grob-suicide! ambitus-line))))
+
+%%%
+%%% Ambitus engraver definition
+%%%
+#(define ambitus-engraver
+ (lambda (context)
+ (let ((ambitus #f))
+ ;; when music is processed: make the ambitus object, if not already built
+ `((process-music . ,(lambda (translator)
+ (if (not ambitus)
+ (set! ambitus (make-ambitus translator)))))
+ ;; set the ambitus clef and key signature state
+ (stop-translation-timestep . ,(lambda (translator)
+ (if ambitus
+ (initialize-ambitus-state ambitus translator))))
+ ;; when a note-head grob is built, update the ambitus notes
+ (acknowledgers
+ (note-head-interface . ,(lambda (engraver grob source-engraver)
+ (if ambitus
+ (update-ambitus-notes ambitus grob)))))
+ ;; finally, typeset the ambitus according to its upper and lower notes
+ ;; (if any).
+ (finalize . ,(lambda (translator)
+ (if ambitus
+ (typeset-ambitus ambitus translator))))))))
+
+%%%
+%%% Example
+%%%
+
+\score {
+ \new StaffGroup <<
+ \new Staff { c'4 des' e' fis' gis' }
+ \new Staff { \clef "bass" c4 des ~ des ees b, }
+ >>
+ \layout { \context { \Staff \consists #ambitus-engraver } }
+}
+++ /dev/null
-\version "2.13.26"
-\header {
- lsrtags = "rhythms,expressive-marks"
- texidoc = "This code demonstrates how to change the number of
-augmentation dots on a single note."
- doctitle = "Changing the number of augmentation dots per note"
-}
-
-\relative c' {
- c4.. a16 r2 |
- \override Dots #'dot-count = #4
- c4.. a16 r2 |
- \override Dots #'dot-count = #0
- c4.. a16 r2 |
- \revert Dots #'dot-count
- c4.. a16 r2 |
-}
--- /dev/null
+\version "2.13.26"
+\header {
+ lsrtags = "pitches"
+ texidoc = "This shows how to hide accidentals on tied notes at the beginning of a
+new system."
+ doctitle = "Hiding accidentals on tied notes at the beginning of a new system"
+}
+
+\relative c'' {
+ \override Accidental #'hide-tied-accidental-after-break = ##t
+ cis1~ cis~
+ \break
+ cis
+}
+
+++ /dev/null
-\version "2.13.15"
-
-\header {
-
- lsrtags = "contexts-and-engravers"
-
-
- texidoc = "This example demonstrates how the ambitus engraver may be
- defined on the user side, with a Scheme engraver.
-
- This is basically a rewrite in Scheme of the code from
- @file{lily/ambitus-engraver.cc}.
-"
-
- doctitle = "Defining an engraver in Scheme: ambitus engraver"
-}
-
-#(use-modules (oop goops))
-
-%%%
-%%% Grob utilities
-%%%
-%%% These are literal rewrites of some C++ methods used by the ambitus engraver.
-#(define (ly:event::in-event-class event class-name)
- "Check if @var{event} the given class.
-Rewrite of @code{Stream_event::internal_in_event_class} from @file{lily/stream-event.cc}."
- (memq class-name (ly:make-event-class (ly:event-property event 'class))))
-
-#(define (ly:separation-item::add-conditional-item grob grob-item)
- "Add @var{grob-item} to the array of conditional elements of @var{grob}.
-Rewrite of @code{Separation_item::add_conditional_item} from @file{lily/separation-item.cc}."
- (ly:pointer-group-interface::add-grob grob 'conditional-elements grob-item))
-
-#(define (ly:accidental-placement::accidental-pitch accidental-grob)
- "Get the pitch from the grob cause of @var{accidental-grob}.
-Rewrite of @code{accidental_pitch} from @file{lily/accidental-placement.cc}."
- (ly:event-property (ly:grob-property (ly:grob-parent accidental-grob Y) 'cause)
- 'pitch))
-
-#(define (ly:accidental-placement::add-accidental grob accidental-grob)
- "Add @var{accidental-grob}, an @code{Accidental} grob, to the
-list of the accidental grobs of @var{grob}, an @code{AccidentalPlacement}
-grob.
-Rewrite of @code{Accidental_placement::add_accidental} from @file{lily/accidental-placement.cc}."
- (let ((pitch (ly:accidental-placement::accidental-pitch accidental-grob)))
- (set! (ly:grob-parent accidental-grob X) grob)
- (set! (ly:grob-property accidental-grob 'X-offset)
- ly:grob::x-parent-positioning)
- (let* ((accidentals (ly:grob-object grob 'accidental-grobs))
- (handle (assq (ly:pitch-notename pitch) accidentals))
- (entry (if handle (cdr handle) '())))
- (set! (ly:grob-object grob 'accidental-grobs)
- (assq-set! accidentals
- (ly:pitch-notename pitch)
- (cons accidental-grob entry))))))
-
-%%%
-%%% Ambitus data structure
-%%%
-
-%%% The <ambitus> class holds the various grobs that are created
-%%% to print an ambitus:
-%%% - ambitus-group: the grob that groups all the components of an ambitus
-%%% (Ambitus grob);
-%%% - ambitus-line: the vertical line between the upper and lower ambitus
-%%% notes (AmbitusLine grob);
-%%% - ambitus-up-note and ambitus-down-note: the note head and accidental
-%%% for the lower and upper note of the ambitus (see <ambitus-note> class
-%%% below).
-%%% The other slots define the key and clef context of the engraver:
-%%% - start-c0: position of middle c at the beginning of the piece. It
-%%% is used to place the ambitus notes according to their pitch;
-%%% - start-key-sig: the key signature at the beginning of the piece. It
-%%% is used to determine if accidentals shall be printed next to ambitus
-%%% notes.
-
-#(define-class <ambitus> ()
- (ambitus-group #:accessor ambitus-group)
- (ambitus-line #:accessor ambitus-line)
- (ambitus-up-note #:getter ambitus-up-note
- #:init-form (make <ambitus-note>))
- (ambitus-down-note #:getter ambitus-down-note
- #:init-form (make <ambitus-note>))
- (start-c0 #:accessor ambitus-start-c0
- #:init-value #f)
- (start-key-sig #:accessor ambitus-start-key-sig
- #:init-value '()))
-
-%%% Accessor for the lower and upper note data of an ambitus
-#(define-method (ambitus-note (ambitus <ambitus>) direction)
- "If @var{direction} is @code{UP}, then return the upper ambitus note
-of @var{ambitus}, otherwise return the lower ambitus note."
- (if (= direction UP)
- (ambitus-up-note ambitus)
- (ambitus-down-note ambitus)))
-
-%%% The <ambitus-note> class holds the grobs that are specific to ambitus
-%%% (lower and upper) notes:
-%%% - head: an AmbitusNoteHead grob;
-%%% - accidental: an AmbitusAccidental grob, to be possibly printed next
-%%% to the ambitus note head.
-%%% Moreover:
-%%% - pitch is the absolute pitch of the note
-%%% - cause is the note event that causes this ambitus note, i.e. the lower
-%%% or upper note of the considered music sequence.
-
-#(define-class <ambitus-note> ()
- (head #:accessor ambitus-note-head
- #:init-value #f)
- (accidental #:accessor ambitus-note-accidental
- #:init-value #f)
- (cause #:accessor ambitus-note-cause
- #:init-value #f)
- (pitch #:accessor ambitus-note-pitch
- #:init-value #f))
-
-%%%
-%%% Ambitus engraving logics
-%%%
-%%% Rewrite of the code from @file{lily/ambitus-engraver.cc}.
-
-#(define (make-ambitus translator)
- "Build an ambitus object: initialize all the grobs and their relations.
-
-The Ambitus grob contain all other grobs:
- Ambitus
- |- AmbitusLine
- |- AmbitusNoteHead for upper note
- |- AmbitusAccidental for upper note
- |- AmbitusNoteHead for lower note
- |- AmbitusAccidental for lower note
-
-The parent of an accidental is the corresponding note head,
-and the accidental is set as the 'accidental-grob of the note head
-so that is printed by the function that prints notes."
- ;; make the ambitus object
- (let ((ambitus (make <ambitus>)))
- ;; build the Ambitus grob, which will contain all other grobs
- (set! (ambitus-group ambitus) (ly:engraver-make-grob translator 'Ambitus '()))
- ;; build the AmbitusLine grob (line between lower and upper note)
- (set! (ambitus-line ambitus) (ly:engraver-make-grob translator 'AmbitusLine '()))
- ;; build the upper and lower AmbitusNoteHead and AmbitusAccidental
- (for-each (lambda (direction)
- (let ((head (ly:engraver-make-grob translator 'AmbitusNoteHead '()))
- (accidental (ly:engraver-make-grob translator 'AmbitusAccidental '()))
- (group (ambitus-group ambitus)))
- ;; The parent of the AmbitusAccidental grob is the
- ;; AmbitusNoteHead grob
- (set! (ly:grob-parent accidental Y) head)
- ;; The AmbitusAccidental grob is set as the accidental-grob
- ;; object of the AmbitusNoteHead. This is later used by the
- ;; function that prints notes.
- (set! (ly:grob-object head 'accidental-grob) accidental)
- ;; both the note head and the accidental grobs are added
- ;; to the main ambitus grob.
- (ly:axis-group-interface::add-element group head)
- (ly:axis-group-interface::add-element group accidental)
- ;; the note head and the accidental grobs are added to the
- ;; ambitus object
- (set! (ambitus-note-head (ambitus-note ambitus direction))
- head)
- (set! (ambitus-note-accidental (ambitus-note ambitus direction))
- accidental)))
- (list DOWN UP))
- ;; The parent of the ambitus line is the lower ambitus note head
- (set! (ly:grob-parent (ambitus-line ambitus) X)
- (ambitus-note-head (ambitus-note ambitus DOWN)))
- ;; the ambitus line is added to the ambitus main grob
- (ly:axis-group-interface::add-element (ambitus-group ambitus) (ambitus-line ambitus))
- ambitus))
-
-#(define-method (initialize-ambitus-state (ambitus <ambitus>) translator)
- "Initialize the state of @var{ambitus}, by getting the starting
-position of middle C and key signature from @var{translator}'s context."
- (if (not (ambitus-start-c0 ambitus))
- (begin
- (set! (ambitus-start-c0 ambitus)
- (ly:context-property (ly:translator-context translator)
- 'middleCPosition
- 0))
- (set! (ambitus-start-key-sig ambitus)
- (ly:context-property (ly:translator-context translator)
- 'keySignature)))))
-
-#(define-method (update-ambitus-notes (ambitus <ambitus>) note-grob)
- "Update the upper and lower ambitus pithes of @var{ambitus}, using
-@var{note-grob}."
- ;; Get the event that caused the note-grob creation
- ;; and check that it is a note-event.
- (let ((note-event (ly:grob-property note-grob 'cause)))
- (if (ly:event::in-event-class note-event 'note-event)
- ;; get the pitch from the note event
- (let ((pitch (ly:event-property note-event 'pitch)))
- ;; if this pitch is lower than the current ambitus lower
- ;; note pitch (or it has not been initialized yet),
- ;; then this pitch is the new ambitus lower pitch,
- ;; and conversely for upper pitch.
- (for-each (lambda (direction pitch-compare)
- (if (or (not (ambitus-note-pitch (ambitus-note ambitus direction)))
- (pitch-compare pitch
- (ambitus-note-pitch (ambitus-note ambitus direction))))
- (begin
- (set! (ambitus-note-pitch (ambitus-note ambitus direction))
- pitch)
- (set! (ambitus-note-cause (ambitus-note ambitus direction))
- note-event))))
- (list DOWN UP)
- (list ly:pitch<? (lambda (p1 p2)
- (ly:pitch<? p2 p1))))))))
-
-#(define-method (typeset-ambitus (ambitus <ambitus>) translator)
- "Typeset the ambitus:
-- place the lower and upper ambitus notes according to their pitch and
- the position of the middle C;
-- typeset or delete the note accidentals, according to the key signature.
- An accidental, if it is to be printed, is added to an AccidentalPlacement
- grob (a grob dedicated to the placement of accidentals near a chord);
-- both note heads are added to the ambitus line grob, so that a line should
- be printed between them."
- ;; check if there are lower and upper pitches
- (if (and (ambitus-note-pitch (ambitus-note ambitus UP))
- (ambitus-note-pitch (ambitus-note ambitus DOWN)))
- ;; make an AccidentalPlacement grob, for placement of note accidentals
- (let ((accidental-placement (ly:engraver-make-grob
- translator
- 'AccidentalPlacement
- (ambitus-note-accidental (ambitus-note ambitus DOWN)))))
- ;; For lower and upper ambitus notes:
- (for-each (lambda (direction)
- (let ((pitch (ambitus-note-pitch (ambitus-note ambitus direction))))
- ;; set the cause and the staff position of the ambitus note
- ;; according to the associated pitch
- (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
- 'cause)
- (ambitus-note-cause (ambitus-note ambitus direction)))
- (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
- 'staff-position)
- (+ (ambitus-start-c0 ambitus)
- (ly:pitch-steps pitch)))
- ;; determine if an accidental shall be printed for this note,
- ;; according to the key signature
- (let* ((handle (or (assoc (cons (ly:pitch-octave pitch)
- (ly:pitch-notename pitch))
- (ambitus-start-key-sig ambitus))
- (assoc (ly:pitch-notename pitch)
- (ambitus-start-key-sig ambitus))))
- (sig-alter (if handle (cdr handle) 0)))
- (cond ((= (ly:pitch-alteration pitch) sig-alter)
- ;; the note alteration is in the key signature
- ;; => it does not have to be printed
- (ly:grob-suicide!
- (ambitus-note-accidental (ambitus-note ambitus direction)))
- (set! (ly:grob-object (ambitus-note-head (ambitus-note ambitus direction))
- 'accidental-grob)
- '()))
- (else
- ;; otherwise, the accidental shall be printed
- (set! (ly:grob-property (ambitus-note-accidental
- (ambitus-note ambitus direction))
- 'alteration)
- (ly:pitch-alteration pitch)))))
- ;; add the AccidentalPlacement grob to the
- ;; conditional items of the AmbitusNoteHead
- (ly:separation-item::add-conditional-item
- (ambitus-note-head (ambitus-note ambitus direction))
- accidental-placement)
- ;; add the AmbitusAccidental to the list of the
- ;; AccidentalPlacement grob accidentals
- (ly:accidental-placement::add-accidental
- accidental-placement
- (ambitus-note-accidental (ambitus-note ambitus direction)))
- ;; add the AmbitusNoteHead grob to the AmbitusLine grob
- (ly:pointer-group-interface::add-grob
- (ambitus-line ambitus)
- 'note-heads
- (ambitus-note-head (ambitus-note ambitus direction)))))
- (list DOWN UP))
- ;; add the AccidentalPlacement grob to the main Ambitus grob
- (ly:axis-group-interface::add-element (ambitus-group ambitus) accidental-placement))
- ;; no notes ==> suicide the grobs
- (begin
- (for-each (lambda (direction)
- (ly:grob-suicide! (ambitus-note-accidental (ambitus-note ambitus direction)))
- (ly:grob-suicide! (ambitus-note-head (ambitus-note ambitus direction))))
- (list DOWN UP))
- (ly:grob-suicide! ambitus-line))))
-
-%%%
-%%% Ambitus engraver definition
-%%%
-#(define ambitus-engraver
- (lambda (context)
- (let ((ambitus #f))
- ;; when music is processed: make the ambitus object, if not already built
- `((process-music . ,(lambda (translator)
- (if (not ambitus)
- (set! ambitus (make-ambitus translator)))))
- ;; set the ambitus clef and key signature state
- (stop-translation-timestep . ,(lambda (translator)
- (if ambitus
- (initialize-ambitus-state ambitus translator))))
- ;; when a note-head grob is built, update the ambitus notes
- (acknowledgers
- (note-head-interface . ,(lambda (engraver grob source-engraver)
- (if ambitus
- (update-ambitus-notes ambitus grob)))))
- ;; finally, typeset the ambitus according to its upper and lower notes
- ;; (if any).
- (finalize . ,(lambda (translator)
- (if ambitus
- (typeset-ambitus ambitus translator))))))))
-
-%%%
-%%% Example
-%%%
-
-\score {
- \new StaffGroup <<
- \new Staff { c'4 des' e' fis' gis' }
- \new Staff { \clef "bass" c4 des ~ des ees b, }
- >>
- \layout { \context { \Staff \consists #ambitus-engraver } }
-}
meter changes (and other elements common to all parts) throughout
the entire score.
"
- doctitle = "Solo verse and two-part refrain"
+ doctitle = "Vocal ensemble template with verse and refrain"
}
global = {
-accidental-tie-overridden.ly
adding-ambitus-per-voice.ly
altering-the-length-of-beamed-stems.ly
ambitus-with-multiple-voices.ly
creating-a-sequence-of-notes-on-various-pitches.ly
dodecaphonic-style-accidentals-for-each-note-including-naturals.ly
generating-random-notes.ly
+hiding-accidentals-on-tied-notes-at-the-start-of-a-new-system.ly
keep-change-clefs-full-sized.ly
makam-example.ly
non-traditional-key-signatures.ly
-accidental-tie-overridden.ly
adding-beams,-slurs,-ties-etc.-when-using-tuplet-and-non-tuplet-rhythms.ly
adding-drum-parts.ly
adjusting-grace-note-spacing.ly
beams-across-line-breaks.ly
changing-beam-knee-gap.ly
changing-form-of-multi-measure-rests.ly
+changing-the-number-of-augmentation-dots-per-note.ly
changing-the-time-signature-without-affecting-the-beaming.ly
changing-the-tuplet-number.ly
changing-time-signatures-inside-a-polymetric-section-using--scaledurations.ly
compound-time-signatures.ly
conducting-signs,-measure-grouping-signs.ly
controlling-tuplet-bracket-visibility.ly
-dot-count-override.ly
engraving-ties-manually.ly
engraving-tremolos-with-floating-beams.ly
entering-several-tuplets-using-only-one--times-command.ly
+++ /dev/null
-% Do not edit this file; it is automatically
-% generated from Documentation/snippets/new
-% This file is in the public domain.
-%% Note: this file works from version 2.13.15
-\version "2.13.20"
-
-\header {
-%% Translation of GIT committish: 0b55335aeca1de539bf1125b717e0c21bb6fa31b
-
- texidoces = "
-Este ejemplo demuestra cómo se puede definir el grabador de ámbito en
-el espacio del usuario, con un grabador de Scheme.
-
-Esto es básicamente una reescritura en Scheme del código de
-@file{lily/ambitus-engraver.cc}.
-
-"
-
- doctitlees = "Definir un grabador en Scheme: grabador de ámbito"
-
-
- lsrtags = "contexts-and-engravers"
-
-
- texidoc = "This example demonstrates how the ambitus engraver may be
- defined on the user side, with a Scheme engraver.
-
- This is basically a rewrite in Scheme of the code from
- @file{lily/ambitus-engraver.cc}.
-"
-
- doctitle = "Defining an engraver in Scheme: ambitus engraver"
-} % begin verbatim
-
-
-#(use-modules (oop goops))
-
-%%%
-%%% Grob utilities
-%%%
-%%% These are literal rewrites of some C++ methods used by the ambitus engraver.
-#(define (ly:event::in-event-class event class-name)
- "Check if @var{event} the given class.
-Rewrite of @code{Stream_event::internal_in_event_class} from @file{lily/stream-event.cc}."
- (memq class-name (ly:make-event-class (ly:event-property event 'class))))
-
-#(define (ly:separation-item::add-conditional-item grob grob-item)
- "Add @var{grob-item} to the array of conditional elements of @var{grob}.
-Rewrite of @code{Separation_item::add_conditional_item} from @file{lily/separation-item.cc}."
- (ly:pointer-group-interface::add-grob grob 'conditional-elements grob-item))
-
-#(define (ly:accidental-placement::accidental-pitch accidental-grob)
- "Get the pitch from the grob cause of @var{accidental-grob}.
-Rewrite of @code{accidental_pitch} from @file{lily/accidental-placement.cc}."
- (ly:event-property (ly:grob-property (ly:grob-parent accidental-grob Y) 'cause)
- 'pitch))
-
-#(define (ly:accidental-placement::add-accidental grob accidental-grob)
- "Add @var{accidental-grob}, an @code{Accidental} grob, to the
-list of the accidental grobs of @var{grob}, an @code{AccidentalPlacement}
-grob.
-Rewrite of @code{Accidental_placement::add_accidental} from @file{lily/accidental-placement.cc}."
- (let ((pitch (ly:accidental-placement::accidental-pitch accidental-grob)))
- (set! (ly:grob-parent accidental-grob X) grob)
- (set! (ly:grob-property accidental-grob 'X-offset)
- ly:grob::x-parent-positioning)
- (let* ((accidentals (ly:grob-object grob 'accidental-grobs))
- (handle (assq (ly:pitch-notename pitch) accidentals))
- (entry (if handle (cdr handle) '())))
- (set! (ly:grob-object grob 'accidental-grobs)
- (assq-set! accidentals
- (ly:pitch-notename pitch)
- (cons accidental-grob entry))))))
-
-%%%
-%%% Ambitus data structure
-%%%
-
-%%% The <ambitus> class holds the various grobs that are created
-%%% to print an ambitus:
-%%% - ambitus-group: the grob that groups all the components of an ambitus
-%%% (Ambitus grob);
-%%% - ambitus-line: the vertical line between the upper and lower ambitus
-%%% notes (AmbitusLine grob);
-%%% - ambitus-up-note and ambitus-down-note: the note head and accidental
-%%% for the lower and upper note of the ambitus (see <ambitus-note> class
-%%% below).
-%%% The other slots define the key and clef context of the engraver:
-%%% - start-c0: position of middle c at the beginning of the piece. It
-%%% is used to place the ambitus notes according to their pitch;
-%%% - start-key-sig: the key signature at the beginning of the piece. It
-%%% is used to determine if accidentals shall be printed next to ambitus
-%%% notes.
-
-#(define-class <ambitus> ()
- (ambitus-group #:accessor ambitus-group)
- (ambitus-line #:accessor ambitus-line)
- (ambitus-up-note #:getter ambitus-up-note
- #:init-form (make <ambitus-note>))
- (ambitus-down-note #:getter ambitus-down-note
- #:init-form (make <ambitus-note>))
- (start-c0 #:accessor ambitus-start-c0
- #:init-value #f)
- (start-key-sig #:accessor ambitus-start-key-sig
- #:init-value '()))
-
-%%% Accessor for the lower and upper note data of an ambitus
-#(define-method (ambitus-note (ambitus <ambitus>) direction)
- "If @var{direction} is @code{UP}, then return the upper ambitus note
-of @var{ambitus}, otherwise return the lower ambitus note."
- (if (= direction UP)
- (ambitus-up-note ambitus)
- (ambitus-down-note ambitus)))
-
-%%% The <ambitus-note> class holds the grobs that are specific to ambitus
-%%% (lower and upper) notes:
-%%% - head: an AmbitusNoteHead grob;
-%%% - accidental: an AmbitusAccidental grob, to be possibly printed next
-%%% to the ambitus note head.
-%%% Moreover:
-%%% - pitch is the absolute pitch of the note
-%%% - cause is the note event that causes this ambitus note, i.e. the lower
-%%% or upper note of the considered music sequence.
-
-#(define-class <ambitus-note> ()
- (head #:accessor ambitus-note-head
- #:init-value #f)
- (accidental #:accessor ambitus-note-accidental
- #:init-value #f)
- (cause #:accessor ambitus-note-cause
- #:init-value #f)
- (pitch #:accessor ambitus-note-pitch
- #:init-value #f))
-
-%%%
-%%% Ambitus engraving logics
-%%%
-%%% Rewrite of the code from @file{lily/ambitus-engraver.cc}.
-
-#(define (make-ambitus translator)
- "Build an ambitus object: initialize all the grobs and their relations.
-
-The Ambitus grob contain all other grobs:
- Ambitus
- |- AmbitusLine
- |- AmbitusNoteHead for upper note
- |- AmbitusAccidental for upper note
- |- AmbitusNoteHead for lower note
- |- AmbitusAccidental for lower note
-
-The parent of an accidental is the corresponding note head,
-and the accidental is set as the 'accidental-grob of the note head
-so that is printed by the function that prints notes."
- ;; make the ambitus object
- (let ((ambitus (make <ambitus>)))
- ;; build the Ambitus grob, which will contain all other grobs
- (set! (ambitus-group ambitus) (ly:engraver-make-grob translator 'Ambitus '()))
- ;; build the AmbitusLine grob (line between lower and upper note)
- (set! (ambitus-line ambitus) (ly:engraver-make-grob translator 'AmbitusLine '()))
- ;; build the upper and lower AmbitusNoteHead and AmbitusAccidental
- (for-each (lambda (direction)
- (let ((head (ly:engraver-make-grob translator 'AmbitusNoteHead '()))
- (accidental (ly:engraver-make-grob translator 'AmbitusAccidental '()))
- (group (ambitus-group ambitus)))
- ;; The parent of the AmbitusAccidental grob is the
- ;; AmbitusNoteHead grob
- (set! (ly:grob-parent accidental Y) head)
- ;; The AmbitusAccidental grob is set as the accidental-grob
- ;; object of the AmbitusNoteHead. This is later used by the
- ;; function that prints notes.
- (set! (ly:grob-object head 'accidental-grob) accidental)
- ;; both the note head and the accidental grobs are added
- ;; to the main ambitus grob.
- (ly:axis-group-interface::add-element group head)
- (ly:axis-group-interface::add-element group accidental)
- ;; the note head and the accidental grobs are added to the
- ;; ambitus object
- (set! (ambitus-note-head (ambitus-note ambitus direction))
- head)
- (set! (ambitus-note-accidental (ambitus-note ambitus direction))
- accidental)))
- (list DOWN UP))
- ;; The parent of the ambitus line is the lower ambitus note head
- (set! (ly:grob-parent (ambitus-line ambitus) X)
- (ambitus-note-head (ambitus-note ambitus DOWN)))
- ;; the ambitus line is added to the ambitus main grob
- (ly:axis-group-interface::add-element (ambitus-group ambitus) (ambitus-line ambitus))
- ambitus))
-
-#(define-method (initialize-ambitus-state (ambitus <ambitus>) translator)
- "Initialize the state of @var{ambitus}, by getting the starting
-position of middle C and key signature from @var{translator}'s context."
- (if (not (ambitus-start-c0 ambitus))
- (begin
- (set! (ambitus-start-c0 ambitus)
- (ly:context-property (ly:translator-context translator)
- 'middleCPosition
- 0))
- (set! (ambitus-start-key-sig ambitus)
- (ly:context-property (ly:translator-context translator)
- 'keySignature)))))
-
-#(define-method (update-ambitus-notes (ambitus <ambitus>) note-grob)
- "Update the upper and lower ambitus pithes of @var{ambitus}, using
-@var{note-grob}."
- ;; Get the event that caused the note-grob creation
- ;; and check that it is a note-event.
- (let ((note-event (ly:grob-property note-grob 'cause)))
- (if (ly:event::in-event-class note-event 'note-event)
- ;; get the pitch from the note event
- (let ((pitch (ly:event-property note-event 'pitch)))
- ;; if this pitch is lower than the current ambitus lower
- ;; note pitch (or it has not been initialized yet),
- ;; then this pitch is the new ambitus lower pitch,
- ;; and conversely for upper pitch.
- (for-each (lambda (direction pitch-compare)
- (if (or (not (ambitus-note-pitch (ambitus-note ambitus direction)))
- (pitch-compare pitch
- (ambitus-note-pitch (ambitus-note ambitus direction))))
- (begin
- (set! (ambitus-note-pitch (ambitus-note ambitus direction))
- pitch)
- (set! (ambitus-note-cause (ambitus-note ambitus direction))
- note-event))))
- (list DOWN UP)
- (list ly:pitch<? (lambda (p1 p2)
- (ly:pitch<? p2 p1))))))))
-
-#(define-method (typeset-ambitus (ambitus <ambitus>) translator)
- "Typeset the ambitus:
-- place the lower and upper ambitus notes according to their pitch and
- the position of the middle C;
-- typeset or delete the note accidentals, according to the key signature.
- An accidental, if it is to be printed, is added to an AccidentalPlacement
- grob (a grob dedicated to the placement of accidentals near a chord);
-- both note heads are added to the ambitus line grob, so that a line should
- be printed between them."
- ;; check if there are lower and upper pitches
- (if (and (ambitus-note-pitch (ambitus-note ambitus UP))
- (ambitus-note-pitch (ambitus-note ambitus DOWN)))
- ;; make an AccidentalPlacement grob, for placement of note accidentals
- (let ((accidental-placement (ly:engraver-make-grob
- translator
- 'AccidentalPlacement
- (ambitus-note-accidental (ambitus-note ambitus DOWN)))))
- ;; For lower and upper ambitus notes:
- (for-each (lambda (direction)
- (let ((pitch (ambitus-note-pitch (ambitus-note ambitus direction))))
- ;; set the cause and the staff position of the ambitus note
- ;; according to the associated pitch
- (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
- 'cause)
- (ambitus-note-cause (ambitus-note ambitus direction)))
- (set! (ly:grob-property (ambitus-note-head (ambitus-note ambitus direction))
- 'staff-position)
- (+ (ambitus-start-c0 ambitus)
- (ly:pitch-steps pitch)))
- ;; determine if an accidental shall be printed for this note,
- ;; according to the key signature
- (let* ((handle (or (assoc (cons (ly:pitch-octave pitch)
- (ly:pitch-notename pitch))
- (ambitus-start-key-sig ambitus))
- (assoc (ly:pitch-notename pitch)
- (ambitus-start-key-sig ambitus))))
- (sig-alter (if handle (cdr handle) 0)))
- (cond ((= (ly:pitch-alteration pitch) sig-alter)
- ;; the note alteration is in the key signature
- ;; => it does not have to be printed
- (ly:grob-suicide!
- (ambitus-note-accidental (ambitus-note ambitus direction)))
- (set! (ly:grob-object (ambitus-note-head (ambitus-note ambitus direction))
- 'accidental-grob)
- '()))
- (else
- ;; otherwise, the accidental shall be printed
- (set! (ly:grob-property (ambitus-note-accidental
- (ambitus-note ambitus direction))
- 'alteration)
- (ly:pitch-alteration pitch)))))
- ;; add the AccidentalPlacement grob to the
- ;; conditional items of the AmbitusNoteHead
- (ly:separation-item::add-conditional-item
- (ambitus-note-head (ambitus-note ambitus direction))
- accidental-placement)
- ;; add the AmbitusAccidental to the list of the
- ;; AccidentalPlacement grob accidentals
- (ly:accidental-placement::add-accidental
- accidental-placement
- (ambitus-note-accidental (ambitus-note ambitus direction)))
- ;; add the AmbitusNoteHead grob to the AmbitusLine grob
- (ly:pointer-group-interface::add-grob
- (ambitus-line ambitus)
- 'note-heads
- (ambitus-note-head (ambitus-note ambitus direction)))))
- (list DOWN UP))
- ;; add the AccidentalPlacement grob to the main Ambitus grob
- (ly:axis-group-interface::add-element (ambitus-group ambitus) accidental-placement))
- ;; no notes ==> suicide the grobs
- (begin
- (for-each (lambda (direction)
- (ly:grob-suicide! (ambitus-note-accidental (ambitus-note ambitus direction)))
- (ly:grob-suicide! (ambitus-note-head (ambitus-note ambitus direction))))
- (list DOWN UP))
- (ly:grob-suicide! ambitus-line))))
-
-%%%
-%%% Ambitus engraver definition
-%%%
-#(define ambitus-engraver
- (lambda (context)
- (let ((ambitus #f))
- ;; when music is processed: make the ambitus object, if not already built
- `((process-music . ,(lambda (translator)
- (if (not ambitus)
- (set! ambitus (make-ambitus translator)))))
- ;; set the ambitus clef and key signature state
- (stop-translation-timestep . ,(lambda (translator)
- (if ambitus
- (initialize-ambitus-state ambitus translator))))
- ;; when a note-head grob is built, update the ambitus notes
- (acknowledgers
- (note-head-interface . ,(lambda (engraver grob source-engraver)
- (if ambitus
- (update-ambitus-notes ambitus grob)))))
- ;; finally, typeset the ambitus according to its upper and lower notes
- ;; (if any).
- (finalize . ,(lambda (translator)
- (if ambitus
- (typeset-ambitus ambitus translator))))))))
-
-%%%
-%%% Example
-%%%
-
-\score {
- \new StaffGroup <<
- \new Staff { c'4 des' e' fis' gis' }
- \new Staff { \clef "bass" c4 des ~ des ees b, }
- >>
- \layout { \context { \Staff \consists #ambitus-engraver } }
-}
meter changes (and other elements common to all parts) throughout
the entire score.
"
- doctitle = "Solo verse and two-part refrain"
+ doctitle = "Vocal ensemble template with verse and refrain"
} % begin verbatim
+++ /dev/null
-/*
- This file is part of LilyPond, the GNU music typesetter.
-
- Copyright (C) 2004--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
-
- LilyPond is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- LilyPond is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "self-alignment-interface.hh"
-
-#include "warn.hh"
-#include "paper-column.hh"
-#include "grob.hh"
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, y_aligned_on_self, 1);
-SCM
-Self_alignment_interface::y_aligned_on_self (SCM element)
-{
- return aligned_on_self (unsmob_grob (element), Y_AXIS, false, 0, 0);
-}
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_aligned_on_self, 1);
-SCM
-Self_alignment_interface::x_aligned_on_self (SCM element)
-{
- return aligned_on_self (unsmob_grob (element), X_AXIS, false, 0, 0);
-}
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, pure_y_aligned_on_self, 3);
-SCM
-Self_alignment_interface::pure_y_aligned_on_self (SCM smob, SCM start, SCM end)
-{
- return aligned_on_self (unsmob_grob (smob), Y_AXIS, true, robust_scm2int (start, 0), robust_scm2int (end, INT_MAX));
-}
-
-SCM
-Self_alignment_interface::aligned_on_self (Grob *me, Axis a, bool pure, int start, int end)
-{
- SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
- : ly_symbol2scm ("self-alignment-Y");
-
- SCM align (me->internal_get_property (sym));
- if (scm_is_number (align))
- {
- Interval ext (me->maybe_pure_extent (me, a, pure, start, end));
- if (ext.is_empty ())
- programming_error ("cannot align on self: empty element");
- else
- return scm_from_double (- ext.linear_combination (scm_to_double (align)));
- }
- return scm_from_double (0.0);
-}
-
-
-
-SCM
-Self_alignment_interface::centered_on_object (Grob *him, Axis a)
-{
- return scm_from_double (robust_relative_extent (him, him, a).center ());
-}
-
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_x_parent, 1);
-SCM
-Self_alignment_interface::centered_on_x_parent (SCM smob)
-{
- return centered_on_object (unsmob_grob (smob)->get_parent (X_AXIS), X_AXIS);
-}
-
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_y_parent, 1);
-SCM
-Self_alignment_interface::centered_on_y_parent (SCM smob)
-{
- return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), Y_AXIS);
-}
-
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_centered_on_y_parent, 1);
-SCM
-Self_alignment_interface::x_centered_on_y_parent (SCM smob)
-{
- return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), X_AXIS);
-}
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_x_parent,1);
-SCM
-Self_alignment_interface::aligned_on_x_parent (SCM smob)
-{
- return aligned_on_parent (unsmob_grob (smob), X_AXIS);
-}
-
-MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_y_parent,1);
-SCM
-Self_alignment_interface::aligned_on_y_parent (SCM smob)
-{
- return aligned_on_parent (unsmob_grob (smob), Y_AXIS);
-}
-
-SCM
-Self_alignment_interface::aligned_on_parent (Grob *me, Axis a)
-{
- Grob *him = me->get_parent (a);
- if (Paper_column::has_interface (him))
- return scm_from_double (0.0);
-
- Interval he = him->extent (him, a);
-
- SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
- : ly_symbol2scm ("self-alignment-Y");
- SCM align_prop (me->internal_get_property (sym));
-
- if (!scm_is_number (align_prop))
- return scm_from_int (0);
-
- Real x = 0.0;
- Real align = scm_to_double (align_prop);
-
- Interval ext (me->extent (me, a));
- if (ext.is_empty ())
- programming_error ("cannot align on self: empty element");
- else
- x -= ext.linear_combination (align);
-
- if (!he.is_empty ())
- x += he.linear_combination (align);
-
- return scm_from_double (x);
-}
-
-void
-Self_alignment_interface::set_center_parent (Grob *me, Axis a)
-{
- add_offset_callback (me,
- (a==X_AXIS) ? centered_on_x_parent_proc : centered_on_y_parent_proc,
- a);
-}
-
-void
-Self_alignment_interface::set_align_self (Grob *me, Axis a)
-{
- add_offset_callback (me,
- (a==X_AXIS) ? x_aligned_on_self_proc : y_aligned_on_self_proc,
- a);
-}
-
-ADD_INTERFACE (Self_alignment_interface,
- "Position this object on itself and/or on its parent. To this"
- " end, the following functions are provided:\n"
- "\n"
- "@table @code\n"
- "@item Self_alignment_interface::[xy]_aligned_on_self\n"
- "Align self on reference point, using"
- " @code{self-alignment-X} and @code{self-alignment-Y}."
- "@item Self_alignment_interface::aligned_on_[xy]_parent\n"
- "@item Self_alignment_interface::centered_on_[xy]_parent\n"
- "Shift the object so its own reference point is centered on"
- " the extent of the parent\n"
- "@end table\n",
-
- /* properties */
- "self-alignment-X "
- "self-alignment-Y "
- );
-
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2004--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "self-alignment-interface.hh"
+
+#include "grob.hh"
+#include "paper-column.hh"
+#include "warn.hh"
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, y_aligned_on_self, 1);
+SCM
+Self_alignment_interface::y_aligned_on_self (SCM element)
+{
+ return aligned_on_self (unsmob_grob (element), Y_AXIS, false, 0, 0);
+}
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_aligned_on_self, 1);
+SCM
+Self_alignment_interface::x_aligned_on_self (SCM element)
+{
+ return aligned_on_self (unsmob_grob (element), X_AXIS, false, 0, 0);
+}
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, pure_y_aligned_on_self, 3);
+SCM
+Self_alignment_interface::pure_y_aligned_on_self (SCM smob, SCM start, SCM end)
+{
+ return aligned_on_self (unsmob_grob (smob), Y_AXIS, true, robust_scm2int (start, 0), robust_scm2int (end, INT_MAX));
+}
+
+SCM
+Self_alignment_interface::aligned_on_self (Grob *me, Axis a, bool pure, int start, int end)
+{
+ SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
+ : ly_symbol2scm ("self-alignment-Y");
+
+ SCM align (me->internal_get_property (sym));
+ if (scm_is_number (align))
+ {
+ Interval ext (me->maybe_pure_extent (me, a, pure, start, end));
+ if (ext.is_empty ())
+ programming_error ("cannot align on self: empty element");
+ else
+ return scm_from_double (- ext.linear_combination (scm_to_double (align)));
+ }
+ return scm_from_double (0.0);
+}
+
+
+SCM
+Self_alignment_interface::centered_on_object (Grob *him, Axis a)
+{
+ return scm_from_double (robust_relative_extent (him, him, a).center ());
+}
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_x_parent, 1);
+SCM
+Self_alignment_interface::centered_on_x_parent (SCM smob)
+{
+ return centered_on_object (unsmob_grob (smob)->get_parent (X_AXIS), X_AXIS);
+}
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_y_parent, 1);
+SCM
+Self_alignment_interface::centered_on_y_parent (SCM smob)
+{
+ return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), Y_AXIS);
+}
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_centered_on_y_parent, 1);
+SCM
+Self_alignment_interface::x_centered_on_y_parent (SCM smob)
+{
+ return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), X_AXIS);
+}
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_x_parent,1);
+SCM
+Self_alignment_interface::aligned_on_x_parent (SCM smob)
+{
+ return aligned_on_parent (unsmob_grob (smob), X_AXIS);
+}
+
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_y_parent,1);
+SCM
+Self_alignment_interface::aligned_on_y_parent (SCM smob)
+{
+ return aligned_on_parent (unsmob_grob (smob), Y_AXIS);
+}
+
+SCM
+Self_alignment_interface::aligned_on_parent (Grob *me, Axis a)
+{
+ Grob *him = me->get_parent (a);
+ if (Paper_column::has_interface (him))
+ return scm_from_double (0.0);
+
+ Interval he = him->extent (him, a);
+
+ SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
+ : ly_symbol2scm ("self-alignment-Y");
+ SCM align_prop (me->internal_get_property (sym));
+
+ if (!scm_is_number (align_prop))
+ return scm_from_int (0);
+
+ Real x = 0.0;
+ Real align = scm_to_double (align_prop);
+
+ Interval ext (me->extent (me, a));
+ if (ext.is_empty ())
+ programming_error ("cannot align on self: empty element");
+ else
+ x -= ext.linear_combination (align);
+
+ if (!he.is_empty ())
+ x += he.linear_combination (align);
+
+ return scm_from_double (x);
+}
+
+void
+Self_alignment_interface::set_center_parent (Grob *me, Axis a)
+{
+ add_offset_callback (me,
+ (a == X_AXIS) ? centered_on_x_parent_proc : centered_on_y_parent_proc,
+ a);
+}
+
+void
+Self_alignment_interface::set_align_self (Grob *me, Axis a)
+{
+ add_offset_callback (me,
+ (a == X_AXIS) ? x_aligned_on_self_proc : y_aligned_on_self_proc,
+ a);
+}
+
+ADD_INTERFACE (Self_alignment_interface,
+ "Position this object on itself and/or on its parent. To this"
+ " end, the following functions are provided:\n"
+ "\n"
+ "@table @code\n"
+ "@item Self_alignment_interface::[xy]_aligned_on_self\n"
+ "Align self on reference point, using"
+ " @code{self-alignment-X} and @code{self-alignment-Y}."
+ "@item Self_alignment_interface::aligned_on_[xy]_parent\n"
+ "@item Self_alignment_interface::centered_on_[xy]_parent\n"
+ "Shift the object so its own reference point is centered on"
+ " the extent of the parent\n"
+ "@end table\n",
+
+ /* properties */
+ "self-alignment-X "
+ "self-alignment-Y "
+ );
$(LILYPOND_BOOK_LILYPOND_FLAGS)' --output=$(outdir) \
$(LILYPOND_BOOK_FLAGS)
-LILYBOOK_HTML_FILES = $(call src-wildcard,*.html)
-LILYBOOK_HTMLY_FILES = $(call src-wildcard,*.htmly)
-LILYBOOK_XML_FILES = $(call src-wildcard,*.xml)
-LILYBOOK_LYTEX_FILES = $(call src-wildcard,*.lytex)
-LILYBOOK_LATEX_FILES = $(call src-wildcard,*.latex)
-LILYBOOK_TEX_FILES = $(call src-wildcard,*.tex)
-LILYBOOK_TEXI_FILES = $(call src-wildcard,*.texi)
-LILYBOOK_TELY_FILES = $(call src-wildcard,*.tely)
-LILYBOOK_DOCBOOK_FILES = $(call src-wildcard,*.lyxml)
+HTML_FILES = $(call src-wildcard,*.html)
+HTMLY_FILES = $(call src-wildcard,*.htmly)
+XML_FILES = $(call src-wildcard,*.xml)
+LYTEX_FILES = $(call src-wildcard,*.lytex)
+LATEX_FILES = $(call src-wildcard,*.latex)
+TEX_FILES = $(call src-wildcard,*.tex)
+TEXI_FILES = $(call src-wildcard,*.texi)
+TELY_FILES = $(call src-wildcard,*.tely)
+DOCBOOK_FILES = $(call src-wildcard,*.lyxml)
-LILYBOOK_OUT_HTML_FILES = ${LILYBOOK_HTML_FILES:%.html=$(outdir)/%.html}
-LILYBOOK_OUT_HTMLY_FILES = ${LILYBOOK_HTML_FILES:%.htmly=$(outdir)/%.html}
-LILYBOOK_OUT_XML_FILES = ${LILYBOOK_XML_FILES:%.xml=$(outdir)/%.html}
+OUT_HTML_FILES = ${HTML_FILES:%.html=$(outdir)/%.html}
+OUT_HTMLY_FILES = ${HTML_FILES:%.htmly=$(outdir)/%.html}
+OUT_XML_FILES = ${XML_FILES:%.xml=$(outdir)/%.html}
# If we have pdflatex, create the pdf, otherwise only the .tex file!
ifeq (,$(findstring dblatex,$(MISSING_OPTIONAL)))
-LILYBOOK_OUT_LYTEX_FILES = ${LILYBOOK_LYTEX_FILES:%.lytex=$(outdir)/%.pdf}
-LILYBOOK_OUT_LATEX_FILES = ${LILYBOOK_LATEX_FILES:%.latex=$(outdir)/%.pdf}
-LILYBOOK_OUT_TEX_FILES = ${LILYBOOK_TEX_FILES:%.tex=$(outdir)/%.pdf}
+OUT_LYTEX_FILES = ${LYTEX_FILES:%.lytex=$(outdir)/%.pdf}
+OUT_LATEX_FILES = ${LATEX_FILES:%.latex=$(outdir)/%.pdf}
+OUT_TEX_FILES = ${TEX_FILES:%.tex=$(outdir)/%.pdf}
else
-LILYBOOK_OUT_LYTEX_FILES = ${LILYBOOK_LYTEX_FILES:%.lytex=$(outdir)/%.tex}
-LILYBOOK_OUT_LATEX_FILES = ${LILYBOOK_LATEX_FILES:%.latex=$(outdir)/%.tex}
-LILYBOOK_OUT_TEX_FILES = ${LILYBOOK_TEX_FILES:%.tex=$(outdir)/%.tex}
+OUT_LYTEX_FILES = ${LYTEX_FILES:%.lytex=$(outdir)/%.tex}
+OUT_LATEX_FILES = ${LATEX_FILES:%.latex=$(outdir)/%.tex}
+OUT_TEX_FILES = ${TEX_FILES:%.tex=$(outdir)/%.tex}
endif
-LILYBOOK_OUT_TEXI_FILES = ${LILYBOOK_TEXI_FILES:%.texi=$(outdir)/%.html}
-LILYBOOK_OUT_TELY_FILES = ${LILYBOOK_TELY_FILES:%.tely=$(outdir)/%.html}
+OUT_TEXI_FILES = ${TEXI_FILES:%.texi=$(outdir)/%.html}
+OUT_TELY_FILES = ${TELY_FILES:%.tely=$(outdir)/%.html}
# If we have dblatex, create the pdf, otherwise only the .xml file!
ifeq (,$(findstring dblatex,$(MISSING_OPTIONAL)))
-LILYBOOK_OUT_DOCBOOK_FILES = ${LILYBOOK_DOCBOOK_FILES:%.lyxml=$(outdir)/%.pdf}
+OUT_DOCBOOK_FILES = ${DOCBOOK_FILES:%.lyxml=$(outdir)/%.pdf}
else
-LILYBOOK_OUT_DOCBOOK_FILES = ${LILYBOOK_DOCBOOK_FILES:%.lyxml=$(outdir)/%.xml}
+OUT_DOCBOOK_FILES = ${DOCBOOK_FILES:%.lyxml=$(outdir)/%.xml}
endif
-LILYBOOK_OUT_FILES = $(sort $(LILYBOOK_OUT_HTML_FILES) \
- $(LILYBOOK_OUT_HTMLY_FILES) \
- $(LILYBOOK_OUT_XML_FILES) \
- $(LILYBOOK_OUT_LYTEX_FILES) \
- $(LILYBOOK_OUT_LATEX_FILES) \
- $(LILYBOOK_OUT_TEX_FILES) \
- $(LILYBOOK_OUT_TEXI_FILES) \
- $(LILYBOOK_OUT_TELY_FILES) \
- $(LILYBOOK_OUT_DOCBOOK_FILES))
-
-EXTRA_DIST_FILES += $(LILYBOOK_HTML_FILES) $(LILYBOOK_HTMLY_FILES) $(LILYBOOK_XML_FILES) \
- $(LILYBOOK_LYTEX_FILES) $(LILYBOOK_LATEX_FILES) \
- $(LILYBOOK_TEX_FILES) $(LILYBOOK_TEXI_FILES) \
- $(LILYBOOK_TELY_FILES) $(LILYBOOK_DOCBOOK_FILES)
+OUT_FILES = $(sort $(OUT_HTML_FILES) \
+ $(OUT_HTMLY_FILES) \
+ $(OUT_XML_FILES) \
+ $(OUT_LYTEX_FILES) \
+ $(OUT_LATEX_FILES) \
+ $(OUT_TEX_FILES) \
+ $(OUT_TEXI_FILES) \
+ $(OUT_TELY_FILES) \
+ $(OUT_DOCBOOK_FILES))
+EXTRA_DIST_FILES +=\
+ $(HTML_FILES)\
+ $(HTMLY_FILES)\
+ $(XML_FILES)\
+ $(LYTEX_FILES)\
+ $(LATEX_FILES)\
+ $(TEX_FILES)\
+ $(DOCBOOK_FILES)