convert MMREST-TEXT to MultiMeasureRestNumber settings.
* ly/engraver-init.ly (ScoreContext): move tablature settings to
ScoreContext
* scm/new-markup.scm (center-markup): \center markup.
* scm/music-functions.scm: remove pitchify scripts.
* lily/music.cc (print_smob): display music name if available
+2003-03-04 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * scm/music-functions.scm (glue-mm-rest-texts): automatically
+ convert MMREST-TEXT to MultiMeasureRestNumber settings.
+
+ * ly/engraver-init.ly (ScoreContext): move tablature settings to
+ ScoreContext
+
+ * scm/new-markup.scm (center-markup): \center markup.
+
+ * scm/music-functions.scm: remove pitchify scripts.
+
+ * lily/music.cc (print_smob): display music name if available
+
+2003-03-02 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * Documentation/user/refman.itely (Instrument names): remove
+ \turnOff doco.
+
2003-03-01 Han-Wen Nienhuys <hanwen@cs.uu.nl>
* lily/score.cc (mark_smob): bugfix.
@c FIXME: in Lyrics mode, we have " " and _
-In Lyrics mode, invisible rests are entered using either `@code{" "}'
+In Lyrics mode, you can make invisible syllables by entering `@code{" "}'
or `@code{_}':
@lilypond[singleline,verbatim]
<
\notes\relative c'' { a2 a4 a a2 a4 a }
>
@end lilypond
+In this case, syllables containing a space will be printed. In the
+case that you really need an invisible space (i.e. something taking up
+time, but not space), you should use @code{\skip}.
Note that the @code{s} syntax is only available in Note mode and Chord
mode. In other situations, you should use the @code{\skip} command,
c'' \< \! c'' d'' \decr e'' \rced
< f''1 { s4 s4 \< \! s4 \> \! s4 } >
@end lilypond
+This may give rise to very short hairpins. Use @code{minimum-length}
+in Voice.HairPin to lengthen these, e.g.
+
+@example
+ \property Staff.Hairpin \override #'minimum-length = #5
+@end example
You can also use a text saying @emph{cresc.} instead of hairpins. Here
is an example how to do it:
[TODO: Write subsection upon usage of ChoirStaff.]
+For entering quotes in Lyrics mode, use the following
+@example
+"\"God\"" is "`King'"
+@end example
+
+
+
@menu
* Ambitus::
@end menu
[ add note about breves.]
+@cindex text on multi-measure rest
+@cindex script on multi-measure rest
+@cindex fermata on multi-measure rest
+
+Texts can be added to multi-measure rests by using the
+@var{note}-@code{markup} syntax. An identifier
+is provided for a fermata.
+
+@lilypond[verbatim,fragment]
+ \time 3/4
+ R2._\markup { \roman "Ad lib" }
+ R2.^\fermataMarkup
+@end lilypond
+
@cindex whole rests for a full measure
The object for this object is @internalsref{MultiMeasureRest}, and
@refbugs
-Currently, there is no way to automatically condense multiple rests
-into a single multimeasure rest. Multi measure rests do not take part
-in rest collisions.
+Only one text can be put on a multi-measure rest with
+@var{note}-@var{text} syntax, since this is internally converted to
+setting @code{#'text} in @internalsref{MultiMeasureRestNumber}. It is
+not possible to use fingerings (e.g. @code{R1-4}) to put numbers over
+multi-measure rests.
-Multi-measure rests do not accept @var{note}-@code{text} syntax for
-putting texts and scripts on the rest. This has to be done by setting
-@code{#'text} in @internalsref{MultiMeasureRestNumber}. An identifier is
-provided for a fermata:
-@cindex text on multi-measure rest
-@cindex script on multi-measure rest
-@cindex fermata on multi-measure rest
-
-@lilypond[verbatim,fragment]
- \time 3/4
- \setMmRestFermata R2.
-@end lilypond
+@cindex condensing rests
+Currently, there is no way to automatically condense multiple rests
+into a single multimeasure rest. Multi measure rests do not take part
+in rest collisions.
-@cindex condensing rests
@node Automatic part combining
@subsection Automatic part combining
@code{\property}), you can change the resulting objects.
@lilypond[verbatim, fragment]
-c'4 \property Voice.Stem = #'()
+c'4 \property Voice.NoteHead = #'() c'4
@end lilypond
-
-The @code{\property} assignment effectively empties the definition of
-the Stem object. One of the effects is that the recipe of how it should be
-printed is erased, with the effect of rendering it invisible. The above
-assignment is available as a standard identifier, for the case that you
-find this useful:
-
-@example
- \property Voice.Stem = \turnOff
-@end example
-
-@cindex \override
-@cindex \revert
-@cindex \set
-
This mechanism is fairly crude, since you can only set, but not modify,
-the definition of a object. For this reason, there is a more advanced
-mechanism.
+the definition of an object. Also, it will thoroughly confuse LilyPond.
-The definition of a object is actually a list of default object
-properties. For example, the definition of the Stem object (available in
-@file{scm/grob-description.scm}), defines the following values for
+The definition of an object is actually a list of default object
+properties. For example, the definition of the Stem object (available
+in @file{scm/grob-description.scm}), includes the following definitions for
@internalsref{Stem}
@example
expressions, XML documents and music expressions. The braces group
notes into horizontal lines. Other types of lists also exist: you can
stack expressions grouped with @code{<<}, and @code{>>} vertically with
-the command @code{\column}.
+the command @code{\column}. Similarly, @code{\center} aligns texts by
+their center lines.
@lilypond[verbatim,fragment,relative=1]
- c1^\markup { \column << a b c >> }
+ c1^\markup { \column << a bbbb c >> }
+ c1^\markup { \center << a bbbb c >> }
c1^\markup { \line << a b c >> }
@end lilypond
+
+
The markup mechanism is very flexible and extensible. Refer to
@file{scm/new-markup.scm} for more information on extending the markup
mode.
-
-
@node Printing lyrics
@section Printing lyrics
@cindex lyrics
different voice, and blank the stem. This is done in the following
snippet of code.
+@cindex transparent objects
+@cindex removing objects
+@cindex invisible objects
@example
\property Voice.Stem \set #'transparent = ##t
d'
dnl aclocal.m4 -*-shell-script-*-
+dnl WARNING WARNING WARNING
+dnl do not edit! this is aclocal.m4, generated from /home/hanwen/usr/src/lilypond/stepmake/aclocal.m4
+dnl aclocal.m4 -*-shell-script-*-
dnl StepMake subroutines for configure.in
multi-measure-rest is a Spanner, minimum distances are set to keep it
colliding from barlines.
-Texts may be added to the rests by setting @code{text} in
-@code{MultiMeasureRestNumber.}
Rests over measures during longer than 2 wholes use breve rests.
"
\score { \notes {
\time 3/4 \key cis \major
R2.*15
- R2.
- \once \property Staff.MultiMeasureRestNumber \set #'text = #'(music "scripts-ufermata")
+
R2.
R2.*3
R2.*27
if (now_mom () > Moment (0))
txt = get_property ("instr");
+ /*
+ UGH.
+ */
+ if (txt == SCM_EOL)
+ return ;
- if (!new_markup_p (txt))
- return ;
-
text_ = new Item (get_property ("InstrumentName"));
if (text_->get_grob_property ("text") != txt)
{
scm_puts ("#<Music ", p);
Music* m = unsmob_music (s);
- scm_puts (classname (m),p);
+ SCM nm = m->get_mus_property ("name");
+ if (gh_symbol_p (nm) || gh_string_p (nm))
+ {
+ scm_display (nm, p);
+ }
+ else
+ {
+ scm_puts (classname (m),p);
+ }
+
/*
- Printing these takes a lot of time, especially during backtraces.
+ Printing properties takes a lot of time, especially during backtraces.
For inspecting, it is better to explicitly use an inspection
function.
*/
% weird effects when doing instrument names for
% piano staves
- instrument = ##f
- instr = ##f
+ instrument = #'()
+ instr = #'()
\accepts "Voice"
}
autoAccidentals = #'(Staff (same-octave . 0))
autoCautionaries = #'()
-
keyAccidentalOrder = #'(
(6 . -1) (2 . -1) (5 . -1 ) (1 . -1) (4 . -1) (0 . -1) (3 . -1)
(3 . 1) (0 . 1) (4 . 1) (1 . 1) (5 . 1) (2 . 1) (6 . 1)
chordNameSeparator = #(make-simple-markup "/")
chordNameExceptions = #ignatzekExceptions
+ %% tablature:
+ stringOneTopmost = ##t
+ highStringOne = ##t
+
+ %% One may change the strings tuning as following :
+ %% The lenght of the list must be equal to the number of string
+
+ stringTunings = #guitar-tunings
+ tablatureFormat = #fret-number-tablature-format
+
\grobdescriptions #all-grob-descriptions
}
StaffSymbol \override #'line-count = #6
StaffSymbol \override #'staff-space = #1.5
- stringOneTopmost = ##t
- highStringOne = ##t
-
- % One may change the strings tuning as following :
- % The lenght of the list must be equal to the number of string
- %TabNoteHead \override #'string-tunings = #'(10 10 10 10 10 10)
-
- % Special "TAB" clef
- clefGlyph = #"clefs-tab"
- clefPosition = #0
-
- % Don't draw stems over the tablature figures !
+ % Don't draw stems over the tablature figures !
Stem \override #'avoid-note-head = ##t
% No accidental in tablature !
\remove Accidental_engraver
\remove Key_engraver
- stringTunings = #guitar-tunings
- tablatureFormat = #fret-number-tablature-format
+ % Special "TAB" clef
+ clefGlyph = #"clefs-tab"
+ clefPosition = #0
+
}
arpeggio = #(make-music-by-name 'ArpeggioEvent)
glissando = #(make-music-by-name 'GlissandoEvent)
+fermataMarkup = \markup { \musicglyph #"scripts-ufermata" }
+
setMmRestFermata =
- \once \property Voice.MultiMeasureRestNumber \override #'text = #'(music "scripts-ufermata")
+ \once \property Voice.MultiMeasureRestNumber \override #'text =
+ #fermataMarkup
(define-public (number-or-string? x)
(or (number? x) (string? x)))
-(define-public (markup? x)
- (or (string? x) (list? x)
- (new-markup? x)))
-
(define-public (scheme? x) #t)
+
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
(MultiMeasureRestNumber
. (
- (molecule-callback . ,Text_item::brew_molecule)
+ (molecule-callback . ,brew-new-markup-molecule)
(X-offset-callbacks . (,Self_alignment_interface::aligned_on_self
,Self_alignment_interface::centered_on_other_axis_parent))
(Y-offset-callbacks . (,Side_position_interface::aligned_side))
;; why -list suffix (see reduce-list)
(define-public (filter-list pred? list)
- "return that part of LIST for which PRED is true."
+ "return that part of LIST for which PRED is true.
+
+ TODO: rewrite using accumulator. Now it takes O(n) stack. "
+
(if (null? list) '()
(let* ((rest (filter-list pred? (cdr list))))
(if (pred? (car list))
)
+(define-public (split-list l sep?)
+ "
+
+(display (split-list '(a b c / d e f / g) (lambda (x) (equal? x '/))) )
+=>
+((a b c) (d e f) (g))
+
+"
+
+(define (split-one sep? l acc)
+ "Split off the first parts before separator and return both parts.
+
+"
+ ;; " KUT EMACS
+ (if (null? l)
+ (cons acc '())
+ (if (sep? (car l))
+ (cons acc (cdr l))
+ (split-one sep? (cdr l) (cons (car l) acc))
+ )
+ ))
+
+(if (null? l)
+ '()
+ (let* ((c (split-one sep? l '())))
+ (cons (reverse! (car c) '()) (split-list (cdr c) sep?))
+ )
+ )
+)
+
+
(define (other-axis a)
(remainder (+ a 1) 2))
"chord-entry.scm"
"double-plus-new-chord-name.scm"
"molecule.scm"
+ "new-markup.scm"
"bass-figure.scm"
- "grob-property-description.scm"
- "context-description.scm"
- "interface-description.scm"
- "beam.scm"
- "clef.scm"
- "slur.scm"
- "font.scm"
"music-functions.scm"
"music-property-description.scm"
"auto-beam.scm"
- "new-markup.scm"
"basic-properties.scm"
"chord-name.scm"
- "grob-description.scm"
"translator-property-description.scm"
"script.scm"
"drums.scm"
"midi.scm"
+
+ "beam.scm"
+ "clef.scm"
+ "slur.scm"
+ "font.scm"
+
+ "grob-property-description.scm"
+ "grob-description.scm"
+ "context-description.scm"
+ "interface-description.scm"
))
(function music)
))
-(define-public (display-one-music music)
+(define-public (display-music music)
+ "Display music, not done with music-map for clarity of presentation."
(display music)
- (display (ly:get-mutable-properties music))
+ (display ": { ")
+
+ (let* ((es (ly:get-mus-property music 'elements))
+ (e (ly:get-mus-property music 'element))
+ )
+
+ (display (ly:get-mutable-properties music))
+
+ (if (pair? es)
+ (begin (display "\nElements: {\n")
+ (map display-music es)
+ (display "}\n")
+ ))
+
+
+ (if (ly:music? e)
+ (begin
+ (display "\nChild:")
+ (display-music e)
+ )
+ )
+ )
+ (display " }\n")
music
)
-(define-public (display-music arg)
- (music-map display-one-music arg))
+
+
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
music))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-
-(define (pitchify-scripts music)
- "Copy the pitch fields of the Note_requests into Text_script_requests, to aid
-Fingering_engraver."
- (define (find-note musics)
- (filter-list (lambda (m) (equal? (ly:music-name m) "Note_req")) musics)
- )
- (define (find-scripts musics)
- (filter-list (lambda (m) (equal? (ly:music-name m) "Text_script_req")) musics))
-
- (let* (
- (e (ly:get-mus-property music 'element))
- (es (ly:get-mus-property music 'elements))
- (notes (find-note es))
- (pitch (if (pair? notes) (ly:get-mus-property (car notes) 'pitch) #f))
- )
-
- (if pitch
- (map (lambda (x) (ly:set-mus-property! x 'pitch pitch)) (find-scripts es))
- )
-
- (if (pair? es)
- (ly:set-mus-property!
- music 'elements
- (map pitchify-scripts es)))
-
- (if (ly:music? e)
- (ly:set-mus-property!
- music 'element
- (pitchify-scripts e)))
-
- music))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; property setting music objs.
(define-public (make-grob-property-set grob gprop val)
- "Make a M-exp that sets GPROP to VAL in GROBS. Does a pop first,
+ "Make a Music expression that sets GPROP to VAL in GROB. Does a pop first,
i.e. this is not an override"
(let* ((m (make-music-by-name 'OverrideProperty)))
(skip ( make-music-by-name 'SkipEvent))
(ch (make-music-by-name 'BarCheck))
(ch2 (make-music-by-name 'BarCheck))
+ (seq (make-music-by-name 'MultiMeasureRestMusicGroup))
)
(ly:set-mus-property! start 'span-direction START)
(ly:set-mus-property! stop 'span-direction STOP)
(ly:set-mus-property! skip 'duration duration)
- (map (lambda (x) (ly:set-mus-property! x 'origin location))
- (list start stop skip ch ch2))
- (make-sequential-music
+ (ly:set-mus-property! seq 'elements
(list
ch
(make-event-chord (list start))
(make-event-chord (list stop))
ch2
))
+
+ seq
))
+(define-public (glue-mm-rest-texts music)
+ "Check if we have R1*4-\markup { .. }, and if applicable convert to
+a property set for MultiMeasureRestNumber."
+
+ (define (script-to-mmrest-text script-music)
+ "Extract 'direction and 'text from SCRIPT-MUSIC, and transform into property sets."
+
+ (let*
+ (
+ (text (ly:get-mus-property script-music 'text))
+ (dir (ly:get-mus-property script-music 'direction))
+ (p (make-grob-property-set 'MultiMeasureRestNumber 'text text))
+ (d (if (ly:dir? dir)
+ (make-grob-property-set 'MultiMeasureRestNumber 'direction dir)
+ #f))
+ (l (list p))
+ )
+ (ly:set-mus-property! p 'once #t)
+ (if d
+ (begin
+ (ly:set-mus-property! d 'once #t)
+ (set! l (cons d l))))
+
+ (context-spec-music (make-sequential-music l) "Voice")
+ ))
+
+ (if (eq? (ly:get-mus-property music 'name) 'MultiMeasureRestMusicGroup)
+ (let*
+ (
+ (text? (lambda (x) (memq 'script-event (ly:get-mus-property x 'types))))
+ (es (ly:get-mus-property music 'elements))
+ (texts (filter-list text? es))
+ (others (filter-out-list text? es))
+ )
+ (if (pair? texts)
+ (ly:set-mus-property!
+ music 'elements
+ (cons (script-to-mmrest-text (car texts))
+ others))
+ )
+ ))
+ music
+ )
+
(define-public (make-property-set sym val)
(let*
(memq 'separator ts)
))
-(define (split-one sep? l acc)
- "Split off the first parts before separator and return both parts.
-
-"
- (if (null? l)
- (cons acc '())
- (if (sep? (car l))
- (cons acc (cdr l))
- (split-one sep? (cdr l) (cons (car l) acc))
- )
- ))
-
-(define-public (split-list l sep?)
- "
-
-(display (split-list '(a b c / d e f / g) (lambda (x) (equal? x '/))) )
-=>
- ...
-
-"
- (if (null? l)
- '()
- (let* ((c (split-one sep? l '())))
- (cons (reverse! (car c) '()) (split-list (cdr c) sep?))
- )
- )
- )
;;; splitting chords into voices.
))
(define (ly:music-message music msg)
- (let* (
+ (let*
+ (
(ip (ly:get-mus-property music 'origin))
)
(define-public toplevel-music-functions
(list check-start-chords
voicify-music
-
+ (lambda (x) (music-map glue-mm-rest-texts x))
; switch-on-debugging
))
(iterator-ctor . ,Sequential_music_iterator::constructor)
(types . (general-music sequential-music))
))
+
+ (MultiMeasureRestMusicGroup
+ . (
+ (description . "Like sequential-music, but specifically intended
+to group start-mmrest, skip, stop-mmrest sequence. Syntax @code{R2.*5} for 5 measures in 3/4 time.")
+ (internal-class-name . "Sequential_music")
+ (iterator-ctor . ,Sequential_music_iterator::constructor)
+ (types . (general-music sequential-music))
+ ))
+
(SimultaneousMusic
. (
(description . "Music playing together. Syntax: \\simultaneous @{ .. @} or < .. >.")
(TimeScaledMusic
. (
(description . "Multiply durations, as in tuplets. Syntax @code{\\times @var{fraction} @var{music}}, e.g.
-@code{\\times 2/3 { ... }} for triplets.
-
+@code{\\times 2/3 @{ ... @}} for triplets.
")
(internal-class-name . "Time_scaled_music")
(iterator-ctor . ,Time_scaled_music_iterator::constructor)
(font-markup 'font-series 'bold))
(define-public number-markup
(font-markup 'font-family 'number))
-
+(define-public roman-markup
+ (font-markup 'font-family 'roman))
(define-public huge-markup
(font-markup 'font-relative-size 2))
(map (lambda (x) (interpret-markup grob props x)) (car rest)))
)
+(define-public (center-markup grob props . rest)
+ (let*
+ (
+ (mols (map (lambda (x) (interpret-markup grob props x)) (car rest)))
+ (cmols (map (lambda (x) (ly:align-to! x X CENTER)) mols))
+ )
+
+ (stack-lines
+ -1 0.0 (cdr (chain-assoc 'baseline-skip props))
+ mols)
+ ))
+
(define-public (musicglyph-markup grob props . rest)
(ly:find-glyph-by-name
(ly:get-font grob (cons '((font-family . music)) props))
;;
(define markup? cheap-markup?)
-
(define markup-function-list
(list
(cons bold-markup (list markup?))
(cons italic-markup (list markup?))
-
+ (cons roman-markup (list markup?))
(cons number-markup (list markup?))
(cons column-markup (list markup-list?))
+ (cons center-markup (list markup-list?))
(cons line-markup (list markup-list?))
(cons combine-markup (list markup? markup?))
(cons simple-markup (list string?))
(cons musicglyph-markup (list scheme?))
-
(cons translate-markup (list number-pair? markup?))
(cons override-markup (list pair? markup?))
(cons char-markup (list integer?))