From 9087400af2bf90be2e1a50595d3d29b3011f08c5 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sat, 17 May 2003 23:26:30 +0000 Subject: [PATCH] * scm/music-functions.scm (set-octavation): new function. * input/regression/ottava.ly: new file * lily/translator-scheme.cc (LY_DEFINE): new function ly:unset-context-property (LY_DEFINE) new function ly:context-property-where-defined: --- ChangeLog | 11 +++- Documentation/user/refman.itely | 46 +++++++++++---- NEWS | 13 +++-- input/regression/ottava.ly | 22 +++++++ input/test/ottava.ly | 19 ------ lily/parser.yy | 18 ++++-- lily/translator-scheme.cc | 32 +++++++++++ ly/engraver-init.ly | 30 +++++----- scm/define-grobs.scm | 4 +- scm/define-translator-properties.scm | 3 + scm/lily.scm | 2 + scm/music-functions.scm | 86 ++++++++++++++++++---------- scm/translation-functions.scm | 32 +++++++++++ 13 files changed, 229 insertions(+), 89 deletions(-) create mode 100644 input/regression/ottava.ly delete mode 100644 input/test/ottava.ly create mode 100644 scm/translation-functions.scm diff --git a/ChangeLog b/ChangeLog index f3ba098a70..0c9b58af7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-05-18 Han-Wen Nienhuys + + * scm/music-functions.scm (set-octavation): new function. + + * input/regression/ottava.ly: new file + + * lily/translator-scheme.cc (LY_DEFINE): new function + ly:unset-context-property + (LY_DEFINE) new function ly:context-property-where-defined: + 2003-05-18 Heikki Junes * lilypond-font-lock.el: Add postfix syntax for horizontal groups. @@ -539,7 +549,6 @@ * scm/music-functions.scm (make-multi-measure-rest): set input locations for multimeasure rests. - 2003-03-31 Juergen Reuter diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 34f0e6141f..131f8e81f6 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -661,6 +661,7 @@ such as keys, clefs and time signatures. * Staff symbol:: * Key signature:: * Clef:: +* Ottava brackets:: * Time signature:: * Unmetered music:: * Bar lines:: @@ -803,6 +804,37 @@ The object for this symbol is @internalsref{Clef}. +@node Ottava brackets +@subsection Ottava brackets + +``Ottava'' brackets introduce an extra transposition of an octave for +the staff. They are created by invoking the function +@code{set-octavation} + +@cindex ottava +@cindex 15ma +@cindex octavation + +@lilypond[verbatim,fragment] +\relative c''' { + a2 b + #(set-octavation 1) + a b + #(set-octavation 0) + a b } +@end lilypond + +Internally the @code{set-octavation} sets @code{ottavation} (eg. to +@code{"8va"}) and @code{centralCPosition} properties. + +@seealso + +@internalsref{OttavaBracket} + +@refbugs + +@code{set-octavation} will get confused when clef changes happen +during an octavation bracket. @node Time signature @subsection Time signature @@ -1655,17 +1687,11 @@ start and ending note of the spanner. The string to be printed, as well as the style, is set through object properties. -[TODO: 8va engraver.] - -An application is to fake octavation indications. - @lilypond[fragment,relative,verbatim] - \relative c' { 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-\startTextSpan b c a-\stopTextSpan } + \relative c' { c1 + \property Voice.TextSpanner \set #'direction = #-1 + \property Voice.TextSpanner \set #'edge-text = #'("rall " . "") + c2-\startTextSpan b c-\stopTextSpan a } @end lilypond diff --git a/NEWS b/NEWS index e42418d753..e90f60eb17 100644 --- a/NEWS +++ b/NEWS @@ -53,14 +53,16 @@ and * NOTATION + + ** Ancient notation ... ?? ... (Jurgen?) -** Completely rewritten text formatting support. It is implemented in a +** Completely rewritten text formatting support, implemented in a completely modular way. ** Chord name formatting completely rewritten. -** Texts on multimeasure rests can be set by the user. +** Texts can be added to multimeasure rests ** Zigzagged glissandi @@ -77,14 +79,15 @@ completely modular way. ** Nested horizontal brackets for music analysis. - NOTE-\groupOpen + NOTE-\startGroup .. - NOTE-\groupClose + NOTE-\stopGroup ** Gregorian ligatures. -** Texts on multi-measure rests. +** Ottava brackets. Syntax: #(set-octavation 1) +** Metronome markings. New features in 1.6 since 1.4 diff --git a/input/regression/ottava.ly b/input/regression/ottava.ly new file mode 100644 index 0000000000..fbadf825de --- /dev/null +++ b/input/regression/ottava.ly @@ -0,0 +1,22 @@ +\header +{ +texidoc = "ottava brackets are supported, through the +use of the scheme function @code{set-octavation}. +" + +} +\version "1.7.18" + + +\paper { raggedright = ##t} +\score { + \notes\relative c''' \notes { + a b c a + #(set-octavation 1) + a b c a + #(set-octavation 0) + + a b c a +} +} + diff --git a/input/test/ottava.ly b/input/test/ottava.ly deleted file mode 100644 index 87579eb59f..0000000000 --- a/input/test/ottava.ly +++ /dev/null @@ -1,19 +0,0 @@ -\version "1.7.16" - - -fragment = \notes { - 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-\startTextSpan b c a-\stopTextSpan -} - -\paper { raggedright = ##t} - -\score { - \notes\relative c \fragment - \paper { } -} -%% new-chords-done %% diff --git a/lily/parser.yy b/lily/parser.yy index f4eeeca5b3..72086b41a8 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -133,7 +133,6 @@ set_music_properties (Music *p, SCM a) } } - SCM make_chord_step (int step, int alter) { @@ -157,7 +156,15 @@ make_chord (SCM pitch, SCM dur, SCM modification_list) return ch; } - +/* + Todo: actually also use apply iso. call too ... +*/ +bool +ly_input_procedure_p (SCM x) +{ + return gh_procedure_p (x) + || (gh_pair_p (x) && gh_procedure_p (gh_car (x))); +} Music* set_property_music (SCM sym, SCM value) @@ -835,14 +842,14 @@ Simultaneous_music: Simple_music: event_chord { $$ = $1; } | APPLYOUTPUT embedded_scm { - if (!gh_procedure_p ($2)) + if (!ly_input_procedure_p ($2)) THIS->parser_error (_ ("\applycontext takes function argument")); $$ = MY_MAKE_MUSIC ("ApplyOutputEvent"); $$->set_mus_property ("procedure", $2); $$->set_spot (THIS->here_input()); } | APPLYCONTEXT embedded_scm { - if (!gh_procedure_p ($2)) + if (!ly_input_procedure_p ($2)) THIS->parser_error (_ ("\applycontext takes function argument")); $$ = MY_MAKE_MUSIC ("ApplyContext"); $$->set_mus_property ("procedure", $2); @@ -983,6 +990,9 @@ Composite_music: scm_gc_unprotect_object (p->self_scm ()); } | APPLY embedded_scm Music { + if (!ly_input_procedure_p ($2)) + THIS->parser_error (_ ("\apply takes function argument")); + SCM ret = gh_call1 ($2, $3->self_scm ()); Music *m = unsmob_music (ret); if (!m) { diff --git a/lily/translator-scheme.cc b/lily/translator-scheme.cc index 7cf9b8ed71..2ced54dbf1 100644 --- a/lily/translator-scheme.cc +++ b/lily/translator-scheme.cc @@ -36,12 +36,44 @@ LY_DEFINE(ly_set_context_property, Translator_group* tr= dynamic_cast (t); SCM_ASSERT_TYPE(tr, context, SCM_ARG1, __FUNCTION__, "Context"); + SCM_ASSERT_TYPE(gh_symbol_p (name), name, SCM_ARG2, __FUNCTION__, "symbol"); + tr->internal_set_property (name, val); return SCM_UNSPECIFIED; } +LY_DEFINE(ly_context_property_where_defined, + "ly:context-property-where-defined", 2, 0, 0, + (SCM context, SCM name), + "Return the context above @var{context} where @var{name} is defined.") +{ + Translator *t = unsmob_translator (context); + Translator_group* tr = dynamic_cast (t); + SCM_ASSERT_TYPE(tr, context, SCM_ARG1, __FUNCTION__, "Context"); + SCM_ASSERT_TYPE(gh_symbol_p (name), name, SCM_ARG2, __FUNCTION__, "symbol"); + + return tr->where_defined (name)->self_scm(); +} + +LY_DEFINE(ly_unset_context_property, + "ly:unset-context-property", 2, 0, 0, + (SCM context, SCM name), + "Unset value of property @var{name} in context @var{context}.") +{ + Translator *t = unsmob_translator (context); + Translator_group* tr = dynamic_cast (t); + SCM_ASSERT_TYPE(tr, context, SCM_ARG1, __FUNCTION__, "Context"); + SCM_ASSERT_TYPE(gh_symbol_p (name), name, SCM_ARG2, __FUNCTION__, "symbol"); + + tr->unset_property (name); + + return SCM_UNSPECIFIED; +} + + + LY_DEFINE(ly_context_parent, "ly:context-parent", 1, 0, 0, (SCM context), diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index da047f5658..bd8d69925f 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -72,7 +72,6 @@ StaffContainerContext = \translator { InnerChoirStaffContext = \translator { \type "Engraver_group_engraver" \name InnerChoirStaff - %% alignmentReference = #0 FIXME \consists "System_start_delimiter_engraver" systemStartDelimiter = #'SystemStartBracket localKeySignature = #'() @@ -84,6 +83,7 @@ InnerChoirStaffContext = \translator { \accepts "Lyrics" \accepts "ChordNames" } + ChoirStaffContext = \translator { \InnerChoirStaffContext \name ChoirStaff @@ -103,8 +103,7 @@ RhythmicStaffContext=\translator{ \description " A context like @code{Staff} but for printing rhythms. Pitches are - ignored; the notes are printed on one line. It can contain - @code{Voice} contexts. + ignored; the notes are printed on one line. " minimumVerticalExtent = ##f extraVerticalExtent = ##f @@ -218,11 +217,10 @@ GrandStaffContext=\translator{ \type "Engraver_group_engraver" \name GrandStaff localKeySignature = #'() - \description " - Contains @code{Staff} or @code{RhythmicStaff} contexts. It adds a - brace on the left side, grouping the staves together. The bar - lines of the contained staves are connected vertically. It can - contain @code{Staff} contexts." + + \description " A group of staffs, with a brace on the left + side, grouping the staves together. The bar lines of the + contained staves are connected vertically. " \consists "Span_bar_engraver" \consists "Span_arpeggio_engraver" @@ -276,12 +274,12 @@ InnerStaffGroupContext= \translator { StaffGroupContext = \translator { \InnerStaffGroupContext \name StaffGroup - \description " - Contains @code{Staff} or @code{RhythmicStaff} contexts. Adds a - bracket on the left side, grouping the staves together. The bar - lines of the contained staves are connected vertically. It can - contain @code{Staff}, @code{RhythmicStaff}, @code{GrandStaff}, or - @code{Lyrics} contexts. + + \description + + " Groups staffs while adding a bracket on the left side, + grouping the staves together. The bar lines of the contained + staves are connected vertically. " \accepts "InnerChoirStaff" @@ -391,9 +389,7 @@ ScoreContext = \translator { other context can contain a @code{Score} context. This context handles the administration of time signatures. It also makes sure that items such as clefs, time signatures, and key-signatures are - aligned across staves. It can contain @code{Lyrics}, - @code{Staff}, @code{RhythmicStaff}, @code{GrandStaff}, - @code{StaffGroup}, and @code{ChoirStaff} contexts. + aligned across staves. You cannot explicitly instantiate a Score context (since it is not contained in any other context). It is instantiated diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index de352b2d25..c08e3f955c 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -714,7 +714,7 @@ (type . line) (if-text-padding . 1.0) (width-correct . 0) - (outer . #t) + (enclose-bounds . #t) (direction . -1) (edge-widen . (0.5 . 0.5)) (edge-height . (1.0 . 1.0)) @@ -1072,7 +1072,7 @@ (Y-offset-callbacks . (,Side_position_interface::aligned_side)) (molecule-callback . ,Text_spanner::brew_molecule) (font-family . roman) - (outer . #t) + (enclose-bounds . #t) (width-correct . 0.0) (type . dotted-line) (edge-height . (0 . 1.5)) diff --git a/scm/define-translator-properties.scm b/scm/define-translator-properties.scm index ba4eb742af..f76d179acd 100644 --- a/scm/define-translator-properties.scm +++ b/scm/define-translator-properties.scm @@ -313,6 +313,9 @@ not less than minimumFret") then beams are generated automatically.") (translator-property-description 'noDirection boolean? "Don't set directions by a2-engraver when part-combining.") (translator-property-description 'oneBeat ly:moment? " How long does one beat in the current time signature last?") +(translator-property-description + 'originalCentralCPosition integer? + "Used for temporary overriding central C in octavation brackets. ") (translator-property-description 'othersolo boolean? "FIXME") (translator-property-description 'ottavation string? "If set, the text for an 8va spanner. Changing this implies a new text spanner. ") diff --git a/scm/lily.scm b/scm/lily.scm index 4add9c25c4..642904e4b9 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -392,7 +392,9 @@ is the first to satisfy CRIT "define-music-properties.scm" "auto-beam.scm" "chord-name.scm" + "define-translator-properties.scm" + "translation-functions.scm" "script.scm" "drums.scm" "midi.scm" diff --git a/scm/music-functions.scm b/scm/music-functions.scm index 5ca516c5bc..4d99d86e3e 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -1,33 +1,3 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; tuplets. - -(define-public (denominator-tuplet-formatter mus) - (number->string (ly:get-mus-property mus 'denominator))) - -(define-public (fraction-tuplet-formatter mus) - (string-append (number->string (ly:get-mus-property mus 'numerator)) - ":" - (number->string (ly:get-mus-property mus 'denominator)) - )) - -;; metronome marks -(define-public (make-metronome-markup event context) - (let* - ((dur (ly:get-mus-property event 'tempo-unit)) - (count (ly:get-mus-property event 'metronome-count)) - (note-mark (make-note-markup (ly:duration-log dur) - (ly:duration-dot-count dur) - 1) - ) - ) - - (make-line-markup - (list - note-mark - (make-simple-markup "=") - (make-simple-markup (number->string count)) - - )))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -108,6 +78,8 @@ music)) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; repeats. @@ -245,7 +217,8 @@ i.e. this is not an override" m )) - +;;;;;;;;;;;;;;;; +;; mmrest (define-public (make-multi-measure-rest duration location) (let* ( @@ -322,6 +295,57 @@ a property set for MultiMeasureRestNumber." m )) + + +(define-public (make-ottava-set octavation) + (let* + ( + (m (make-music-by-name 'ApplyContext)) + ) + + + (define (ottava-modify context) + "Either reset centralCPosition to the stored original, +or remember old centralCPosition, add OCTAVATION to centralCPosition, +and set OTTAVATION to `8va', or whatever appropriate. +" + (if (= octavation 0) + (let* + ((where (ly:context-property-where-defined context 'centralCPosition)) + (oc0 (ly:get-context-property context 'originalCentralCPosition)) + + ) + + (ly:set-context-property context 'centralCPosition oc0) + (ly:unset-context-property where 'originalCentralCPosition) + (ly:unset-context-property where 'ottavation) + ) + + (let* + ((where (ly:context-property-where-defined context 'centralCPosition)) + (c0 (ly:get-context-property context 'centralCPosition)) + (new-c0 (+ c0 (* -7 octavation))) + (string (cdr + (assoc octavation '((2 . "15ma") + (1 . "8va") + (0 . #f) + (-1 . "8va bassa") + (-2 . "15ma bassa"))))) + ) + + (ly:set-context-property where 'centralCPosition new-c0) + (ly:set-context-property where 'originalCentralCPosition c0) + (ly:set-context-property where 'ottavation string) + + ))) + + (ly:set-mus-property! m 'procedure ottava-modify) + m + )) + +(define-public (set-octavation ottavation) + (ly:export (make-ottava-set ottavation))) + (define-public (make-time-signature-set num den . rest) " Set properties for time signature NUM/DEN. Rest can contain a list of beat groupings diff --git a/scm/translation-functions.scm b/scm/translation-functions.scm new file mode 100644 index 0000000000..fc3dd63ac1 --- /dev/null +++ b/scm/translation-functions.scm @@ -0,0 +1,32 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; tuplets. + +(define-public (denominator-tuplet-formatter mus) + (number->string (ly:get-mus-property mus 'denominator))) + +(define-public (fraction-tuplet-formatter mus) + (string-append (number->string (ly:get-mus-property mus 'numerator)) + ":" + (number->string (ly:get-mus-property mus 'denominator)) + )) + + +;; metronome marks +(define-public (make-metronome-markup event context) + (let* + ((dur (ly:get-mus-property event 'tempo-unit)) + (count (ly:get-mus-property event 'metronome-count)) + (note-mark (make-note-markup (ly:duration-log dur) + (ly:duration-dot-count dur) + 1) + ) + ) + + (make-line-markup + (list + note-mark + (make-simple-markup "=") + (make-simple-markup (number->string count)) + + )))) + -- 2.39.2