From 9a99014bb1c199f187553fa8284521505c569031 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Tue, 12 Dec 2000 23:23:42 +0100 Subject: [PATCH] patch::: 1.3.116.jcn3 1.3.116.jcn3 --- Generated by janneke@gnu.org, From = lilypond-1.3.116.jcn2, To = lilypond-1.3.116.jcn3 usage cd lilypond-source-dir; patch -E -p1 < lilypond-1.3.116.jcn3.diff Patches do not contain automatically generated files or (urg) empty directories, i.e., you should rerun autoconf, configure --- CHANGES | 21 +- Documentation/regression-test.tely | 8 + Documentation/user/GNUmakefile | 12 +- Documentation/user/features.tely | 263 +++++++++++++++++++++++++ VERSION | 2 +- input/bugs/no-bars.ly | 20 ++ input/bugs/slur-attachment.ly | 19 ++ input/test/beam-length.ly | 10 +- input/test/ophee-slurs.ly | 9 +- input/test/slur-attachment-override.ly | 19 ++ input/test/slur-attachment.ly | 24 +-- lily/dynamic-engraver.cc | 5 - lily/hairpin.cc | 2 +- lily/slur.cc | 5 +- lily/text-spanner-engraver.cc | 19 +- lily/text-spanner.cc | 32 ++- lily/timing-engraver.cc | 1 + scm/backend-property.scm | 1 + scm/element-descriptions.scm | 15 +- scm/slur.scm | 3 +- 20 files changed, 423 insertions(+), 67 deletions(-) create mode 100644 Documentation/user/features.tely create mode 100644 input/bugs/no-bars.ly create mode 100644 input/bugs/slur-attachment.ly create mode 100644 input/test/slur-attachment-override.ly diff --git a/CHANGES b/CHANGES index 0ea170ea0e..c523a32c9b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,23 @@ ---- ../lilypond-1.3.116.jcn1/CHANGES Sat Dec 9 23:51:08 2000 +--- ../lilypond-1.3.116.jcn2/CHANGES Mon Dec 11 22:17:51 2000 +++ b/CHANGES Tue Dec 12 23:23:42 2000 +@@ -1,7 +1,15 @@ +-1.3.116.jcn2 +1.3.116.jcn3 + ============ + +-* Bugfix: generic text-spanner: set padding property to non-empty value. +* Bugfixes for (de)crescendo spanners and generic text spanners + +* Bugfix: Slur::set_interface (): don't overwrite, but copy attachment +property. + +* Started documenting some new or not too wel documented features. + +1.3.116.jcn2 +============ + + * Bugfix: only assume making deep split html documentation when + makeinfo --version 4.0.jcn2 is available. Although the documentation--- ../lilypond-1.3.116.jcn1/CHANGES Sat Dec 9 23:51:08 2000 ++ b/CHANGES Mon Dec 11 22:17:51 2000 @@ -1,3 +1,12 @@ 1.3.116.jcn2 diff --git a/Documentation/regression-test.tely b/Documentation/regression-test.tely index 98d6a1b34d..34d110de79 100644 --- a/Documentation/regression-test.tely +++ b/Documentation/regression-test.tely @@ -89,12 +89,20 @@ and documenting bugfixes. @lilypondfile{beam-rest.ly} +@lilypondfile{beam-length.ly} + @lilypondfile{slur-nice.ly} @lilypondfile{slur-symmetry.ly} @lilypondfile{slur-symmetry-1.ly} @lilypondfile{slur-broken-trend.ly} +@lilypondfile{slur-attachment.ly} + +@lilypondfile{slur-attachment-override.ly} + +@lilypondfile{ophee-slurs.ly} + @lilypondfile{tie.ly} @lilypondfile{tie-chord.ly} diff --git a/Documentation/user/GNUmakefile b/Documentation/user/GNUmakefile index e380492e38..32f8816323 100644 --- a/Documentation/user/GNUmakefile +++ b/Documentation/user/GNUmakefile @@ -52,12 +52,17 @@ SPLITTING_MAKEINFO = $(shell makeinfo --version | grep 4.0.jcn2) # $(outdir)/%/%.html: $(outdir)/%.texi $(outdir)/lilypond/lilypond.html: $(outdir)/lilypond.texi -$(MAKEINFO) --force --output=$@ --html $< -# we want footers even if website builds (or is built) partly + -mv -f $(outdir)/*.png $(outdir)/lilypond $(deep-footify) $(sort $(wildcard $(outdir)/$(*F)/*.html)) $(outdir)/lilypond-internals/lilypond-internals.html: $(outdir)/lilypond-internals.texi -$(MAKEINFO) --force --output=$@ --html $< -# we want footers even if website builds (or is built) partly + -mv -f $(outdir)/*.png $(outdir)/lilypond-internals + $(deep-footify) $(sort $(wildcard $(outdir)/$(*F)/*.html)) + +$(outdir)/features/features.html: $(outdir)/features.texi + -$(MAKEINFO) --force --output=$@ --html $< + -mv -f $(outdir)/*.png $(outdir)/features $(deep-footify) $(sort $(wildcard $(outdir)/$(*F)/*.html)) ifneq ($(SPLITTING_MAKEINFO),) @@ -74,11 +79,8 @@ endif local-WWW: $(HTML_FILES) $(datafiles) $(PS_GZ_FILES) $(DEEP_HTML_FILES) $(SHELL) $(buildscript-dir)/install-info-html.sh --dir=$(outdir) lilypond lilypond-internals $(MAKE) footify - -mkdir $(outdir)/lilypond - cp -f $(outdir)/*.png $(outdir)/lilypond $(MAKE) deep-footify - # $(PYTHON) $(step-bindir)/ls-latex.py --title 'User documentation' \ # $(DOC_FILES) $(TEX_FILES) $(TELY_FILES) \ # | sed "s!$(outdir)/!!g" > $(outdir)/index.html diff --git a/Documentation/user/features.tely b/Documentation/user/features.tely new file mode 100644 index 0000000000..14989bd912 --- /dev/null +++ b/Documentation/user/features.tely @@ -0,0 +1,263 @@ +\input texinfo @c -*-texinfo-*- +@setfilename features.info +@settitle GNU LilyPond Features + +@ignore +TODO + * add more un/badly-documented features + * write some text + * add to/merge with refman +@end ignore + +@node Top +@chapter Features + +@menu +* Arpeggio:: Arpeggio +* Glissando:: Glissando +* Manual beam settings:: Manual beam settings +* Slur attachments:: Slur attachments +* Text spanner:: Text spanner +* Output property:: Output property +* Markup text:: Markup text +* Engraver hacking:: Engraver hacking +@end menu + +Testin'' a b c... +@lilypond[fragment,relative,verbatim,center] + a'' b c +@end lilypond + +@node Arpeggio +@section Arpeggio + +@lilypond[fragment,relative,verbatim,center] + \context Voice +@end lilypond + +@lilypond[fragment,relative,verbatim,center] + \context PianoStaff < + \property PianoStaff.connectArpeggios = ##t + \context Staff \context Voice + \context Staff=other \context Voice + > +@end lilypond + + +@node Glissando +@section Glissando + + +@lilypond[fragment,relative,verbatim,center] + c'' \glissando c' +@end lilypond + +@subsection Follow Thread +@lilypond[fragment,relative,verbatim,center] + \context PianoStaff < + \property PianoStaff.followThread = ##t + \context Staff \context Voice { + c'1 + \translator Staff=two + b2 a + } + \context Staff=two {\clef bass; \skip 1*2;} + > +@end lilypond + + +@node Manual beam settings +@section Manual beam settings + + +Beams over rests... + +@lilypond[fragment,relative,verbatim,center] + \context Staff { + r4 [r8 g'' a] + } +@end lilypond + + +Control number of beams... + +@lilypond[fragment,relative,verbatim,center] + \context Staff { + [f'8 r16 f g a] + [f8 r16 \property Voice.stemLeftBeamCount = #1 f g a] + } +@end lilypond + +@lilypond[fragment,relative,verbatim,center] + f'32 g a b b a g f + + \property Voice.autoBeamSettings + \set #'(end * * * *) = #(make-moment 1 4) + f32 g a b b a g f + + f32 g a + \property Voice.stemRightBeamCount = #1 b + \property Voice.stemLeftBeamCount = #1 b + a g f +@end lilypond + +Don't extend to middle line esp. for grace + +@lilypond[fragment,relative,verbatim,center] + \grace a'8 a4 + \property Voice.Stem \set #'no-stem-extend = ##t + \grace g8 g4 +@end lilypond + +@c beam slope +@c beam start beam end + + +@node Slur attachments +@section Slur attachments + +BUG Override attachments... +@lilypond[fragment,relative,verbatim,center] + \property Voice.Slur \set #'direction = #1 + \property Voice.Stem \set #'length = #5.5 + g''8(g)g4 + g4(g8)g + \property Voice.Slur \set #'attachment = #'(stem . stem) + g8(g)g4 + g4(g8)g +@end lilypond + +Ophee slurs... +@lilypond[fragment,relative,verbatim,center] + \property Voice.Slur \set #'direction = #1 + \property Voice.Slur \set #'attachment = #'(head . head) + g''16()g()g()g()d'()d()d()d +@end lilypond + + +@c ugly slurs +@c high slurs, eg from gnossienes + + +@node Text spanner +@section Text spanner + +Have crescendo set a text spanner iso hairpin +@lilypond[fragment,relative,verbatim,center] + \context Voice { + \property Voice.crescendoText = "cresc." + \property Voice.crescendoSpanner = #'dashed-line + a''2\mf\< a a \!a + } +@end lilypond + +@subsection Ottava + +@lilypond[fragment,relative,verbatim,center] + a'''' b c a + \property Voice.TextSpanner \set #'type = #'dotted-line + \property Voice.TextSpanner \set #'edge-height = #'(0 . 1.5) + \property Voice.TextSpanner \set #'edge-text = #'("8va " . "") + \property Staff.centralCPosition = #-13 + a\spanrequest \start "text" b c a \spanrequest \stop "text" +@end lilypond + + +@node Output property +@section Output property + +@lilypond[fragment,relative,verbatim,center] + \outputproperty #(make-type-checker 'note-head-interface) + #'extra-offset = #'(2 . 3) + c''2 c +@end lilypond + +Don't move the finger 2, only text "m.d." ... +@lilypond[verbatim,center] +#(define (make-text-checker text) + (lambda (grob) (equal? text (ly-get-elt-property grob 'text)))) + +\score { + \notes\relative c''' { + \property Voice.Stem \set #'direction = #1 + \outputproperty #(make-text-checker "m.d.") + #'extra-offset = #'(-3.5 . -4.5) + a^2^"m.d." + } + \paper { linewidth = -1.; } +} +@end lilypond + + +@node Markup text +@section Markup text + +@c markup text hacking + +Metrome hack... + +@lilypond[verbatim,center] +#(define note '(rows (music "noteheads-2" ((kern . -0.1) "flags-stem")))) +#(define eight-note `(rows ,note ((kern . -0.1) (music ((raise . 3.5) "flags-u3"))))) +#(define dotted-eight-note `(rows ,eight-note (music "dots-dot"))) + +\score { + \notes\relative c'' { + a1^#`(rows ,dotted-eight-note " = 64") + } + \paper { + linewidth = -1.; + \translator{ + \ScoreContext + TextScript \override #'font-shape = #'upright + } + } +} +@end lilypond + +@node Engraver hacking +@section Engraver hacking + +No time signature, no barlines... +@lilypond[verbatim,center] +\score { + \notes \relative c'' { + a b c d + d c b a + } + \paper { + \translator { + \StaffContext + whichBar = #"" + \remove "Time_signature_engraver"; + linewidth = -1.; + } + } +} +@end lilypond + +No staff, no clef, squash pitches +@lilypond[verbatim,center] +\score { + \notes { c4 c4 c8 c8 } + \paper { + \translator { + \StaffContext + \remove Staff_symbol_engraver; + \consists Pitch_squash_engraver; + \remove Clef_engraver; + } + linewidth = -1.; + } +} +@end lilypond + +@c subsection no clefs + + +@c equalizer + +@bye + + + diff --git a/VERSION b/VERSION index de2382f6f8..88fd8ef6eb 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=116 -MY_PATCH_LEVEL=jcn2 +MY_PATCH_LEVEL=jcn3 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/bugs/no-bars.ly b/input/bugs/no-bars.ly new file mode 100644 index 0000000000..0ab9bf606a --- /dev/null +++ b/input/bugs/no-bars.ly @@ -0,0 +1,20 @@ +\header{ +texidoc=" +defaultBarType is cheched by Timing_translator, but has no effect? +"; +} + +\score { + \notes \relative c'' { + a b c d + d c b a + } + \paper { + \translator { + \StaffContext + defaultBarType = #"" + \remove "Time_signature_engraver"; + linewidth = -1.; + } + } +} diff --git a/input/bugs/slur-attachment.ly b/input/bugs/slur-attachment.ly new file mode 100644 index 0000000000..7a00de8687 --- /dev/null +++ b/input/bugs/slur-attachment.ly @@ -0,0 +1,19 @@ +\header{ +texidoc=" +Slurs should be attached to note heads, except when they would collide +with beams. Also see: ophee-slurs. +"; +} +\score{ + \notes \relative c''{ + \property Voice.Slur \set #'direction = #1 + a8( a )a4 + a4( a8 )a + a8 a()a4 + a4() a8 a + } + \paper{ + indent = 0.0; + linewidth = 100.\mm; + } +} diff --git a/input/test/beam-length.ly b/input/test/beam-length.ly index 0b39c8e46a..3c2a8f16be 100644 --- a/input/test/beam-length.ly +++ b/input/test/beam-length.ly @@ -1,10 +1,14 @@ +\header{ +texidoc=" +beams should look the same +"; +} + \score { \context Voice \notes\relative c { - % beams should look the same + [d''8 d d] [d g d] c c } - \paper { } - \midi { } } diff --git a/input/test/ophee-slurs.ly b/input/test/ophee-slurs.ly index 402aba2322..1e595dca67 100644 --- a/input/test/ophee-slurs.ly +++ b/input/test/ophee-slurs.ly @@ -1,6 +1,13 @@ +\header{ +texidoc=" +Slurs can be forced to always attach to note heads. +"; +} + + \score{ \notes \relative c''{ - \property Voice.slurVerticalDirection = #1 + \property Voice.VerticalDirection = #1 \property Voice.slurBeginAttachment = #'head \property Voice.slurEndAttachment = #'head g16()g()g()g()d'()d()d()d diff --git a/input/test/slur-attachment-override.ly b/input/test/slur-attachment-override.ly new file mode 100644 index 0000000000..caac6ff210 --- /dev/null +++ b/input/test/slur-attachment-override.ly @@ -0,0 +1,19 @@ +\header{ +texidoc=" +In some cases, you may want to set slur attachments by hand. +"; +} + +\score{ + \notes \relative c''{ + \property Voice.Stem \set #'length = #5.5 + \property Voice.Slur \set #'direction = #1 + \property Voice.Slur \set #'attachment = #'(stem . stem) + g8(g)g4 + g4(g8)g + } + \paper{ + indent = 0.0; + linewidth = 60.\mm; + } +} diff --git a/input/test/slur-attachment.ly b/input/test/slur-attachment.ly index 4f7e8d4991..7a00de8687 100644 --- a/input/test/slur-attachment.ly +++ b/input/test/slur-attachment.ly @@ -1,17 +1,19 @@ +\header{ +texidoc=" +Slurs should be attached to note heads, except when they would collide +with beams. Also see: ophee-slurs. +"; +} \score{ \notes \relative c''{ - % URG, make stem length match beam! - \property Voice.stemLength = #5 - - \property Voice.slurVerticalDirection = #1 - \property Voice.slurEndAttachment = #'stem - a8(a)a4 - \property Voice.slurEndAttachment = ##f - \property Voice.slurBeginAttachment = #'stem - a4(a8)a + \property Voice.Slur \set #'direction = #1 + a8( a )a4 + a4( a8 )a + a8 a()a4 + a4() a8 a } - \paper{ + \paper{ indent = 0.0; - linewidth = 60.0\mm; + linewidth = 100.\mm; } } diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index 66f2e4a732..dcbc09cd40 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -252,11 +252,6 @@ Dynamic_engraver::create_grobs () cresc_p_ = new Spanner (get_property ("TextSpanner")); cresc_p_->set_grob_property ("type", s); - // urg. Can't set this into Text_spanner, because we - // only want this for (de)crescendi spanners. - if (!gh_number_p (cresc_p_->get_grob_property ("padding"))) - cresc_p_->set_grob_property ("padding", gh_double2scm (1)); - daddy_trans_l_->set_property (start_type + "Spanner", SCM_UNDEFINED); s = get_property ((start_type + "Text").ch_C()); diff --git a/lily/hairpin.cc b/lily/hairpin.cc index b4b646caaa..c4520adef0 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -36,7 +36,7 @@ Hairpin::brew_molecule (SCM smob) /* Ugh, must be same as Text_spanner::brew_molecule. */ - Real padding = gh_scm2double (me->get_grob_property ("padding")); + Real padding = gh_scm2double (me->get_grob_property ("if-text-padding")); Real broken_left = spanner->get_broken_left_end_align (); Real width = spanner->spanner_length (); width -= broken_left; diff --git a/lily/slur.cc b/lily/slur.cc index 3a21afe015..901c8fc417 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -37,8 +37,9 @@ void Slur::set_interface (Grob*me) { - me->set_grob_property ("attachment", gh_cons (SCM_BOOL_F, SCM_BOOL_F)); - me->set_interface (ly_symbol2scm ("slur-interface")); + /* Ugh, junked this function, but if we don't do this, we somehow + won't be able to write to it */ + me->set_grob_property ("attachment", me->get_grob_property ("attachment")); } void diff --git a/lily/text-spanner-engraver.cc b/lily/text-spanner-engraver.cc index 858aa18da9..69b6056406 100644 --- a/lily/text-spanner-engraver.cc +++ b/lily/text-spanner-engraver.cc @@ -117,19 +117,12 @@ Text_spanner_engraver::create_grobs () { current_req_ = req_drul_[START]; span_ = new Spanner (get_property ("TextSpanner")); - - /* Don't remove me without testing. - - Urg. It seems that a padding property with empty cdr - ``(padding)'' is set somewhere, overriding the default - TextSpanner properties. Also, my gdb won't print *span_ - or span_->mutable_property_alis_ here */ - if (1)//!gh_number_p (span_->get_grob_property ("padding"))) - { - span_->remove_grob_property ("padding"); - span_->set_grob_property ("padding", gh_double2scm (0)); - } - + + /* Ugh. Reset (de)cresc. specific properties */ + span_->set_grob_property ("outer", SCM_BOOL_T); + span_->set_grob_property ("if-text-padding", gh_double2scm (0)); + span_->set_grob_property ("width-correct", gh_double2scm (0)); + Side_position::set_axis (span_, Y_AXIS); Grob *e = unsmob_grob (get_property ("currentMusicalColumn")); span_->set_bound (LEFT, e); diff --git a/lily/text-spanner.cc b/lily/text-spanner.cc index 20d0dd1758..22d400cc6b 100644 --- a/lily/text-spanner.cc +++ b/lily/text-spanner.cc @@ -37,16 +37,7 @@ Text_spanner::brew_molecule (SCM smob) /* Ugh, must be same as Hairpin::brew_molecule. */ -#if 0 - Real padding = gh_scm2double (me->get_grob_property ("padding")); -#else - /* something seems seriously broken, somewhere, when used by - text-spanner-engraver. For dynamic-engraver, all seems fine */ - Real padding = 0; - if (me->get_grob_property ("padding") != SCM_EOL - && gh_number_p (me->get_grob_property ("padding"))) - padding = gh_scm2double (me->get_grob_property ("padding")); -#endif + Real padding = gh_scm2double (me->get_grob_property ("if-text-padding")); Real broken_left = spanner->get_broken_left_end_align (); Real width = spanner->spanner_length (); width -= broken_left; @@ -59,24 +50,31 @@ Text_spanner::brew_molecule (SCM smob) Item *b = spanner->get_bound (d); broken[d] = b->break_status_dir () != CENTER; - /* This should be switchable, only for (de)cresc. not for generic - text spanners */ - if (padding && !broken [d]) + if (!broken [d]) { Interval e = b->extent (b, X_AXIS); Real r = 0.0; if (!e.empty_b ()) r = e[-d] + padding; - width += d * r; - extra_off[d] = r; + /* Text spanners such as ottava, should span from outer limits of + noteheads, iso (de)cresc. spanners that span the inner space */ + if (me->get_grob_property ("outer") != SCM_EOL) + // r *= -1; // huh? + { + width -= d * r; + } + else + { + width += d * r; + extra_off[d] = r; + } } } while (flip (&d) != LEFT); // FIXME: ecs tells us -- only for (de)cresc. spanners - if (padding) - width += gh_scm2double (me->get_grob_property ("width-correct")); + width += gh_scm2double (me->get_grob_property ("width-correct")); /* /Ugh */ diff --git a/lily/timing-engraver.cc b/lily/timing-engraver.cc index d246f08f0d..f151c270b3 100644 --- a/lily/timing-engraver.cc +++ b/lily/timing-engraver.cc @@ -47,6 +47,7 @@ Timing_engraver::start_translation_timestep( ) if (!measure_position () || (to_boolean (always))) { + /* should this work, or be junked? See input/bugs/no-bars.ly */ which=get_property ("defaultBarType" ); } } diff --git a/scm/backend-property.scm b/scm/backend-property.scm index ebc85c4e2a..e7c7c4e558 100644 --- a/scm/backend-property.scm +++ b/scm/backend-property.scm @@ -161,6 +161,7 @@ is used by @ref{note-collision-interface}") (grob-property-description 'kern number? "amount of extra white space to add before text. This is `relative'(?) to the current alignment.") (grob-property-description 'kern number? "space after a thick line") (grob-property-description 'left-padding number? "space left of accs") +(grob-property-description 'length number? "Stem length for unbeamed stems, only for user override") (grob-property-description 'lengths list? "Stem length given multiplicity of flag") (grob-property-description 'line-count integer? "Number of staff lines") (grob-property-description 'line-thickness number? "the thickness[stafflinethickness] of the line") diff --git a/scm/element-descriptions.scm b/scm/element-descriptions.scm index 5a212867ac..b5958a2fad 100644 --- a/scm/element-descriptions.scm +++ b/scm/element-descriptions.scm @@ -126,9 +126,11 @@ (Hairpin . ( (molecule-callback . ,Hairpin::brew_molecule) (thickness . 1.0) - (padding . 1.0) (height . 0.6666) + + (if-text-padding . 1.0) (width-correct . -1.0) + (dash-thickness . 1.2) (dash-length . 4.0) (self-alignment-Y . 0) @@ -403,6 +405,7 @@ (bezier-area-steps . 1.0))) (beautiful . 0.5) (y-free . 0.75) + (attachment . (#f . #f)) (attachment-offset . ((0 . 0) . (0 . 0))) (slope-limit . 0.8) (meta . ,(grob-description "Slur" slur-interface)) @@ -553,11 +556,11 @@ (molecule-callback . ,Text_spanner::brew_molecule) (font-shape . italic) (type . "line") - ;;; urg - ;; this would be for (de)cresc. text spanners - ;;;(padding . 1.0) - ;;;(padding . 0.0) - (width-correct . -1) ;ughr, only for (de)cres. spanners + + ;; urg, only for (de)cresc. text spanners + (if-text-padding . 1.0) + (width-correct . -1) + (direction . 1) (meta . ,(grob-description "TextSpanner" text-spanner-interface font-interface)) )) diff --git a/scm/slur.scm b/scm/slur.scm index 02e4642f0e..fe9e8eeff6 100644 --- a/scm/slur.scm +++ b/scm/slur.scm @@ -67,13 +67,14 @@ (ly-get-elt-property stem 'beam) ;; and beam on same side as slur (let ((beaming (ly-get-elt-property stem 'beaming))) + ;; (display "beaming: ") (write beaming) (newline) (if (pair? beaming) (<= 1 (if (= dir -1) (car beaming) (cdr beaming))) #f)))))) 'stem) - ;;(cons (lambda (slur dir) (begin (display "before loose-end") (newline))#f) #f) + ;; (cons (lambda (slur dir) (begin (display "before loose-end") (newline))#f) #f) (cons (lambda (slur dir) (not (attached-to-stem slur dir))) 'loose-end) ;; (cons (lambda (slur dir) (begin (display "after loose-end") (newline))#f) #f) -- 2.39.2