From: hanwen Date: Sat, 30 Aug 2003 21:35:56 +0000 (+0000) Subject: * scm/music-functions.scm (remove-tag): filter \tagged music X-Git-Tag: release/1.9.5~20 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=362c39dacaa4a9cf1ee99ecc7a0f26af1514dd2e;p=lilypond.git * scm/music-functions.scm (remove-tag): filter \tagged music expressions. * input/regression/tag-filter.ly (texidoc): new file. * lily/parser.yy (post_event): add \tag #'symbol / \tag #'(symbol1 symbol2 .. ) etc. * Documentation/user/refman.itely (Fingering instructions): adjust manual. --- diff --git a/ChangeLog b/ChangeLog index 26df67e1a8..26bb357369 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2003-08-30 Han-Wen Nienhuys + * scm/music-functions.scm (remove-tag): filter \tagged music + expressions. + + * input/regression/tag-filter.ly (texidoc): new file. + + * lily/parser.yy (post_event): add \tag #'symbol / \tag #'(symbol1 + symbol2 .. ) etc. + * scripts/convert-ly.py (FatalConversionError.conv): fingering convert rule. diff --git a/Documentation/topdocs/NEWS.texi b/Documentation/topdocs/NEWS.texi index b0b4ec04c6..bf4aacc5c6 100644 --- a/Documentation/topdocs/NEWS.texi +++ b/Documentation/topdocs/NEWS.texi @@ -8,6 +8,35 @@ @chapter New features in 1.9 since 1.8 @itemize + +@item +Each music expression can now be tagged, to make different printed +versions from the same music expression. In the following example, +we see two versions of a piece of music, one for the full score, and +one with cue notes for the instrumental part: +@example +< \tag #'part < + @{ c4 f2 g @} % in the part, we have cue-notes + \\ R1 > + \tag #'score R1 % in the score: only a rest +> +@end example + +The same can be applied to articulations, texts, etc.: they are +made by prepending +@example + -\tag #@var{your-tag(s)} +@end example +to an articulation, for example, +@example + c4-\tag #'with-fingerings -4 -\tag #'with-strings \6 +@end example + +This defines a note, which has a fingering and a string-number +indication. + + + @item Markup text (ie. general text formatting) may now be used for lyrics too. diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 8423e5c64e..94bb40d6c3 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -4432,6 +4432,65 @@ in this example disappears in the second line: @end lilypond +@node Different editions from one source +@subsection Different editions from one source + +The @code{\\tag} command marks music expressions with a name. These +tagged expressions can be filtered out later. With this mechanism it +is possible to make different versions of the same music source. + +In the following example, we see two versions of a piece of music, one +for the full score, and one with cue notes for the instrumental part: + +@example + c1 + \relative c' < + \tag #'part < + R1 \\ + { + \property Voice.fontSize = #-1 + c4_"cue" f2 g4 } + > + \tag #'score R1 + > +@end example + +The same can be applied to articulations, texts, etc.: they are +made by prepending +@example + -\tag #@var{your-tag} +@end example +to an articulation, for example, +@example + c1-\tag #'part ^4 +@end example + +This defines a note with a conditional fingering indication. + +By applying the @code{remove-tag} function, tagged expressions can be +filtered. For example, +@example +\simultaneous { + @var{the music} + \apply #(remove-tag 'score) @var{the music} + \apply #(remove-tag 'part) @var{the music} +} +@end example +would yield + +@lilypondfile[notexidoc]{tag-filter.ly} + +The argument of the @code{\tag} command should be a symbol, or a list +of symbols, for example, +@example + \tag #'(original-part transposed-part) @dots{} +@end example + +@seealso + +@inputfileref{input/regression,tag-filter.ly} + + @node Sound output for transposing instruments @subsection Sound output for transposing instruments diff --git a/input/regression/tag-filter.ly b/input/regression/tag-filter.ly new file mode 100644 index 0000000000..e7d5915276 --- /dev/null +++ b/input/regression/tag-filter.ly @@ -0,0 +1,53 @@ + +\version "1.9.3" +\header { + +texidoc = "The @code{\\tag} command marks music expressions with a +name. These tagged expressions can be filtered out later. This +mechanism can be used to make different versions of the same music. In +this example, the top stave displays the music expression with all +tags included. The bottom two staves are filtered: the part has cue +notes and fingerings, but the score has not." + +} + +\paper { raggedright= ##t } + +common = +\notes \relative c'' { + + c1 + \relative c' < + \tag #'part < + R1 \\ + { + \property Voice.fontSize = #-1 + c4_"cue" f2 g4 } + > + \tag #'score R1 + > + c1-\tag #'part ^4 +} + + +\score { + \notes \simultaneous { + \new Staff { + \property Staff.instrument = #"both" + \common + } + \new Staff { + \property Staff.instrument = #"part" + \apply #(remove-tag 'score) \common + } + \new Staff { + \property Staff.instrument = #"score" + \apply #(remove-tag 'part) \common + } + } +} + + + + + diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index 1e63016cbf..b2f154f92c 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -80,6 +80,7 @@ static Keyword_ent the_key_tab[]={ {"set", SET}, {"simultaneous", SIMULTANEOUS}, {"skip", SKIP}, + {"tag", TAG}, {"tempo", TEMPO}, {"time", TIME_T}, {"times", TIMES}, diff --git a/lily/parser.yy b/lily/parser.yy index 2b8ec7198c..e8c710b8ac 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -96,7 +96,23 @@ My_lily_parser* my_lily_parser; #define yyerror THIS->parser_error +/* + Add symbols to the TAGS field of a music object. +*/ +void +tag_music (Music*m, SCM tag, Input ip) +{ + SCM tags = m->get_mus_property ("tags"); + if (gh_symbol_p (tag)) + tags = scm_cons (tag, tags); + else if (gh_list_p (tag)) + tags = gh_append2 (tag, tags); + else + ip.warning (_("Tag must be symbol or list of symbols.")); + + m->set_mus_property ("tags", tags); +} @@ -278,6 +294,7 @@ yylex (YYSTYPE *s, void * v) %token SIMULTANEOUS %token SKIP %token SPANREQUEST +%token TAG %token TEMPO %token TIMES %token TIME_T @@ -352,7 +369,7 @@ yylex (YYSTYPE *s, void * v) %type steno_duration optional_notemode_duration multiplied_duration %type verbose_duration -%type post_events +%type post_events %type gen_text_def direction_less_event direction_reqd_event %type steno_pitch pitch absolute_pitch pitch_also_in_chords %type explicit_pitch steno_tonic_pitch @@ -367,7 +384,7 @@ yylex (YYSTYPE *s, void * v) %type Music_list %type music_output_def_body %type shorthand_command_req -%type post_event +%type post_event tagged_post_event %type command_req verbose_command_req %type extender_req %type hyphen_req @@ -1092,7 +1109,11 @@ basic music objects too, since the meaning is different. } | relative_music { $$ = $1; } | re_rhythmed_music { $$ = $1; } - | part_combined_music { $$ = $1; } + | part_combined_music { $$ = $1; } + | TAG embedded_scm Music { + tag_music ($3, $2, THIS->here_input ()); + $$ = $3; + } ; relative_music: @@ -1510,20 +1531,33 @@ post_events: $$ = gh_cons ($2->self_scm(), $$); scm_gc_unprotect_object ($2->self_scm()); } + | post_events tagged_post_event { + $2 -> set_spot (THIS->here_input ()); + $$ = scm_cons ($2->self_scm(), $$); + scm_gc_unprotect_object ($2->self_scm()); + } ; +tagged_post_event: + '-' TAG embedded_scm post_event { + tag_music ($4, $3, THIS->here_input ()); + $$ = $4; + } + ; post_event: direction_less_event { $$ = $1; } | script_dir direction_reqd_event { - $2->set_mus_property ("direction", gh_int2scm ($1)); + if ($1) + $2->set_mus_property ("direction", gh_int2scm ($1)); $$ = $2; } | script_dir direction_less_event { - $2->set_mus_property ("direction", gh_int2scm ($1)); + if ($1) + $2->set_mus_property ("direction", gh_int2scm ($1)); $$ = $2; } | string_number_event diff --git a/scm/define-music-properties.scm b/scm/define-music-properties.scm index e705f24b59..705706a735 100644 --- a/scm/define-music-properties.scm +++ b/scm/define-music-properties.scm @@ -42,6 +42,10 @@ TODO: consider making type into symbol ") (music-property-description 'denominator integer? "denominator in a time signature") (music-property-description 'digit integer? "digit for fingering") (music-property-description 'direction ly:dir? "Print this up or down?") +(music-property-description 'tags list? "List of symbols that for denoting extra details, +eg. @code{\\tag #'part ...} could tag a piece of music as only being active in a part.") + + (music-property-description 'text-type symbol? "Particular type of text script (eg. finger, dynamic).") (music-property-description 'tempo-unit ly:duration? "The unit for the metronome count.") (music-property-description 'tonic ly:pitch? "Base of the scale") diff --git a/scm/music-functions.scm b/scm/music-functions.scm index 431b9bdc30..591468c510 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -1,4 +1,3 @@ - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define-public (music-map function music) @@ -14,6 +13,48 @@ (function music) )) +(define-public (music-filter pred? music) + "Filter out music expressions that do not satisfy PRED." + + (define (inner-music-filter pred? music) + "Recursive function." + (let* ((es (ly:get-mus-property music 'elements)) + (e (ly:get-mus-property music 'element)) + (as (ly:get-mus-property music 'articulations)) + (filtered-as (filter ly:music? (map (lambda (y) (inner-music-filter pred? y)) as))) + (filtered-e (if (ly:music? e) + (inner-music-filter pred? e) + e)) + (filtered-es (filter ly:music? (map (lambda (y) (inner-music-filter pred? y)) es))) + ) + + (ly:set-mus-property! music 'element filtered-e) + (ly:set-mus-property! music 'elements filtered-es) + (ly:set-mus-property! music 'articulations filtered-as) + + ;; if filtering emptied the expression, we remove it completely. + (if (or (pred? music) + (and (eq? filtered-es '()) (not (ly:music? e)) + (or (not (eq? es '())) + (ly:music? e)))) + (set! music '())) + + music)) + + (set! music (inner-music-filter pred? music)) + (if (ly:music? music) + music + (make-music-by-name 'Music) ;must return music. + )) + +(define-public (remove-tag tag) + (lambda (mus) + (music-filter + (lambda (m) + (let* ((tags (ly:get-mus-property m 'tags)) + (res (memq tag tags))) + res)) mus))) + (define-public (display-music music) "Display music, not done with music-map for clarity of presentation." (display music)