From: Han-Wen Nienhuys Date: Mon, 14 Jul 2003 23:49:33 +0000 (+0000) Subject: (An orchestral part): new X-Git-Tag: release/1.7.26~41 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=b4139c2fb2ec738a17ee1157edf23e8ea56ed560;p=lilypond.git (An orchestral part): new section on orchestral stuff and identifiers. * lily/spacing-spanner.cc (musical_column_spacing): use average, not maximum of spacing wishes in polyphonic situations. * scm/define-grobs.scm (all-grob-descriptions): bold tuplet number * lilypond-indent.el: remove paren matching. * lily/text-item.cc (interpret_new_markup): new function use iso. text2molecule. * lily/main.cc (notice): change FSF address * po/de.po: update PO file to 1.6. --- diff --git a/ChangeLog b/ChangeLog index 61842abdf6..2acf0f4c8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-07-15 Han-Wen Nienhuys + + * Documentation/user/tutorial.itely (An orchestral part): new + section on orchestral stuff and identifiers. + 2003-07-14 Heikki Junes * lilypond-mode.el: comment-out paren-highlighting, it still causes @@ -5,6 +10,17 @@ 2003-07-14 Han-Wen Nienhuys + * lily/spacing-spanner.cc (musical_column_spacing): use average, + not maximum of spacing wishes in polyphonic situations. + + * scm/define-grobs.scm (all-grob-descriptions): bold tuplet + number + + * lilypond-indent.el: remove paren matching. + + * lily/text-item.cc (interpret_new_markup): new function + use iso. text2molecule. + * lily/main.cc (notice): change FSF address * po/de.po: update PO file to 1.6. diff --git a/Documentation/user/internals.itely b/Documentation/user/internals.itely index e9b5aef53f..a2cd3b74a0 100644 --- a/Documentation/user/internals.itely +++ b/Documentation/user/internals.itely @@ -508,10 +508,12 @@ The following list are all lilypond specific types, that can exist during parsing: @table @code @item Duration -@item Identifier @item Input @item Moment @item Music +@item Event +In C++ terms, an @code{Event} is a subtype of @code{Music}. However, +both have different functions in the syntax. @item Music_output_def @item Pitch @item Score @@ -533,8 +535,8 @@ including dimensions. @item Spring_smob -@item Translator: An object that produces audio objects or Grobs. This is -not yet user-accessible. +@item Translator: An object that produces audio objects or Grobs. +It may be accessed with @code{\applyoutput}. @item Font_metric: An object representing a font. @end table diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 4d315ade8e..e542edc3a1 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -31,7 +31,7 @@ * Vocal music:: * Tablatures:: * Chord names:: -* Writing parts:: +* Orchestral music:: * Ancient notation :: * Contemporary notation:: * Tuning output:: @@ -549,7 +549,7 @@ shown on screen. See @ref{Point and click} for more information. * Relative octaves:: * Bar check:: * Skipping corrected music:: -* Automatic note splitting:: +* Automatic note splitting :: @end menu @@ -761,7 +761,7 @@ exactly on the barline. @node Key signature @subsection Key signature -@cindex Key +@cindex Key signature @cindex @code{\key} @@ -1636,7 +1636,7 @@ for the problematic notes. @section Expressive marks @menu -* Slurs:: +* Slurs :: * Phrasing slurs:: * Breath marks:: * Metronome marks:: @@ -3812,8 +3812,10 @@ may result in strange chord names when chords are entered with the -@node Writing parts -@section Writing parts +@node Orchestral music +@section Orchestral music + +@cindex Writing parts Orchestral music involves some special notation, both in the full score and the individual parts. This section explains how to tackle @@ -3822,6 +3824,7 @@ some common problems in orchestral music. @menu +* Multiple staff contexts:: * Rehearsal marks:: * Bar numbers:: * Instrument names:: @@ -3832,6 +3835,28 @@ some common problems in orchestral music. * Sound output for transposing instruments:: @end menu +@node Multiple staff contexts +@subsection Multiple staff contexts + +Polyphonic scores consist of many staffs. These staffs can be +constructed in three different ways: +@itemize @bullet +@item The group is started with a brace at the left. This is done with the +@internalsref{GrandStaff} context. +@item The group is started with a bracket. This is done with the +@internalsref{StaffGroup} context +@item The group is started with a vertical line. This is the default +for the score. +@end itemize + +@cindex Staff, multiple +@cindex bracket, vertical +@cindex brace, vertical +@cindex grand staff +@cindex staff group + + + @node Rehearsal marks @subsection Rehearsal marks @@ -6655,7 +6680,7 @@ affecting a whole set of objects. Second, you can select one specific object, and set a object property in that object. @menu -* Tuning objects:: +* Tuning objects :: * Constructing a tweak:: * Applyoutput:: * Outputproperty:: diff --git a/Documentation/user/tutorial.itely b/Documentation/user/tutorial.itely index 61bcb61b92..02a1b992be 100644 --- a/Documentation/user/tutorial.itely +++ b/Documentation/user/tutorial.itely @@ -19,8 +19,8 @@ * Printing lyrics:: * A lead sheet:: * Listening to output:: -* Titling:: -* Single staff polyphony:: +* Titling :: +* Single staff polyphony :: * Piano staffs:: * Setting variables:: * Fine tuning layout:: @@ -178,9 +178,8 @@ s16_" " Clefs are fully explained in @ref{Clef}. -When you enter these commands in a file, you must to enclose them in -@code{\notes @{@dots{}@}}. This lets LilyPond know that music (as -opposed to @rglos{lyrics}) follows: +These commands must be enclosed in @code{\notes @{@dots{}@}}. This +indicates that music (as opposed to @rglos{lyrics}) follows: @example \notes @{ @@ -632,6 +631,16 @@ a8-[ ais-] d-[ es r d-] @end quotation @separate +@menu +* Combining music into compound expressions:: +* Adding articulation marks to notes :: +* More basic rhythms:: +* Commenting input files:: +@end menu + +@node Combining music into compound expressions +@subsection Combining music into compound expressions + To print more than one staff, each piece of music that makes up a staff is marked by adding @code{\context Staff} before it. These @code{Staff}'s are then grouped inside @code{\simultaneous @{} and @code{@}}, as is @@ -681,11 +690,50 @@ We can now typeset a melody with two staves: @end lilypond @end quotation -The time signature is specified in one melody staff only -(the top staff), but is printed on both, since common practice -dictates that all staves have the same time signature. +The example shows how small chunks of music, for example the notes +@code{c2}, @code{e4}, etc. of the second staff, are combined to form a +larger chunk by enclosing it in braces. Again, a larger chunk is +formed by prefix @code{\context Staff} to it, and that chunk is +combined with @code{< >}. This mechanism is similar with mathematical +formulas: in a formula, a so-called expression is formed by combining +simpler expressions into larger expressions. For example, -@separate +@quotation + 1 + + 1 + 2 + + (1 + 2) * 3 + + ((1 + 2) * 3) / (4 * 5) +@end quotation +is a sequence of expressions, where each expression is contained in +the next one. The simplest expressions are numbers and operators +(like +, * and /). Parentheses are used to group expressions. In +LilyPond input, a similar mechanism is used. Here, the simplest +expressions are notes and rests. By enclosing expressions in @code{< +>} and @code{@{ @}}, more complex music is formed. The @code{\context} +also forms new expressions; it is prepended to a music expression. + +When spreading expressions over multiple lines, it is customary to use +an indent that indicates the nesting level. Formatting music like this +eases reading, and helps you insert the right amount of closing +braces at the end of an expression. For example +@example +\score @{ + \notes < + @{ + @dots{} + @} + @{ + @dots{} + @} + > +@} +@end example + +@node Adding articulation marks to notes +@subsection Adding articulation marks to notes Common accents can be added to a note using @code{-.}, @code{--}, @code{->}: @quotation @@ -702,9 +750,6 @@ and the digit to be printed. @end lilypond - - - Dynamic signs are made by adding the markings to the note: @quotation @lilypond[verbatim,relative 1] @@ -753,6 +798,9 @@ r4 <>8-\>-( <> <> <>8-\!-) @separate +@node More basic rhythms +@subsection More basic rhythms + A pickup (or upstep) is entered with the keyword @code{\partial}. It is followed by a duration: @code{\partial 4} is a quarter note upstep and @code{\partial 8} an eighth note. @@ -782,6 +830,9 @@ a keyword. In this case, the keyword is @code{\grace}. More information on the use of grace notes is in @ref{Grace notes}. +@node Commenting input files +@subsection Commenting input files + Comments are pieces of the input that are ignored. There are two types of comments. A line comments are introduced by @code{%}: after that, the rest of that line is ignored. Block comments span larger @@ -1072,7 +1123,7 @@ voices with @code{\\}: < @{ a4 g2 f4-~ f4 @} \\ @{ r4 g4 f2 f4 @} > @end example -@lilypond[relative=2] +@lilypond[relative 1] \context Staff < { a4 g2 f4-~ f4 } \\ { r4 g4 f2 f4 } > @end lilypond @@ -1084,7 +1135,7 @@ temporarily do not play: < @{ a4 g2 f4-~ f4 @} \\ @{ s4 g4 f2 f4 @} > @end example -@lilypond[relative=2] +@lilypond[relative 1] \context Staff < { a4 g2 f4-~ f4 } \\ { s4 g4 f2 f4 } > @end lilypond @@ -1263,7 +1314,7 @@ little to the left, and 1.8 staff space downwards. @cindex setting object properties -@lilypond[relative 2,verbatim] +@lilypond[relative 1,verbatim] \stemUp f-5 \once \property Voice.Fingering @@ -1308,35 +1359,165 @@ discusses in depth how to figure out these statements for yourself, in @node Organizing larger pieces @section Organizing larger pieces -TODO: discuss identifiers, include files, \version. +When all of the elements discussed earlier are combined to produce +larger files, the @code{\score} blocks get a lot bigger, because the +music expressions are longer, and, in the case of polyphonic and/or +orchestral pieces, more deeply nested. + +By using variables, also known as identifiers, it is possible to break +up complex music expressions. +An identifier is assigned as follows +@example + namedMusic = \notes @{ @dots{} +@end example + +The contents of the music expression @code{namedMusic}, can be used +later by preceding the name with a backslash, i.e. @code{\namedMusic}. +For example + +@lilypond[singleline,verbatim] +seufzer = \notes { + dis'8 e'8 +} +\score { \notes { + \seufzer \seufzer +} } +@end lilypond + +The name of an identifier should only have alphabetic characters only, +and no numbers, underscores or dashes. The assignment should be +outside of the @code{\score} block. +It is possible to use variables for many other types of objects in the +input. For example, +@example + width = 1.5\cm + name = "Wendy" + aFivePaper = \paper @{ paperheight = 22.7 \cm @} +@end example +Depending on its contents, the identifier can be used in different +places. The following example uses the above variables: +@example + \score @{ + \notes @{ c4^\name @} + \paper @{ + \aFivePaper + linewidth = \width + @} + @} +@end example + +More information on the possible uses of identifiers is in the +technical manual, in @ref{Scheme datatypes}. @node An orchestral part @section An orchestral part -TODO: +In orchestral music, all notes are printed twice: both in a part for +the musicians, and in a full score for the which is printed both in +parts as in full score. Identifiers can be used to avoid double work: +the music is entered once, and stored in an variables. The contents of +that variable is then used to generate both the part and the score. -\markup, mmrest, transposing, cue notes +It is convenient to define the notes in a special file, for example, +suppose that the following is in @file{horn-music.ly}: +@example +hornNotes = \notes \relative c @{ + \time 2/4 + r4 f8 a cis4 f e d +@} +@end example +Then, an individual part is made by putting the following in a file +@example +\include "horn-music.ly" +\header @{ + instrument = "Horn in F" +@} +\score @{ + \notes \transpose c' f \hornNotes +@} +@end example +The @code{\include} command substitutes the contents of the file at +this position in the file, so that @code{hornNotes} is defined +afterwards. Since the horn is tuned in F, the @code{\transpose} +command is used. The code @code{\transpose c' f} indicates that the +argument, being @code{\hornNotes} should be transposed by a fifth +downwards: the @code{c'} becomes a @code{f}. The transposition can be +seen in the following output: + +@lilypond[singleline] +\score { + \notes \transpose c' f \notes \relative c' { + \time 2/4 + r4 f8 a cis4 f e d +} +} +@end lilypond +In ensemble pieces, one of the voices often does not play for many +measures. This is denoted by a special rest, the multi-measure +rest. It is entered with a capital R, and followed by a duration (1 +for a whole note, 2 for a half note, etc.) By multiplying the +duration, longer rests can be constructed. For example, the next rest +takes 3 measures in 2/4 time. +@example + R2*3 +@end example + +When printing the part, the following @code{skipBars} property must be +set to false, to prevent the rest from being expanded in three one bar +rests. +@example + \property Score.skipBars = ##t +@end example + +The result would look like + +@lilypond[singleline] +\score {\notes { \transpose c' f \relative c' { \time 2/4 +\property Score.skipBars = ##t + R2*3 + r4 f8 a cis4 f e d } }} +@end lilypond + +The score is made by combining all of the music in a @code{\score} +block, assuming that the other voice is in @code{hornNotes}, in the +file @file{horn-music.ly}: +@example +\include "fagot-music.ly" +\include "horn-music.ly" + +\score @{ + \simultaneous @{ + \context Staff = hornStaff \hornNotes + \context Staff = fagStaff \fagottoNotes + @} @} +@end example + +This would lead to the following output: + +@lilypond[singleline] +\score { + \notes \relative c \simultaneous { + \context Staff = hornStaff { \time 2/4 + R2*3 + r4 f8 a cis4 f e d } + \context Staff = fagStaff { \clef bass + r4 d,8 f | gis4 c | b bes | + a8 e f4 | g d | gis f } + } } +@end lilypond + +More in depth information is in the notation manual, in +@ref{Orchestral music}. -@separate -@example -\version "1.5.72" -@end example -Lilypond and its language are still under development, and -occasionally details of the syntax are changed. The @code{version} -fragment indicates which LilyPond version the input file was written -for. When you compile this file, the version number will be -checked. When the file is too old, a warning is issued. The version -number is also used by the @code{convert-ly} program (See -@ref{Invoking convert-ly}), which updates the file to the latest -version automatically. @node Integrating text and music @section Integrating text and music +TODO: shorten. @cindex La@TeX{}, music in @cindex HTML, music in diff --git a/input/mutopia/W.A.Mozart/mozart-hrn3-allegro.ly b/input/mutopia/W.A.Mozart/mozart-hrn3-allegro.ly index 78d3efe1ed..7ffe6dac44 100644 --- a/input/mutopia/W.A.Mozart/mozart-hrn3-allegro.ly +++ b/input/mutopia/W.A.Mozart/mozart-hrn3-allegro.ly @@ -14,7 +14,7 @@ allegro = c'2^"Tutti" g c, r R1*1 - r8 [g' g g] g-[ g e c] + r8 g' g g g g e c g'4 g, r2 R1*18 r2 r4^"Solo" g'4 | diff --git a/input/mutopia/W.A.Mozart/mozart-hrn3-rondo.ly b/input/mutopia/W.A.Mozart/mozart-hrn3-rondo.ly index 926dba257c..4d3bcd6227 100644 --- a/input/mutopia/W.A.Mozart/mozart-hrn3-rondo.ly +++ b/input/mutopia/W.A.Mozart/mozart-hrn3-rondo.ly @@ -107,7 +107,7 @@ rondo = \notes \relative c' a4 ( c8-) f4 ( b,8-) d4. ( c8-) r r R2.*3| - r4 r8 r4 c'8 + r4 r8 r4 c8 b4( c8-) b4( c8-) bes4. ~ bes4 g8 a4 c8 f-[ ( d-) b!] @@ -115,8 +115,8 @@ rondo = \notes \relative c' \mark "E" R2.*9 | \lipbreaker - c8-[ c' c] c4.~ - c8-[ c d] e-[ e fis] + c8-[ c' c] c4.~ + c8-[ c d] e-[ e fis] g4 r8 r4 r8 R2. r8 g,-[ g] g-[ g g] | @@ -181,10 +181,6 @@ rondo = \notes \relative c' c4 r8 r4 r8 \bar "|." } - - - - \score { \notes { \transpose c' bes \rondo } diff --git a/lily/beam.cc b/lily/beam.cc index ed397d98bd..f949c8f230 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -481,8 +481,8 @@ Beam::brew_molecule (SCM grob) SCM properties = Font_interface::font_alist_chain (me); - - Molecule tm = Text_item::text2molecule (me, scm_makfrom0str (str.to_str0 ()), properties); + Molecule tm = Text_item::interpret_new_markup + (me->self_scm(), properties, scm_makfrom0str (str.to_str0 ())); the_beam.add_at_edge (Y_AXIS, UP, tm, 5.0, 0); } #endif diff --git a/lily/breathing-sign.cc b/lily/breathing-sign.cc index 2936777e1e..4f0b37190b 100644 --- a/lily/breathing-sign.cc +++ b/lily/breathing-sign.cc @@ -28,6 +28,11 @@ * stafflinethickness) rather than hardwired to (staff_space / 6). */ +/* + WTF: what does Breathing_sign have to do with text?! + + --hwn + */ MAKE_SCHEME_CALLBACK (Breathing_sign,brew_molecule,1); SCM Breathing_sign::brew_molecule (SCM smob) @@ -37,8 +42,7 @@ Breathing_sign::brew_molecule (SCM smob) if (text == SCM_EOL) return divisio_minima (smob); SCM properties = Font_interface::font_alist_chain (me); - Molecule out; - out = Text_item::text2molecule (me, text, properties); + Molecule out = Text_item::interpret_new_markup (smob, properties, text); SCM space_scm = me->get_grob_property ("word-space"); if (gh_number_p (space_scm)) { diff --git a/lily/include/text-item.hh b/lily/include/text-item.hh index 1bbd4a689e..bc7f7f782f 100644 --- a/lily/include/text-item.hh +++ b/lily/include/text-item.hh @@ -24,7 +24,7 @@ public: static Molecule string2molecule (Grob *me, SCM text, SCM properties); static Molecule markup_text2molecule (Grob *me, SCM markup_text, SCM properties); static bool has_interface (Grob*); - + static Molecule interpret_new_markup (SCM grob, SCM achain, SCM markup); private: static Molecule lookup_character (Grob *me, Font_metric*, SCM char_name); static Molecule lookup_text (Grob *me, Font_metric*, SCM text); diff --git a/lily/paper-column.cc b/lily/paper-column.cc index eab3671d1a..8b990511f5 100644 --- a/lily/paper-column.cc +++ b/lily/paper-column.cc @@ -120,8 +120,8 @@ Paper_column::brew_molecule (SCM p) String r = to_string (Paper_column::get_rank (me)); SCM properties = Font_interface::font_alist_chain (me); - Molecule t = Text_item::text2molecule (me, scm_makfrom0str (r.to_str0 ()), - properties); + Molecule t = Text_item::interpret_new_markup (p, properties, + scm_makfrom0str (r.to_str0 ())); t.align_to (X_AXIS, CENTER); t.align_to (Y_AXIS, DOWN); diff --git a/lily/parser.yy b/lily/parser.yy index aff60db1e3..3f740e4d65 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -294,7 +294,7 @@ yylex (YYSTYPE *s, void * v) %token DURATION_IDENTIFIER %token FRACTION %token IDENTIFIER -%token CHORDNAMES CHORDNAMES_IDENTIFIER +%token CHORDNAMES %token CHORD_MODIFIER diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 5a889c74b4..72d72af0eb 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -553,9 +553,10 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real inc bool expand_only = false; Real base_note_space = note_spacing (me, lc, rc, shortest, &expand_only); - Real max_note_space = -infinity_f; - Real max_fixed_note_space = -infinity_f; - + Real compound_note_space = 0.0; + Real compound_fixed_note_space = 0.0; + int wish_count = 0; + SCM seq = lc->get_grob_property ("right-neighbors"); /* @@ -581,8 +582,12 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real inc Real fixed =0.0; Note_spacing::get_spacing (wish, rc, base_note_space, increment, &space, &fixed); - max_note_space = max_note_space >? space; - max_fixed_note_space = max_fixed_note_space >? fixed; + + + compound_note_space = compound_note_space + space; + compound_fixed_note_space = compound_fixed_note_space + fixed; + wish_count ++; + } } @@ -592,13 +597,18 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real inc /* Ugh. 0.8 is arbitrary. */ - max_note_space *= 0.8; + compound_note_space *= 0.8; } - if (max_note_space < 0) + if (compound_note_space < 0 || wish_count == 0) + { + compound_note_space = base_note_space; + compound_fixed_note_space = increment; + } + else { - max_note_space = base_note_space; - max_fixed_note_space = increment; + compound_note_space /= wish_count; + compound_fixed_note_space /= wish_count; } /* @@ -608,7 +618,7 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real inc TODO: this criterion is discontinuous in the derivative. Maybe it should be continuous? */ - max_fixed_note_space = max_fixed_note_space get_paper ()->get_scmvar ("packed")); Real strength, distance; @@ -628,12 +638,12 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real inc line will then be stretched to fill the whole linewidth. */ strength = 1.0; - distance = max_fixed_note_space; + distance = compound_fixed_note_space; } else { - strength = 1 / (max_note_space - max_fixed_note_space); - distance = max_note_space; + strength = 1 / (compound_note_space - compound_fixed_note_space); + distance = compound_note_space; } // Spaceable_grob::add_spring (lc, rc, distance, strength, expand_only); diff --git a/lily/text-item.cc b/lily/text-item.cc index 098ef17402..cc91f9c5bd 100644 --- a/lily/text-item.cc +++ b/lily/text-item.cc @@ -275,3 +275,15 @@ new_markup_brewer () return proc; } + + +Molecule +Text_item::interpret_new_markup (SCM grob, SCM achain, + SCM markup) +{ + static SCM proc; + if (!proc) + proc = scm_c_eval_string ("interpret-markup"); + + return *unsmob_molecule (scm_call_3 (proc, grob, achain, markup)); +} diff --git a/lily/text-spanner.cc b/lily/text-spanner.cc index a9fdb32579..254ee1fe29 100644 --- a/lily/text-spanner.cc +++ b/lily/text-spanner.cc @@ -100,7 +100,8 @@ Text_spanner::brew_molecule (SCM smob) /* TODO: use markup. */ - edge[d] = Text_item::text2molecule (me, text, properties); + + edge[d] = Text_item::interpret_new_markup (smob, properties, text); if (!edge[d].empty_b ()) edge[d].align_to (Y_AXIS, CENTER); } @@ -249,7 +250,9 @@ Text_spanner::setup_pedal_bracket(Spanner *me) SCM text = textbit->get_grob_property("text"); if (gh_string_p (text)) { SCM properties = Font_interface::font_alist_chain (me); - Molecule mol = Text_item::text2molecule (me, text, properties); + + Molecule mol = Text_item::interpret_new_markup (me->self_scm (), + properties, text); extra_short += mol.extent(X_AXIS).length() / 2; } } diff --git a/lily/time-signature.cc b/lily/time-signature.cc index dd8e06682e..3382380da9 100644 --- a/lily/time-signature.cc +++ b/lily/time-signature.cc @@ -96,11 +96,10 @@ Time_signature::numbered_time_signature (Grob*me,int num, int den) me->set_grob_property ("font-family", ly_symbol2scm ("number")); Molecule n = - Text_item::text2molecule (me, scm_makfrom0str (to_string (num).to_str0 ()), - chain); + Text_item::interpret_new_markup (me->self_scm(), chain,scm_makfrom0str (to_string (num).to_str0 ())); + Molecule d = - Text_item::text2molecule (me, scm_makfrom0str (to_string (den).to_str0 ()), - chain); + Text_item::interpret_new_markup (me->self_scm(), chain,scm_makfrom0str (to_string (den).to_str0 ())); n.align_to (X_AXIS, CENTER); d.align_to (X_AXIS, CENTER); Molecule m; diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index 1d6a7fe12f..3832249a07 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -158,7 +158,7 @@ Tuplet_bracket::brew_molecule (SCM smob) if (gh_string_p (number) && number_visibility) { SCM properties = Font_interface::font_alist_chain (me); - Molecule num = Text_item::text2molecule (me, number, properties); + Molecule num = Text_item::interpret_new_markup (smob, properties, number); num.align_to (X_AXIS, CENTER); num.translate_axis (w/2, X_AXIS); num.align_to (Y_AXIS, CENTER); diff --git a/lily/volta-bracket.cc b/lily/volta-bracket.cc index f1eb88a57f..6250dd8f9f 100644 --- a/lily/volta-bracket.cc +++ b/lily/volta-bracket.cc @@ -106,7 +106,7 @@ Volta_bracket_interface::brew_molecule (SCM smob) SCM text = me->get_grob_property ("text"); SCM properties = me->get_property_alist_chain (SCM_EOL); - Molecule num = Text_item::text2molecule (me, text, properties); + Molecule num = Text_item::interpret_new_markup (smob, properties, text); mol.add_at_edge (X_AXIS, LEFT, num, - num.extent (X_AXIS).length () - 1.0, 0); diff --git a/lilypond-indent.el b/lilypond-indent.el index 1e36e993ae..a8313ff616 100644 --- a/lilypond-indent.el +++ b/lilypond-indent.el @@ -569,279 +569,3 @@ builtin 'blink-matching-open' is not used. In syntax table, see "This function is redefined to be used in Emacs' show-paren-function and in XEmacs' paren-highlight." (LilyPond-blink-matching-paren dir)) - -;;; From Emacs' paren.el, with minimal changes (see "LilyPond"-lines) -;; Find the place to show, if there is one, -;; and show it until input arrives. -(defun LilyPond-show-paren-function () - (if LilyPond-show-paren-mode - (let (pos dir mismatch face (oldpos (point))) - (cond ((eq (char-syntax (preceding-char)) ?\)) - (setq dir -1)) - ((eq (char-syntax (following-char)) ?\() - (setq dir 1))) - ;; - ;; Find the other end of the sexp. - (when (and dir - (not (LilyPond-inside-string-or-comment-p))) - (save-excursion - (save-restriction - ;; Determine the range within which to look for a match. - (when blink-matching-paren-distance - (narrow-to-region - (max (point-min) (- (point) blink-matching-paren-distance)) - (min (point-max) (+ (point) blink-matching-paren-distance)))) - ;; Scan across one sexp within that range. - ;; Errors or nil mean there is a mismatch. - (condition-case () - (setq pos (LilyPond-scan-sexps (point) dir)) - (error (setq pos t mismatch t))) - ;; If found a "matching" paren, see if it is the right - ;; kind of paren to match the one we started at. - (when (integerp pos) - (let ((beg (min pos oldpos)) (end (max pos oldpos))) - (when (/= (char-syntax (char-after beg)) ?\$) - (setq mismatch - (not (eq (char-before end) - ;; This can give nil. - (matching-paren (char-after beg))))))))))) - ;; - ;; Highlight the other end of the sexp, or unhighlight if none. - (if (not pos) - (progn - ;; If not at a paren that has a match, - ;; turn off any previous paren highlighting. - (and show-paren-overlay (overlay-buffer show-paren-overlay) - (delete-overlay show-paren-overlay)) - (and show-paren-overlay-1 (overlay-buffer show-paren-overlay-1) - (delete-overlay show-paren-overlay-1))) - ;; - ;; Use the correct face. - (if mismatch - (progn - (if show-paren-ring-bell-on-mismatch - (beep)) - (setq face 'show-paren-mismatch-face)) - (setq face 'show-paren-match-face)) - ;; - ;; If matching backwards, highlight the closeparen - ;; before point as well as its matching open. - ;; If matching forward, and the openparen is unbalanced, - ;; highlight the paren at point to indicate misbalance. - ;; Otherwise, turn off any such highlighting. - (if (and (= dir 1) (integerp pos)) - (when (and show-paren-overlay-1 - (overlay-buffer show-paren-overlay-1)) - (delete-overlay show-paren-overlay-1)) - (let ((from (if (= dir 1) - (point) - (forward-point -1))) - (to (if (= dir 1) - (forward-point 1) - (point)))) - (if show-paren-overlay-1 - (move-overlay show-paren-overlay-1 from to (current-buffer)) - (setq show-paren-overlay-1 (make-overlay from to))) - ;; Always set the overlay face, since it varies. - (overlay-put show-paren-overlay-1 'priority show-paren-priority) - (overlay-put show-paren-overlay-1 'face face))) - ;; - ;; Turn on highlighting for the matching paren, if found. - ;; If it's an unmatched paren, turn off any such highlighting. - (unless (integerp pos) - (delete-overlay show-paren-overlay)) - (let ((to (if (or (eq show-paren-style 'expression) - (and (eq show-paren-style 'mixed) - (not (pos-visible-in-window-p pos)))) - (point) - pos)) - (from (if (or (eq show-paren-style 'expression) - (and (eq show-paren-style 'mixed) - (not (pos-visible-in-window-p pos)))) - pos - (save-excursion - (goto-char pos) - (forward-point (- dir)))))) - (if show-paren-overlay - (move-overlay show-paren-overlay from to (current-buffer)) - (setq show-paren-overlay (make-overlay from to)))) - ;; - ;; Always set the overlay face, since it varies. - (overlay-put show-paren-overlay 'priority show-paren-priority) - (overlay-put show-paren-overlay 'face face))) - ;; show-paren-mode is nil in this buffer. - (and show-paren-overlay - (delete-overlay show-paren-overlay)) - (and show-paren-overlay-1 - (delete-overlay show-paren-overlay-1)))) - -;;; From XEmacs' paren.el, with minimal changes (see "LilyPond"-lines) -;; Find the place to show, if there is one, -;; and show it until input arrives. -(defun LilyPond-paren-highlight () - "This highlights matching parentheses. - -See the variables: - paren-message-offscreen use modeline when matching paren is offscreen? - paren-ding-unmatched make noise when passing over mismatched parens? - paren-mode 'blink-paren, 'paren, or 'sexp - blink-matching-paren-distance maximum distance to search for parens. - -and the following faces: - paren-match, paren-mismatch, paren-blink-off" - - ;; I suppose I could check here to see if a keyboard macro is executing, - ;; but I did a quick empirical check and couldn't tell that there was any - ;; difference in performance - - (let ((oldpos (point)) - (pface nil) ; face for paren...nil kills the overlay - (dir (and paren-mode - (not (input-pending-p)) - (not executing-kbd-macro) - (cond ((eq (char-syntax (preceding-char)) ?\)) - -1) - ((eq (char-syntax (following-char)) ?\() - 1)))) - pos mismatch) - - (save-excursion - (if (or (not dir) - (LilyPond-inside-string-or-comment-p) - (not (save-restriction - ;; Determine the range within which to look for a match. - (if blink-matching-paren-distance - (narrow-to-region - (max (point-min) - (- (point) blink-matching-paren-distance)) - (min (point-max) - (+ (point) blink-matching-paren-distance)))) - - ;; Scan across one sexp within that range. - (condition-case nil - (setq pos (LilyPond-scan-sexps (point) dir)) - ;; NOTE - if blink-matching-paren-distance is set, - ;; then we can have spurious unmatched parens. - (error (paren-maybe-ding) - nil))))) - - ;; do nothing if we didn't find a matching paren... - nil - - ;; See if the "matching" paren is the right kind of paren - ;; to match the one we started at. - (let ((beg (min pos oldpos)) (end (max pos oldpos))) - (setq mismatch - (and (/= (char-syntax (char-after beg)) ?\\) - (/= (char-syntax (char-after beg)) ?\$) - ;; XEmacs change - (matching-paren (char-after beg)) - (/= (char-after (1- end)) - (matching-paren (char-after beg))))) - (if (eq paren-mode 'sexp) - (setq paren-extent (make-extent beg end)))) - (and mismatch - (paren-maybe-ding)) - (setq pface (if mismatch - 'paren-mismatch - 'paren-match)) - (and (memq paren-mode '(blink-paren paren)) - (setq paren-extent (make-extent (- pos dir) pos))) - - (if (and paren-message-offscreen - (eq dir -1) - (not (current-message)) - (not (window-minibuffer-p (selected-window))) - (not (pos-visible-in-window-safe pos))) - (paren-describe-match pos mismatch)) - - ;; put the right face on the extent - (cond (pface - (set-extent-face paren-extent pface) - (set-extent-priority paren-extent 100) ; want this to be high - (and (eq paren-mode 'blink-paren) - (setq paren-blink-on-face pface - paren-n-blinks 0 - paren-timeout-id - (and paren-blink-interval - (add-timeout paren-blink-interval - 'paren-blink-timeout - nil - paren-blink-interval)))))) - )))) - -(if (not (string-match "XEmacs\\|Lucid" emacs-version)) -;;; EMACS' Lilypond-show-paren-mode definition -(define-minor-mode LilyPond-show-paren-mode - "Toggle Show Paren mode. -With prefix ARG, turn Show Paren mode on if and only if ARG is positive. -Returns the new status of Show Paren mode (non-nil means on). - -When Show Paren mode is enabled, any matching parenthesis is highlighted -in `show-paren-style' after `show-paren-delay' seconds of Emacs idle time." - :global t :group 'LilyPond-paren-showing - ;; Turn off the usual paren-matching method - ;; when this one is turned on. - (if (local-variable-p 'LilyPond-show-paren-mode) - (make-local-variable 'blink-matching-paren-on-screen) - (kill-local-variable 'blink-matching-paren-on-screen)) - (setq blink-matching-paren-on-screen (not LilyPond-show-paren-mode)) - ;; Now enable or disable the mechanism. - ;; First get rid of the old idle timer. - (if show-paren-idle-timer - (cancel-timer show-paren-idle-timer)) - (if (boundp 'LilyPond-show-paren-idle-timer) - (cancel-timer LilyPond-show-paren-idle-timer)) - (setq LilyPond-show-paren-idle-timer nil) - ;; If show-paren-mode is enabled in some buffer now, - ;; set up a new timer. - (when (memq t (mapcar (lambda (buffer) - (or (with-current-buffer buffer - show-paren-mode) - (with-current-buffer buffer - LilyPond-show-paren-mode))) - (buffer-list))) - (setq LilyPond-show-paren-idle-timer (run-with-idle-timer - show-paren-delay t - 'LilyPond-show-paren-function))) - (unless show-paren-mode - (and show-paren-overlay - (eq (overlay-buffer show-paren-overlay) (current-buffer)) - (delete-overlay show-paren-overlay)) - (and show-paren-overlay-1 - (eq (overlay-buffer show-paren-overlay-1) (current-buffer)) - (delete-overlay show-paren-overlay-1)))) -;;; XEMACS' Lilypond-paren-set-mode definition -(defun LilyPond-paren-set-mode (arg &optional quiet) - "Cycles through possible values for `paren-mode', force off with negative arg. -When called from lisp, a symbolic value for `paren-mode' can be passed directly. -See also `paren-mode' and `paren-highlight'." - (interactive "P") - ;; kill off the competition, er, uh, eliminate redundancy... - (setq post-command-hook (delq 'show-paren-command-hook post-command-hook)) - (setq pre-command-hook (delq 'blink-paren-pre-command pre-command-hook)) - (setq post-command-hook (delq 'blink-paren-post-command post-command-hook)) - - (let* ((paren-modes '(blink-paren paren sexp)) - (paren-next-modes (cons nil (append paren-modes (list nil))))) - (setq paren-mode (if (and (numberp arg) (< arg 0)) - nil ; turn paren highlighting off - (cond ((and arg (symbolp arg)) arg) - ((and (numberp arg) (> arg 0)) - (nth (1- arg) paren-modes)) - ((numberp arg) nil) - (t (car (cdr (memq paren-mode - paren-next-modes))))) - ))) - (cond (paren-mode - (add-hook 'post-command-hook 'LilyPond-paren-highlight) - (add-hook 'pre-command-hook 'paren-nuke-extent) - (setq blink-matching-paren nil)) - ((not (local-variable-p 'paren-mode (current-buffer))) - (remove-hook 'post-command-hook 'LilyPond-paren-highlight) - (remove-hook 'pre-command-hook 'paren-nuke-extent) - (paren-nuke-extent) ; overkill - (setq blink-matching-paren t) - )) - (or quiet (message "Paren mode is %s" (or paren-mode "OFF")))) -) diff --git a/make/lilypond.redhat.spec.in b/make/lilypond.redhat.spec.in index 9b18151465..509ca4f5a4 100644 --- a/make/lilypond.redhat.spec.in +++ b/make/lilypond.redhat.spec.in @@ -14,7 +14,8 @@ URL: http://www.lilypond.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-root -Buildrequires: t1utils bison flex mftrace texinfo +Buildrequires: t1utils bison flex mftrace +Buildrequires: texinfo >= 4.6 Requires: tetex tetex-latex libstdc++ python Requires: guile >= 1.6.4-7 diff --git a/ps/music-drawing-routines.ps b/ps/music-drawing-routines.ps index 75d7bbaa42..dd2f6efec9 100644 --- a/ps/music-drawing-routines.ps +++ b/ps/music-drawing-routines.ps @@ -2,12 +2,15 @@ % % Functions for direct and embedded PostScript + /blot-diameter { lilypondpaperblotdiameter } bind def /set_tex_dimen { cvr def } bind def + + /euclidean_length { 1 copy mul exch 1 copy mul add sqrt diff --git a/python/lilylib.py b/python/lilylib.py index e4116f7cc5..9e9abca643 100644 --- a/python/lilylib.py +++ b/python/lilylib.py @@ -401,7 +401,8 @@ def make_ps_images (ps_name, resolution = 90): ## todo: ## have better algorithm for deciding when to crop page, ## and when to show full page - + base = re.sub (r'\.e?ps', '', ps_name) + header = open (ps_name).read (1024) multi_page = re.search ('\n%%Pages: ', header) cmd = '' @@ -429,9 +430,11 @@ def make_ps_images (ps_name, resolution = 90): cmd = r'''gs -g%dx%d -sDEVICE=pnggray -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=%s -r%d -dNOPAUSE %s %s -c quit ''' % \ (x, y, output_file, resolution, trans_ps, ps_name) + + rmfile = base + '-page*.png' else: output_file = re.sub (r'\.e?ps', '-page%d.png', ps_name) - + rmfile = base + '.png' cmd = r'''gs -s -sDEVICE=pnggray -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=%s -dNOPAUSE -r%d %s -c quit''' % (output_file, resolution, ps_name) @@ -439,6 +442,10 @@ def make_ps_images (ps_name, resolution = 90): status = system (cmd) signal = 0xf & status exit_status = status >> 8 + + rms = glob.glob (rmfile) + print 'removing ', rms + map (os.unlink, rms) if status: os.unlink (png) diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index ee4e6777de..0532220a1b 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1156,6 +1156,7 @@ (molecule-callback . ,Tuplet_bracket::brew_molecule) (font-family . roman) (font-shape . italic) + (font-series . bold) (font-relative-size . -1) (meta . ((interfaces . (text-interface tuplet-bracket-interface font-interface spanner-interface)))) diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index ac8b391a15..cbf018bd50 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -1072,20 +1072,31 @@ def schedule_lilypond_block (chunk): needed_filetypes.append ('eps') pathbase = os.path.join (g_outdir, basename) - def f (base, ext1, ext2): - a = os.path.isfile (base + ext2) - if (os.path.isfile (base + ext1) and - os.path.isfile (base + ext2) and - os.stat (base+ext1)[stat.ST_MTIME] > - os.stat (base+ext2)[stat.ST_MTIME]) or \ - not os.path.isfile (base + ext2): + def must_rebuild (base, ext1, ext2): + + f2 = base + ext2 + f1 = base + ext1 + fp2 = base + '-page1' + ext2 + + isfile2 = os.path.isfile (f2) + + if not isfile2 and os.path.isfile (fp2): + f2 = fp2 + isfile2 = os.path.isfile (fp2) + + if (os.path.isfile (f2) and isfile2 and + os.stat (f1)[stat.ST_MTIME] > + os.stat (f2)[stat.ST_MTIME]) or \ + not isfile2: + return 1 + todo = [] - if 'tex' in needed_filetypes and f (pathbase, '.ly', '.tex'): + if 'tex' in needed_filetypes and must_rebuild (pathbase, '.ly', '.tex'): todo.append ('tex') - if 'eps' in needed_filetypes and f (pathbase, '.tex', '.eps'): + if 'eps' in needed_filetypes and must_rebuild (pathbase, '.tex', '.eps'): todo.append ('eps') - if 'png' in needed_filetypes and f (pathbase, '.eps', '.png'): + if 'png' in needed_filetypes and must_rebuild (pathbase, '.eps', '.png'): todo.append ('png') return ('lilypond', body, opts, todo, basename)