]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'translation' into staging
authorDavid Kastrup <dak@gnu.org>
Thu, 26 Dec 2013 21:49:51 +0000 (22:49 +0100)
committerDavid Kastrup <dak@gnu.org>
Thu, 26 Dec 2013 21:49:51 +0000 (22:49 +0100)
231 files changed:
Documentation/changes.tely
Documentation/contributor/administration.itexi
Documentation/contributor/introduction.itexi
Documentation/contributor/programming-work.itexi
Documentation/contributor/quick-start.itexi
Documentation/contributor/source-code.itexi
Documentation/css/lilypond-manuals.css
Documentation/essay/engraving.itely
Documentation/extending/programming-interface.itely
Documentation/extending/scheme-tutorial.itely
Documentation/included/authors.itexi
Documentation/included/helpus.itexi
Documentation/included/note-head-style.ly
Documentation/lilypond-texi2html.init
Documentation/ly-examples/orchestra.ly
Documentation/notation/changing-defaults.itely
Documentation/notation/rhythms.itely
Documentation/notation/spacing.itely
Documentation/notation/staff.itely
Documentation/notation/vocal.itely
Documentation/snippets/adding-timing-marks-to-long-glissandi.ly
Documentation/snippets/ancient-notation-template----modern-transcription-of-gregorian-music.ly
Documentation/snippets/changing-the-tuplet-number.ly
Documentation/snippets/flat-flags-and-beam-nibs.ly
Documentation/snippets/fretted-headword.ly
Documentation/snippets/guitar-slides.ly
Documentation/snippets/incipit.ly
Documentation/snippets/jazz-combo-template.ly
Documentation/snippets/making-an-object-invisible-with-the-transparent-property.ly
Documentation/snippets/making-glissandi-breakable.ly
Documentation/snippets/modifying-tuplet-bracket-length.ly
Documentation/snippets/new/flat-flags-and-beam-nibs.ly [new file with mode: 0644]
Documentation/snippets/new/incipit.ly
Documentation/snippets/new/modifying-tuplet-bracket-length.ly [new file with mode: 0644]
Documentation/snippets/new/staff-headword.ly
Documentation/snippets/score-for-diatonic-accordion.ly
Documentation/snippets/staff-headword.ly
Documentation/snippets/unfretted-headword.ly
Documentation/usage/external.itely
Documentation/usage/running.itely
Documentation/usage/updating.itely
Documentation/web.texi
Documentation/web/download.itexi
Documentation/web/introduction.itexi
Documentation/web/manuals.itexi
Documentation/web/news-front.itexi
Documentation/web/news.itexi
Documentation/web/server/tweets.xml
Documentation/web/we-wrote.bib
VERSION
flower/include/std-vector.hh
flower/string-convert.cc
input/regression/auto-beam-exceptions.ly
input/regression/chord-dots.ly [new file with mode: 0644]
input/regression/completion-heads-factor.ly
input/regression/completion-rest.ly
input/regression/display-lily-tests.ly
input/regression/header-score-reordered.ly [new file with mode: 0644]
input/regression/les-nereides.ly
input/regression/make-relative-copies.ly [new file with mode: 0644]
input/regression/make-relative-music.ly [new file with mode: 0644]
input/regression/make-relative.ly
input/regression/midi-grace-after-rest.ly [new file with mode: 0644]
input/regression/optional-args.ly
input/regression/rhythmic-sequence.ly [new file with mode: 0644]
input/regression/score-lines.ly [new file with mode: 0644]
input/regression/tablature-slurs-with-beams.ly
lily/accidental.cc
lily/align-interface.cc
lily/arpeggio.cc
lily/audio-item.cc
lily/completion-note-heads-engraver.cc
lily/completion-rest-engraver.cc
lily/dot-column.cc
lily/drum-note-performer.cc
lily/flag.cc
lily/grob-property.cc
lily/hairpin.cc
lily/include/audio-item.hh
lily/include/lily-lexer.hh
lily/include/slur-score-parameters.hh
lily/include/slur-scoring.hh
lily/include/unpure-pure-container.hh
lily/input.cc
lily/lexer.ll
lily/lily-parser.cc
lily/mensural-ligature.cc
lily/midi-item.cc
lily/midi-walker.cc
lily/music.cc
lily/note-head.cc
lily/note-performer.cc
lily/optimal-page-breaking.cc
lily/page-breaking.cc
lily/page-layout-problem.cc
lily/page-spacing.cc
lily/page-turn-page-breaking.cc
lily/paper-column-engraver.cc
lily/paper-column.cc
lily/parser.yy
lily/partial-iterator.cc
lily/performance.cc
lily/rest.cc
lily/script-column.cc
lily/simultaneous-music-iterator.cc
lily/slur-configuration.cc
lily/slur-score-parameters.cc
lily/slur-scoring.cc
lily/slur.cc
lily/source-file.cc
lily/system-start-delimiter.cc
lily/system.cc
lily/time-signature.cc
lily/unpure-pure-container.cc
lily/volta-repeat-iterator.cc
ly/engraver-init.ly
ly/music-functions-init.ly
ly/performer-init.ly
ly/script-init.ly
mf/common-modules-and-initialization.mf [new file with mode: 0644]
mf/debugging-settings.mf [new file with mode: 0644]
mf/declare-autometric-parameters.mf [new file with mode: 0644]
mf/feta-accidentals.mf
mf/feta-alphabet-generic.mf [new file with mode: 0644]
mf/feta-alphabet.mf [deleted file]
mf/feta-alphabet11.mf
mf/feta-alphabet13.mf
mf/feta-alphabet14.mf
mf/feta-alphabet16.mf
mf/feta-alphabet18.mf
mf/feta-alphabet20.mf
mf/feta-alphabet23.mf
mf/feta-alphabet26.mf
mf/feta-arrow.mf [new file with mode: 0644]
mf/feta-braces-a.mf
mf/feta-braces-b.mf
mf/feta-braces-c.mf
mf/feta-braces-d.mf
mf/feta-braces-e.mf
mf/feta-braces-f.mf
mf/feta-braces-g.mf
mf/feta-braces-generic.mf [new file with mode: 0644]
mf/feta-braces-h.mf
mf/feta-braces-i.mf
mf/feta-braces.mf
mf/feta-clefs.mf
mf/feta-flags-generic.mf
mf/feta-flags11.mf
mf/feta-flags13.mf
mf/feta-flags14.mf
mf/feta-flags16.mf
mf/feta-flags18.mf
mf/feta-flags20.mf
mf/feta-flags23.mf
mf/feta-flags26.mf
mf/feta-flats.mf [new file with mode: 0644]
mf/feta-generic.mf [deleted file]
mf/feta-macros.mf
mf/feta-naturals.mf [new file with mode: 0644]
mf/feta-noteheads-generic.mf
mf/feta-noteheads.mf
mf/feta-noteheads11.mf
mf/feta-noteheads13.mf
mf/feta-noteheads14.mf
mf/feta-noteheads16.mf
mf/feta-noteheads18.mf
mf/feta-noteheads20.mf
mf/feta-noteheads23.mf
mf/feta-noteheads26.mf
mf/feta-other-generic.mf [new file with mode: 0644]
mf/feta-parenthesis.mf [new file with mode: 0644]
mf/feta-rests.mf
mf/feta-scripts.mf
mf/feta-sharps.mf [new file with mode: 0644]
mf/feta-test-generic.mf [deleted file]
mf/feta-test11.mf [deleted file]
mf/feta-test13.mf [deleted file]
mf/feta-test16.mf [deleted file]
mf/feta-test20.mf [deleted file]
mf/feta-test23.mf [deleted file]
mf/feta-test26.mf [deleted file]
mf/feta-timesignatures.mf
mf/feta11.mf
mf/feta13.mf
mf/feta14.mf
mf/feta16.mf
mf/feta18.mf
mf/feta20.mf
mf/feta23.mf
mf/feta26.mf
mf/parmesan-clefs.mf
mf/parmesan-generic.mf [deleted file]
mf/parmesan-noteheads-generic.mf
mf/parmesan-noteheads11.mf
mf/parmesan-noteheads13.mf
mf/parmesan-noteheads14.mf
mf/parmesan-noteheads16.mf
mf/parmesan-noteheads18.mf
mf/parmesan-noteheads20.mf
mf/parmesan-noteheads23.mf
mf/parmesan-noteheads26.mf
mf/parmesan-other-generic.mf [new file with mode: 0644]
mf/parmesan11.mf
mf/parmesan13.mf
mf/parmesan14.mf
mf/parmesan16.mf
mf/parmesan18.mf
mf/parmesan20.mf
mf/parmesan23.mf
mf/parmesan26.mf
ps/music-drawing-routines.ps
python/convertrules.py
scm/auto-beam.scm
scm/bar-line.scm
scm/c++.scm
scm/define-context-properties.scm
scm/define-grob-properties.scm
scm/define-grobs.scm
scm/define-markup-commands.scm
scm/define-music-display-methods.scm
scm/define-music-properties.scm
scm/framework-ps.scm
scm/layout-slur.scm
scm/lily-library.scm
scm/lily.scm
scm/ly-syntax-constructors.scm
scm/music-functions.scm
scm/time-signature-settings.scm
scripts/build/gen-emmentaler-scripts.py
scripts/build/mf-to-table.py
scripts/convert-ly.py

index 909d8e62d26735e78f7289f549296267b3fa5def..4ea92a7cb3859e823b45f37bbc3c53d71b3a6fdb 100644 (file)
@@ -36,7 +36,7 @@ See user manual, \NAME\
 @finalout
 
 @node Top
-@top New features in 2.18 since 2.16
+@top New features in 2.20 since 2.18
 
 @allowcodebreaks false
 
@@ -62,425 +62,25 @@ which scares away people.
 @end ignore
 
 @item
-Several articulations can be put into a single variable or
-returned from an event function:
+The PostScript functionality of stroke adjustment is no longer
+applied automatically but left to the discretion of the PostScript
+device (by default, Ghostscript uses it for resolutions up to
+150dpi when generating raster images).  When it is enabled, a more
+complex drawing algorithm designed to benefit from stroke
+adjustment is employed mostly for stems and bar lines.
 
-@lilypond[verbatim,quote]
-sempreStacc = -. ^\markup \italic sempre
-\relative { c''4\sempreStacc c c c }
-@end lilypond
-
-@item
-The baseline of score markups is now taken from the reference
-point (usually the middle of the staff) of the first bottom system
-rather than the top of the bounding rectangle.  The following
-@lilypond[verbatim,quote]
-\markup {
-  violin: \score { \new Staff { <g d' a' e''>1 }
-                   \layout { indent=0 } } ,
-  cello: \score { \new Staff { \clef "bass" <c, g, d a> }
-                  \layout { indent=0 } }
-}
-@end lilypond
-previously looked like
-@lilypond[quote]
-\markup {
-  violin: \general-align #Y #UP
-          \score { \new Staff { <g d' a' e''>1 }
-                   \layout { indent=0 } } ,
-  cello:  \general-align #Y #UP
-          \score { \new Staff { \clef "bass" <c, g, d a> }
-                  \layout { indent=0 } }
-}
-@end lilypond
-without a reliable way to get both scores to line up.
-
-@item
-LilyPond no longer automatically infers a @samp{\defaultchild}
-context in a context definition with @samp{\accepts} clauses.  Any
-context definition without an explicit or inherited
-@samp{\defaultchild} definition counts as a @samp{Bottom} context
-and will be eligible for rhythmic events and overrides without
-causing the implicit creation of other contexts.  Be sure to
-specify a @samp{\defaultchild} for non-@samp{Bottom} contexts when
-defining them from scratch.
-
-@item
-There is now extensive support for both discant and bass accordion
-register symbols in the @samp{scm accreg} module, see
-@ruser{Accordion Registers}.
-@lilypond[verbatim,quote]
-#(use-modules (scm accreg))
-\new PianoStaff
-<<
-  \new Staff \relative
-  { \clef "treble"  \discant "10"
-    r8 s32 f'[ bes f] s e[ a e] s d[ g d] s16 e32[ a]
-    \discant "121"
-    << { r16 <f bes> r <e a> r <d g> } \\
-       { d r a r bes r } >> |
-    <cis e a>1
-  }
-  \new Staff \relative
-  { \clef "treble"  \freeBass "1"
-    r8 d'32 s16. c32 s16. bes32 s16. a32[ cis] s16
-    \clef "bass"  \stdBass "Master"
-    << { r16 <f, bes d>^"b" r <e a c>^"am" r <d g bes>^"gm" |
-         <e a cis>1^"a" } \\
-       { d8_"D" c_"C" bes_"B" | a1_"A" }
-    >>
-  }
->>
-@end lilypond
-
-@item
-New commands @code{markLengthOn} and @code{markLengthOff} control
-the allowance of horizontal space for tempo and rehearsal marks.
-
-@lilypond[quote,relative=2]
-\markLengthOn
-\compressFullBarRests
-\tempo "Molto vivace" c2 c'
-\mark\default
-\tempo "Meno mosso" R1*16
-\mark\default
-g,2 g
-\bar "||"
-\markLengthOff
-\tempo "Molto vivace" c2 c'
-\mark#1
-\tempo "Meno mosso" R1*16
-\mark\default
-g,2 g
-@end lilypond
-
-@item
-Rehearsal marks at the beginning of a line are now placed to the right
-of the clef and key signature by default.  As in previous versions, the
-@code{break-alignable-interface} controls the behavior.
-
-@lilypond[quote,relative=2]
-\set Score.barNumberVisibility = #all-bar-numbers-visible
-\set Timing.currentBarNumber = #72
-\bar"||" \time 3/4 \key e\major \mark#10 \tempo "Adagio" b2.
-@end lilypond
-
-@item
-Decimal numbers can now be written directly in music,
-without a hash sign.  Together with the previous change
-in the way object properties are specified, the code to
-change the length of stems has changed from this:
-@example
-\override Stem #'length = #5.6
-e' f' g' a'
-@end example
-to this:
-@example
-\override Stem.length = 5.6
-e' f' g' a'
-@end example
-
-One has to write a digit on both sides of the dot -- values like
-@code{4.} or @code{-.3} are not allowed.
-
-Decimal fractions are also not accepted in @code{\chordmode}.
-
-@item
-A number of shorthands like @code{(}, @code{)}, @code{|},
-@code{[}, @code{]}, @code{~}, @code{\(}, @code{\)} and others can
-now freely be redefined like normal commands.  An example would be
-@lilypond[verbatim,quote]
-"\\{" = (
-"\\}" = )
-"(" = \melisma
-")" = \melismaEnd
-
-\new Staff <<
-  \relative c' {
-    c8 \{ d e f \} % slurred
-    g ( a b c ) % no slur, but with melisma
-    c,1 \bar "|."
-   }
-   \addlyrics { Li -- ly -- pond. }
->>
-@end lilypond
-
-@item
-The articulation shorthand for @code{\staccatissimo} has been
-renamed from @code{-|} to@tie{}@code{-!}.
-
-@item
-Tempo change ranges are now written as @code{\tempo 4 = 60 - 68}
-rather than @code{\tempo 4 = 60 ~ 68}.
-
-@item
-Grob @code{OctavateEight} was renamed to @code{ClefModifier}.
-Related context properties were renamed from @code{xxxOctavationyyy}
-to @code{xxxTranspositionyyy}.
-
-@item
-There is a new @code{\absolute} command explicitly marking music
-as being entered in absolute pitch.  While this has been the
-default previously, an explicit @code{\absolute} also prevents
-reinterpretation when the passage is placed inside of
-@code{\relative}:
-@lilypond[verbatim,quote]
-\relative c { c'4 \absolute { f'' g'' } c }
-@end lilypond
-
-@item
-When @code{\relative} is used without an explicit reference pitch,
-the reference pitch now is the middle of the first octave, making
-the first entered pitch indistinguishable from absolute pitch.
-Previously, omitting the reference pitch would have lead to a
-default of @code{c'}.  Since that choice was somewhat arbitrary,
-recommended usage was to always specify the reference pitch.
-
-@item
-A new command @code{\single} can be used for converting a property
-override into a tweak to be applied on a single music expression:
-
-@lilypond[quote,verbatim,relative=2]
-<a \single\voiceTwoStyle e' a>1
-@end lilypond
-
-@item
-Two ways of letting graphical objects not appear in the output are
-overriding its @code{transparent} property with @code{#t}
-(retaining the original spacing) or overriding its @code{stencil}
-property with @code{#f} (not using any space at all).  Those two
-operations now have the shorthands @code{\hide} and @code{\omit},
-respectively.  They can either be given a music expression to
-tweak, or the name of a graphical object for which an override
-should be created (for specifying both, use @code{\single} on the
-override form):
-
-@lilypond[quote,verbatim]
-\new Staff \with { \omit Clef }
-\relative c'' <a e' \hide a>1
-@end lilypond
-
-@item
-A new command @code{\temporary} can be applied to overrides in
-order to not have them replace previous property settings.  If a
-@code{\revert} is applied to the same property subsequently, the
-previous setting reappears:
-
-@lilypond[quote,verbatim,relative=2]
-\override NoteHead.color = #red c4
-\override NoteHead.color = #green d
-\revert NoteHead.color e2
-\override NoteHead.color = #red c4
-\temporary\override NoteHead.color = #green d
-\revert NoteHead.color e
-\revert NoteHead.color c
-@end lilypond
-
-This is mainly useful for writing music functions that need to
-have some property changed just for the duration of the function.
-
-@item
-@code{\tag}, @code{\removeWithTag}, and @code{\keepWithTag} can
-now accept a list of symbols rather than just a single symbol for
-marking, removing, and keeping music with any of multiple tags.
-This is particularly important for @code{\keepWithTag} since one
-cannot achieve the same effect by using multiple consecutive
-@code{\keepWithTag} commands.
-
-@item
-The @samp{-d old-relative} option has been removed.  Not actually
-accessible from the command line any more, its remaining use was
-for interpretating @code{\relative} in LilyPond files converted
-automatically from version@tie{}1.8 or older.  It is unclear how
-much of this was actually still operative.
-
-@item
-The meaning of @code{instrumentTransposition} has been reversed.
-After
-@example
-\set instrumentTransposition = #@{ b #@}
-@end example
-a written @code{c'} now sounds like @code{b}.  Previously, this
-would have been the other way round.  This and the following change
-should make dealing with transposing instruments more
-straightforward.
-
-@item
-The music generated by @code{\set} and @code{\override} commands
-is no longer affected by @code{\transpose}.  The main consequence
-is that @code{\transpose} will transpose audible/@/concert pitch and
-printed pitch by the same amount even when the transposed music
-contains @code{\transposition}.  Previously,
-@example
-\transpose c' f' \transposition bes'
-@end example
-was equivalent to @code{\transposition f'}.  Now it stays
-equivalent to @code{\transposition bes'}.
-
-@item
-When checking for collisions, LilyPond no longer treats objects as
-rectangles.  Instead, the actual shape of objects is approximated
-using an integral-like approach.  This generally results in more
-even and snug positioning of objects and systems:
-
-@lilypond[relative=1]
-#(ly:set-option 'debug-skylines #t)
-\dynamicUp
-c'4\f a4\f d\f( f)
-a,4\< c c c\!
-d4-.\downbow a4^"r'venu..." c \tempo "T1" e
-@end lilypond
-
-Previously, the above snippet looked like this:
-
-@lilypond[relative=1]
-#(ly:set-option 'debug-skylines #t)
-\override Hairpin #'vertical-skylines = #'()
-\override DynamicText #'vertical-skylines = #'()
-\override TextScript #'vertical-skylines = #'()
-\override Score.MetronomeMark #'vertical-skylines = #'()
-\override Staff.Clef #'vertical-skylines = #'()
-\dynamicUp
-c'4\f a4\f d\f( f)
-a,4\< c c c\!
-d4-.\downbow a4^"r'venu..." c \tempo "T1" e
-@end lilypond
-
-Affected objects include @code{Accidentals}, @code{Beams}, @code{Clefs},
-@code{Dynamics}, @code{FiguredBass}, @code{Flags}, @code{Glissandos},
-@code{Lyrics}, @code{MetronomeMarks}, @code{OttavaBrackets},
-@code{Pedals}, @code{RehearsalMarks}, @code{Rests}, @code{Scripts},
-@code{TextScripts}, @code{Ties}, @code{Tuplets} and @code{VoltaBrackets}.
-
-@item
-Tuplets are now created with the @code{\tuplet} command, which
-takes a fraction @code{@var{t}/@var{n}} to specify that @var{t}
-notes are played in the time usually allowed for @var{n}. One
-@code{\tuplet} command can create several tuplet groups if their
-duration is typed after the fraction.
-@lilypond[quote,verbatim,relative=2]
-\tuplet 3/2 { c8 d e } \tuplet 3/2 { f e d } c2
-\tuplet 3/2 4 { c8 d e f e d } c2
-@end lilypond
-The @code{\times} command with its inverted fraction order
-@code{@var{n}/@var{t}} is still available.
-
-@item
-Introducing two new markup-commands; @code{\draw-dashed-line} and
-@code{\draw-dotted-line}.
-
-@noindent
-The dashed-line extends to the whole length given by @var{dest}, if
-@code{full-length} is set to @code{#t} (this is the default) without any
-space at the beginning or end.  @code{off} will then be altered to fit.
-To insist on the given (or default) values of @code{on}, @code{off} use
-@code{\override #'(full-length . #f)}.  Manual settings for @code{on},
-@code{off} and @code{phase} are possible.
-
-@noindent
-The dotted-line always extends to the whole length given by @var{dest},
-without any space at the beginning or end.  Manual settings for
-@code{off} are possible to get larger or smaller space between the dots.
-The given (or default) value of @code{off} will be altered to fit the
-line-length.
-
-@lilypond[verbatim,quote]
-\markup {
-  \draw-dashed-line #'(5.1 . 2.3)
-  \override #'(on . 0.3)
-  \override #'(off . 0.5)
-  \draw-dashed-line #'(5.1 . 2.3)
-  \draw-dotted-line #'(5.1 . 2.3)
-  \override #'(thickness . 2)
-  \override #'(off . 0.2)
-  \draw-dotted-line #'(5.1 . 2.3)
-}
-@end lilypond
-
-@item
-Starting with version@tie{}2.17.10, error messages or the
-@code{textedit} @acronym{URI} used for point-and-click
-functionality specify column numbers starting with@tie{}1 rather
-than@tie{}0.  The byte offset (also part of @code{textedit}
-@acronym{URI}s) still starts at@tie{}0.
-
-@item
-The @code{\clef} command supports optional transposition:
-@lilypond[verbatim,quote,relative=1]
-\clef "treble_(8)"
-c2 c
-\clef "bass^[15]"
-c2 c
-@end lilypond
-
-@item
-The LilyPond syntax of dot-separated words @code{Voice.Accidental}
-has been made interchangeable with @code{#'(Voice Accidental)}, a
-Scheme list of symbols.  As one result, code like
-@example
-\override Voice.TextSpanner #'(bound-details left text) = "rit."
-@end example
-is now equivalent to
-@example
-\override Voice.TextSpanner bound-details.left.text = "rit."
-@end example
-or even
-@example
-\override #'(Voice TextSpanner) bound-details.left.text = "rit."
-@end example
-
-@item
-Grob and grob property path no longer need to be specified as two
-separate arguments to commands like @samp{\override} and
-@code{\revert}, allowing for the syntax
-@example
-\override Voice.TextSpanner.bound-details.left.text = "rit."
-@end example
-Since complementary music functions like @samp{\overrideProperty}
-cannot support forms with and without separating space at the same
-time, using a single dotted path is now the preferred form.
-Specifying grob path and grob property path separately, currently
-still supported with @samp{\override} and @samp{\revert} for
-compatibility reasons, is deprecated.
-
-@item
-Due to words now being accepted as symbol function arguments, the
-interfaces of @samp{\accidentalStyle}, @samp{\alterBroken},
-@samp{\footnote} and @samp{\tweak} had to be redesigned where
-optional symbol arguments were involved.  Please check the
-respective music function documentation for details.
-
-@item
-Several commands now accept symbol lists (conveniently entered as
-dot-separated words) for various kinds of arguments.  These
-include @samp{\accidentalStyle}, @samp{\alterBroken},
-@samp{\footnote}, @samp{\hide}, @samp{\omit},
-@samp{\overrideProperty}, @samp{\shape}, and @samp{\tweak}.
-
-@item
-The bar line user interface has changed. Bar glyphs now resemble the
-appearance of the bar line, so a left repeat sign has to be coded
-as @code{.|:}. The command @code{\defineBarLine} provides an easy way
-to define additional bar line styles.
-
-@item
-Accidentals in the key signature may be printed in octaves other
-than their traditional positions, or in multiple octaves.
-@lilypond[quote,relative=0]
-\override Staff.KeySignature #'flat-positions = #'((-5 . 5))
-\override Staff.KeyCancellation #'flat-positions = #'((-5 . 5))
-\clef bass \key es \major es g bes d
-\clef treble \bar "||" \key es \major es g bes d
-\override Staff.KeySignature #'sharp-positions = #'(2)
-\bar "||" \key d \major b fis b2
-@end lilypond
+Stroke adjustment can be forced by specifying the command line
+option @samp{-dstrokeadjust} to LilyPond.  When generating
+@code{PDF} files, this will usually result in markedly better
+looking @code{PDF} previews but significantly larger file size.
+Print quality at high resolutions will be unaffected.
 
 @end itemize
 
 @ifhtml
 For older news, go to
+@uref{http://lilypond.org/doc/v2.18/Documentation/changes/},
 @uref{http://lilypond.org/doc/v2.16/Documentation/changes/},
-@uref{http://lilypond.org/doc/v2.14/Documentation/changes/},
 or @uref{../,go back} to the Documentation index.
 
 
index 8be1d903fa12f1e0c8448005c412e05b1ca9af21..90fe795a0cffa5b3617765afc330674f90225b64 100644 (file)
@@ -126,7 +126,7 @@ on which part of the job, checks to make sure that everything is
 running smoothly, and has final say on our policy for
 Documentation.  Also includes LSR work.
 
-Currently: Graham
+Currently: None
 
 @item
 Translation Meister: trains new translators, updates the
@@ -135,19 +135,6 @@ directions).
 
 Currently: Francisco
 
-@item
-Frog Meister: is responsible for code patches from (relatively)
-inexperienced contributors.  Keeps track of patches, does initial
-reviewing of those patches, sends them to @w{@code{-devel}} when
-they've had some initial review on the Frog list, pesters the
-@w{@code{-devel}} community into actually reviewing said patches, and
-finally pushes the patches once they're accepted.  This person is
-@emph{not} responsible for training new programmers, because that
-would be far too much work -- his/her job is @qq{only} to guide
-completed patches through our process.
-
-Currently: Mike Solomon
-
 @end itemize
 
 @node Patchy
index b6530b4ffdcdfa99a3e5fe2520034a58320e71ae..12c62e5bfaaffc554cace48ef0a9a377af64c814 100644 (file)
@@ -47,27 +47,24 @@ since the program was born.
 
 The @q{official} LilyPond Git repository is hosted by the GNU
 Savannah software forge at @uref{http://git.sv.gnu.org}.
-Although, since Git uses a @emph{distributed} model, technically
-there is no central repository.  Instead, each contributor keeps a
-complete copy of the entire repository (about 116MB).
 
 Changes made within one contributor's copy of the repository can
 be shared with other contributors using @emph{patches}.  A patch
-is a simple text file generated by the @command{git} program that
-indicates what changes have been made (using a special format).
+is a text file that indicates what changes have been made.
 If a contributor's patch is approved for inclusion (usually
 through the mailing list), someone on the current development team
 will @emph{push} the patch to the official repository.
 
 The Savannah software forge provides two separate interfaces for
-viewing the LilyPond Git repository online: @emph{cgit} and
-@emph{gitweb}.  The cgit interface should work faster than gitweb
+viewing the LilyPond Git repository online:
+@uref{http://git.sv.gnu.org/cgit/lilypond.git/, cgit} and
+@uref{http://git.sv.gnu.org/gitweb/?p=lilypond.git, gitweb}.
+
+@ignore
+The cgit interface should work faster than gitweb
 in most situations, but only gitweb allows you to search through
 the source code using @command{grep}, which you may find useful.
-The cgit interface is at
-@uref{http://git.sv.gnu.org/cgit/lilypond.git/} and the gitweb
-interface is at
-@uref{http://git.sv.gnu.org/gitweb/?p=lilypond.git}.
+@end ignore
 
 Git is a complex and powerful tool, but tends to be confusing at
 first, particularly for users not familiar with the command line
@@ -283,8 +280,8 @@ switching git branches (not expected, but just in case...)
 @item
 You don't need to be able to completely approve patches.  Make
 sure the patch meets whatever you know of the guidelines (for doc
-style, code indentation, whatever), and then send it on to the
-frog list or -devel for more comments.  If you feel confident
+style, code indentation, whatever), and then send it on to -devel
+for more comments.  If you feel confident
 about the patch, you can push it directly (this is mainly intended
 for docs and translations; code patches should almost always go to
 -devel before being pushed).
index 819534b4ad0b23127f1ff304da1e4a56473fa558..447f553ea4cf2b1f57e5c736f4794aee06392112 100644 (file)
@@ -1888,55 +1888,8 @@ of a spanner broken at given starting and ending columns.
 
 @node How purity is defined and stored
 @subsection How purity is defined and stored
-Purity can currently be defined two different ways in LilyPond that
-correspond to two types of scenarios.  In one scenario, we know that a
-callback is pure, but we are not necessarily certain what properties
-will use this callback.  In another, we want a property to be pure, but
-we don't want to guarantee that its callback function will be pure in
-all circumstances.
-
-In the first scenario, we register the callback in define-grobs.scm in
-one of four places depending on what the function does.
-
-@itemize
-@item @code{pure-print-functions}: If finding a print function's vertical
-extent does not have any @q{side effects} we register it here. We then
-don't have to set the pure Y-extent property, which will be taken from the
-stencil.
-
-@item @code{pure-print-to-height-conversions}: If a stencil can
-eventually be used to glean a grob's Y-extent but is not pure (meaning
-it will have a different height at different stages of the compilation
-process), we add it to this list along with a function for the pure
-Y-extent.
-
-@item @code{pure-conversions-alist}: This list contains pairs of
-functions and their pure equivalents.  It is onto but not one-to-one.
-
-@item @code{pure-functions}: Like pure-print-functions in that they work
-for both pure and impure values, but they do not return a stencil.
-@end itemize
-
-At all stages of the compilation process, when LilyPond wants the pure
-version of a property, it will consult these lists and see if it can get
-this property for a given Grob.  Note that you do @emph{not} need to
-register the pure property in the grob itself.  For example, there is no
-property @q{pure-Y-extent}.  Rather, by registering these functions as
-defined above, every time LilyPond needs a pure property, it will check
-to see if a Grob contains one of these functions and, if so, will use
-its value.  If LilyPond cannot get a pure function, it will return a
-value of @code{##f} for the property.
-
-LilyPond is smart enough to know if a series of chained functions are
-pure.  For example, if a Y-offset property has four chained functions
-and all of them have pure equivalents, LilyPond will read the four pure
-equivalents when calculating the pure property.  However, if even one is
-impure, LilyPond will not return a pure property for the offset (instead
-returning something like @code{#f} or @code{'()}) and will likely wreak
-havoc on your score.
-
-In the second scenario, we create an unpure-pure-container (unpure is
-not a word, but hey, neither was Lilypond until the 90s).  For example:
+Purity is defined in LilyPond with the creation of an unpure-pure container
+(unpure is not a word, but hey, neither was Lilypond until the 90s).  For example:
 
 @example
 #(define (foo grob)
@@ -1948,23 +1901,8 @@ not a word, but hey, neither was Lilypond until the 90s).  For example:
 \override Stem #'length = #(ly:make-unpure-pure-container foo bar)
 @end example
 
-This is useful if we want to:
-
-@itemize
-@item create overrides that have pure alternatives (should not be used
-in development, but useful for users)
-
-@item use return values that are not functions (i.e. pairs or booleans)
-for either pure or unpure values.
-
-@item allow a function to be considered pure in a limited amount of
-circumstances.  This is useful if we are sure that, when associated with
-one grob a function will be pure but not necessarily with another grob
-that has different callbacks.
-@end itemize
-
-Items can only ever have two pure heights: their actual pure height if
-they are between @q{start} and @q{end}, or an empty interval if they are
+Note that items can only ever have two pure heights: their actual pure height
+if they are between @q{start} and @q{end}, or an empty interval if they are
 not.  Thus, their pure property is cached to speed LilyPond up.  Pure
 heights for spanners are generally not cached as they change depending
 on the start and end values.  They are only cached in certain particular
index df0b9ed50ae14c0ab9c816ac0c13f20aa1f6e050..22ea0591b10c33022aea51adb0d93b9d956f9cd8 100644 (file)
@@ -35,12 +35,6 @@ it is available for all major operating systems and is easy to install
 If you are not familiar with GNU/Linux, it may be beneficial to read a
 couple of @qq{introduction to Ubuntu} web pages.
 
-Some contributors have recommended a free PDF:
-
-@example
-@uref{http://www.ubuntupocketguide.com/}
-@end example
-
 For those interested, the LilyDev remix is currently based on a 32bit
 version of 10.04 LTS Ubuntu (Lucid Lynx).
 
@@ -421,11 +415,6 @@ Send patch files to the appropriate place:
 @item
 If you have a mentor, send it to them via email.
 
-@item
-New contributors should send the patch attached to an email to
-@email{frogs@@lilynet.net}.  Please add @qq{[PATCH]} to the
-subject line.
-
 @item
 Translators should send patches to
 @email{translations@@lilynet.net}.
@@ -435,6 +424,10 @@ More experienced contributors should upload the patch for
 web-based review.  This requires additional software and use of
 the command-line; see @ref{Uploading a patch for review}.
 
+@item
+If you have trouble uploading the patch for review,
+ask for help on @email{lilypond-devel@@gnu.org}.
+
 @end itemize
 
 
index f44dd31b3fd2534a0fe591ab10014e9184e51e93..6a957052daadc2c4696a37abe1815fb84fc35fb1 100644 (file)
@@ -1384,6 +1384,11 @@ can be used.
 
 @end itemize
 
+First you will see a terminal editor where you can edit the
+message that will accompany your patch. @command{git-cl} will
+respect the @env{EDITOR} environment variable if defined,
+otherwise it will use @command{vi} as the default editor.
+
 After prompting for your Google email address and password, the
 patch set will be posted to Rietveld, and you will be given a URL
 for your patch.
index 995c2173c6e586d111e6318fc79df08bf15363b2..8950b847a712bdf7f169793a833c5ebe7ec57fee 100644 (file)
@@ -1,3 +1,27 @@
+/**********************************************************/
+/*                  GENERAL INFORMATION                   */
+/**********************************************************/
+
+/* It has been requested that each web manual be styled using a
+   different color. To faciliate that, each manual is being
+   assigned a hue value on the HSB color chart. All specific
+   colors for a manual will be shades and tints of that hue.
+
+   Manual            Color          Hue
+   learning          green          120
+   music-glossary
+   essay
+
+   notation          blue           205
+   usage             yellow         50
+   snippets
+
+   changes
+   extending         red            0
+   internals         purple         280
+
+   contributor       black          doesn't matter - desat
+
 /**********************************************************/
 /*                  PAGE-WIDE SETTINGS                    */
 /**********************************************************/
@@ -24,7 +48,7 @@ body {
 .appendix, .appendixsec, .appendixsubsec,
 .unnumbered, .unnumberedsec, .unnumberedsubsec, .unnumberedsubsubsec,
 .subheading, .subsubheading {
-  color: #204a87;
+  color: #black;
   border-bottom: 1px dashed black;
   padding-bottom: 0.15em;
   margin-top: 0.6em;
@@ -32,15 +56,23 @@ body {
 }
 
 .settitle {
-  background: #b1d281;
+  background: #657f40;
+  color: white;
   font-size: 2em;
   text-align: center;
   padding: 0.4em 0.5em;
-  border: solid #7b925a;
+  border: solid black;
   border-width: 1px 0;
-  margin: 0;
+  margin: 0 0 10px 0;
 }
 
+body.learning    .settitle { background-color: #407f40; }
+body.notation    .settitle { background-color: #40657f; }
+body.usage       .settitle { background-color: #7f7f33; }
+body.extending   .settitle { background-color: #7f4040; }
+body.internals   .settitle { background-color: #6a407f; }
+body.contributor .settitle { background-color: #000000; }
+
 .chapter, .appendix, .unnumbered {
   font-size: 1.8em;
 }
@@ -99,8 +131,16 @@ blockquote, .smallexample {
   border: solid #b1d281;
   border-width: 1px 1px 1px 5px;
   margin: 1em auto;
+  background-color: white;
 }
 
+body.learning    blockquote, body.learning .smallexample { border-color: #00ff00; }
+body.notation    blockquote, body.notation .smallexample { border-color: #0095ff; }
+body.usage       blockquote, body.usage .smallexample { border-color: #ffff00; }
+body.extending   blockquote, body.extending .smallexample { border-color: #ff0000; }
+body.internals   blockquote, body.internals .smallexample { border-color: #aa00ff; }
+body.contributor blockquote, body.contributor .smallexample { border-color: #000000; }
+
 blockquote p, pre.smallexample {
   padding: 1em;
   margin: 0;
@@ -133,6 +173,13 @@ table.cartouche {
   margin: 0 auto 1em;
 }
 
+body.learning    table.cartouche { background-color: #cfe5cf; border: 2px solid #7db27d; }
+body.notation    table.cartouche { background-color: #cfdce5; border: 2px solid #7d9cb2; }
+body.usage       table.cartouche { background-color: #e5e2b8; border: 2px solid #b2b27d; }
+body.extending   table.cartouche { background-color: #e5cfcf; border: 2px solid #b27d7d; }
+body.internals   table.cartouche { background-color: #decfe5; border: 2px solid #a17db2; }
+body.contributor table.cartouche { background-color: #e5e5e5; border: 2px solid #b2b2b2; }
+
 table.cartouche p {
   padding: 1em;
   margin: 0;
@@ -208,13 +255,20 @@ div#tocframe {
   padding: 0;
   margin: 0;
   overflow: auto;
-  background: #f5f5dc;
+  background: #dce35cf;
   z-index: 100;
   list-style-type: none;
   font-size: 0.83em;
   line-height: 1.3;
 }
 
+body.learning    div#tocframe { background-color: #cfe5cf; }
+body.notation    div#tocframe { background-color: #cfdce5; }
+body.usage       div#tocframe { background-color: #e5e5b8; }
+body.extending   div#tocframe { background-color: #e5cfcf; }
+body.internals   div#tocframe { background-color: #decfe5; }
+body.contributor div#tocframe { background-color: #e5e5e5; }
+
 @media screen {
   body > div#tocframe {
     position: fixed
@@ -222,12 +276,12 @@ div#tocframe {
 }
 
 div#tocframe a:link, div#tocframe a:visited {
-  color: #454532;
+  color: black;
   text-decoration: none;
 }
 
 div#tocframe a:hover {
-  color: #232b16;
+  color: #666666;
   text-decoration: underline;
 }
 
@@ -236,7 +290,7 @@ div#tocframe p.toc_uplink {
   line-height: 1.125;
   background: #c9ccc4;
   padding: 0.25em 1em 0.25em 0.5em;
-  border-bottom: 1px solid #a0a087;
+  border-bottom: 1px solid black;
   margin: 0;
 }
 
@@ -382,16 +436,24 @@ table .title {
 }
 
 .footer {
-  background: #e5f5ce;
+  background: #657f40;
   font-size: 0.8em;
   padding: 0.2em 0;
-  border: solid #b1d281;
+  border: solid white;
   border-width: 0 0 5px 0;
   margin: 0;
+  color: white;
 }
 
+body.learning    .footer { background-color: #407f40; }
+body.notation    .footer { background-color: #40657f; }
+body.usage       .footer { background-color: #7f7f33; }
+body.extending   .footer { background-color: #7f4040; }
+body.internals   .footer { background-color: #6a407f; }
+body.contributor .footer { background-color: #000000; }
+
 .footer a:link {
-  color: #0308fc;
+  color: white;
 }
 
 .footer p {
@@ -456,6 +518,14 @@ div#search p, div#search form {
   margin: 1em;
 }
 
+body.learning    .warning { border-color: #00ff00; }
+body.notation    .warning { border-color: #0095ff; }
+body.usage       .warning { border-color: #ffff00; }
+body.extending   .warning { border-color: #ff0000; }
+body.internals   .warning { border-color: #aa00ff; }
+body.contributor .warning { border-color: #000000; }
+
+
 .advanced {
   background: #eeffcc;
   text-align: left;
index 0192b98623c53580097eba8f2856c698185c16c4..16f3518d56192b8e8f3b916c3473bab2b37d2df9 100644 (file)
@@ -1580,8 +1580,8 @@ therefore be easily embedded in other text-based formats such as
 @command{lilypond-book} program, included with LilyPond, the input
 fragments can be replaced by music images in the resulting PDF or HTML
 output files.  Another example is the third-party OOoLilyPond extension
-for OpenOffice.org, which makes it extremely easy to embed musical
-examples in documents.
+for OpenOffice.org or LibreOffice, which makes it extremely easy to
+embed musical examples in documents.
 
 For more examples of LilyPond in action, full documentation, and the
 software itself, see our main website: www.lilypond.org.
index 82ef216ad844ee74fb85555703c527c9424992d9..6b16fdafbc64bb34bb4bfa580ebdfe5b98561f48 100644 (file)
@@ -179,13 +179,7 @@ strings (with or without quotes), numbers, full markups and markup
 lists, score, book, bookpart, context definition and output definition
 blocks.
 
-For some kinds of expression (like most music not enclosed in braces)
-LilyPond needs to look further than the expression itself in order to
-determine its end.  If such an expression were considered for an
-optional argument by evaluating its predicate, LilyPond would not be
-able to @q{backup} when it decides the expression does not fit the
-parameter.  So some forms of music might need to be enclosed in braces
-to make them acceptable in some circumstances.  Some other
+Some
 ambiguities LilyPond sorts out by checking with predicate
 functions: is @samp{-3} a fingering postevent or a negative number?  Is
 @code{"a" 4} in lyric mode a string followed by a number, or a lyric
@@ -196,8 +190,8 @@ lookahead.
 
 For example, a predicate accepting both music expressions and
 pitches will consider @code{c''} to be a pitch rather than a music
-expression.  Immediately following durations or postevents might
-not work with that interpretation.  So it's best to avoid overly
+expression.  Immediately following durations or postevents will
+change that interpretation.  It's best to avoid overly
 permissive predicates like @code{scheme?} when the application
 rather calls for more specific argument types.
 
index bad8d261b214cd4e6fc1aff56dafbed1af3b6938..7503306b1fa56f3e8c16b0f6d25b5f5e8d8f28a6 100644 (file)
@@ -1134,23 +1134,30 @@ will display
 
 By default, LilyPond will print these messages to the console along
 with all the other messages.  To split up these messages and save
-the results of @code{\display@{STUFF@}}, redirect the output to
-a file.
+the results of @code{\display@{STUFF@}}, you can specify an optional
+output port to use:
 
 @example
-lilypond file.ly >display.txt
+@{
+  \displayMusic #(open-output-file "display.txt") @{ c'4\f @}
+@}
 @end example
 
-With a combined bit of Lilypond and Scheme magic, you can actually
-let Lilypond direct just this output to a file of its own:
-
+This will overwrite a previous output file whenever it is called; if you
+need to write more than one expression, you would use a variable for
+your port and reuse it:
 @example
 @{
-  #(with-output-to-file "display.txt"
-      (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
+  port = #(open-output-file "display.txt")
+  \displayMusic \port @{ c'4\f @}
+  \displayMusic \port @{ d'4 @}
+  #(close-output-port port)
 @}
 @end example
 
+Guile's manual describes ports in detail.  Closing the port is actually
+only necessary if you need to read the file before Lilypond finishes; in
+the first example, we did not bother to do so.
 
 A bit of reformatting makes the above information easier to read:
 
index 28d1a54639f8054e4eb24ae5989c834530851eab..19ea379bd82ec09b8cded9fe7bbabe5d7dcd69ba 100644 (file)
@@ -142,7 +142,7 @@ happy nitpicker
 
 @item Mats Bengtsson:
 @email{mats.bengtsson@@ee.kth.se},
-@uref{http://www.s3.kth.se/~mabe/},
+@uref{https://www.kth.se/profile/matben/},
 Support guru
 
 @item Pedro Kroeger:
@@ -179,15 +179,20 @@ Core developer, Schemer extraordinaire
 
 Aleksandr Andreev,
 Frédéric Bron,
+Torsten Hämmerle ,
 Marc Hohl,
 James Lowe,
+Andrew Main,
+Thomas Morley,
 David Nalesnik,
 Keith OHara,
 BenkÅ‘ Pál,
 Anders Pilegaard,
 Julien Rioux,
 Johannes Rohrer,
-Adam Spiers
+Devon Schudy,
+Adam Spiers,
+Heikki Tauriainen
 
 @c no comma for last entry
 
@@ -211,9 +216,13 @@ Adam Spiers
 
 Frédéric Bron,
 Federico Bruni,
+Colin Campbell,
+Urs Liska,
 James Lowe,
+Thomas Morley,
 Jean-Charles Malahieude,
 Guy Stalnaker,
+Martin Tarenskeen,
 Arnold Theresius,
 Rodolfo Zitellini
 
@@ -242,6 +251,15 @@ Ralph Palmer
 
 @c use commas not colons
 
+Colin Campbell,
+Eluze,
+Marc Hohl,
+Marek Klein,
+Alex Loomis,
+Kieren MacMillan,
+Urs Liska,
+Ralph Palmer
+
 @c no comma for last entry
 
 @end macro
@@ -253,11 +271,12 @@ Ralph Palmer
 @c use commas not colons
 
 Federico Bruni,
+Luca Rossetto Casel,
 Felipe Castro,
 Pavel Fric,
 Jean-Charles Malahieude,
-Till Rettig,
-Luca Rossetto Casel
+Till Paala,
+Yoshiki Sawada
 
 @c no comma for last entry
 
index 2789f28097841523ad317ea635056a57178b9f90..96f697be4cb95bbf1767356cf3a62ac2fb4ca39f 100644 (file)
@@ -15,9 +15,9 @@ of spending time on those simple tasks.
 
 For a multi-faceted project like LilyPond, sometimes it's tough to know
 where to begin.  In addition to the avenues proposed below, you can send
-an e-mail to the @email{mike@@mikesolomon.org, Frog meister}
-letting him know your skill set and asking how you can help or proposing a
-project.  He'll be able to give you guidance on how to get started.
+an e-mail to the
+@uref{https://lists.gnu.org/mailman/listinfo/lilypond-devel, lilypond-devel@@gnu.org}
+mailing list, and we'll help you to get started.
 
 @end macro
 
@@ -35,11 +35,6 @@ Mailing list support: answer questions from fellow users.
 Bug reporting: help users create proper @rweb{Bug reports}, and/or
 join the Bug Squad to organize @rcontrib{Issues}.
 
-@item
-@rcontrib{Grand Regression Test Checking}: verify that LilyPond works correctly
-by examining output of test snippets.  Checking one snippet takes less
-than a minute!
-
 @item
 Documentation: small changes can be proposed by following the
 guidelines for @rcontrib{Documentation suggestions}.
@@ -90,8 +85,7 @@ Translations: see @rcontrib{Translating the documentation}, and
 @rcontrib{Translating the website}.
 
 @item
-Bugfixes or new features: the best way to begin is to join the
-Frogs, and read @rcontrib{Programming work}.
+Bugfixes or new features: read @rcontrib{Programming work}.
 
 @end itemize
 
@@ -101,23 +95,6 @@ Frogs, and read @rcontrib{Programming work}.
 @macro helpusProjects
 @subheading Projects
 
-@subsubheading Frogs
-
-Website and mailing list:
-
-@example
-@uref{http://frogs.lilynet.net}
-@end example
-
-The Frogs are ordinary LilyPond users who have chosen to get
-involved in their favorite software's development.  Fixing bugs,
-implementing new features, documenting the source code: there's a
-lot to be done, but most importantly: this is a chance for
-everyone to learn more about LilyPond, about Free Software, about
-programming@dots{} and to have fun.  If you're curious about any of
-it, then the word is: @emph{Join the Frogs!}
-
-
 
 @subsubheading Grand LilyPond Input Syntax Standardization
 
index a78697873446f8fa68061e011f436b7b89c13275..0d2cabfcdac63dbe67ad5d40d14241f5376cff57 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.6"
+\version "2.19.0"
 
 \header {
   texidoc="
@@ -25,11 +25,11 @@ dimensions.
 pattern = <<
   \new Voice {
     \override Stem.direction = #UP
-    e'4 e'2. e'1 e'\breve*1/2 e'\longa*1/4 \bar "||"
+    e'4 2. 1 \breve*1/2 \longa*1/4 \bar "||"
   }
   \new Voice {
     \override Stem.direction = #DOWN
-    a4 a2. a1 a\breve*1/2 a\longa*1/4 \bar "||"
+    a4  2. 1 \breve*1/2 \longa*1/4 \bar "||"
   }
 >>
 
index cd370bb87d0f19b5a2ab48b286a7970798dfcdf9..414c5add23620ec791c28d7dca123272c8b1fc41 100644 (file)
@@ -1094,6 +1094,25 @@ sub lilypond_css_lines ($$)
       $Texi2HTML::THISDOC{'CSS_LINES'} .= "<script language=\"JavaScript\" src=\"${reldir}lily_search.js\"></script>\n";
     }
   }
+
+  ## This section makes the manual name visible to CSS through the body tag
+  ## so that styles can be applied per manual. It will add the manual
+  ## directory name (e.g., 'notation' or 'learning') as a CSS class, as well
+  ## as a development status.
+
+  # Parse the input file name to determine the manual we're dealing with.
+  my ($docu_dir, $docu_name) = split_texi_filename ($Texi2HTML::THISDOC{'input_file_name'});
+
+  # Hard-coded value to indicate if this is a development version
+  # ('devStatus') or stable version ('stableStatus')
+  # TODO: Figure out how to automatically set this value based on the even/odd minor revision number or some other mechanism.
+  $documentstatus = 'devStatus';
+
+  # Create the extra information for the <body> tag.
+  # For example, the development Notation reference in English
+  # will output in HTML as <body lang='en' class='notation devStatus'>
+  $Texi2HTML::Config::BODYTEXT = 'lang="' . $Texi2HTML::THISDOC{current_lang} . '" class="' . $docu_name . ' ' . $documentstatus . '"';
+
 }
 
 
index 6b205af903f8f9f53582db839243310e42982c51..d784dfd6af3147c224b797ab7e7678fdb3007f31 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.6"
+\version "2.19.0"
 
 \header {
   tagline = ##f
@@ -271,49 +271,49 @@ R2. |
     ees r r r4 r8 r4 r8 |
   }
 
-  trian = \relative c' {
+  trian = {
     \clef percussion \time 6/8
     R2.*4 |
     \time 9/8
     R1*9/8 |
   }
 
-  cym = \relative c' {
+  cym = {
     \clef percussion \time 6/8
     R2.*4 |
     \time 9/8
     R1*9/8 |
   }
 
-  tamt = \relative c' {
+  tamt = {
     \clef percussion \time 6/8
 R2. |
     r4 r8 r c4\mf\<^"*" ~ |
-    c8\!\ff r r r4 r8 | R2. |
+    8\!\ff r r r4 r8 | R2. |
     \time 9/8
     R1*9/8 |
   }
 
-  tamb = \relative c' {
+  tamb = {
     \clef percussion \time 6/8
     R2.*4 |
     \time 9/8
     R1*9/8 |
   }
 
-  snare = \relative c' {
+  snare = {
     \clef percussion \time 6/8
     R2.*4 |
     \time 9/8
-    c8\pp c c c c c c c c |
+    c8\pp 8 8 8 8 8 8 8 8 |
   }
 
-  bsdrum = \relative c' {
+  bsdrum = {
     \clef percussion \time 6/8
-    c2.:32\pp\< ~ | c: ~ |
-    c8\!\ff \offCr r r r4 r8 | R2. |
+    c2.:32\pp\< ~ | 2.: ~ |
+    8\!\ff \offCr r r r4 r8 | R2. |
     \time 9/8
-    c2.:32\pp ~ c4.: |
+    2.:32\pp ~ 4.: |
   }
 
   harprh = \relative c'' {
index 3dc39edd9b88e1a238ea2d8bad24895ce4887551..cb8edf2c033a272ccf7aff8124f6a4080e76e343 100644 (file)
@@ -213,8 +213,9 @@ Handles clefs, bar lines, keys, accidentals.  It can contain
 
 @strong{@emph{RhythmicStaff}}
 
-Like @code{Staff} but for printing rhythms.  Pitches are ignored;
-the notes are printed on one line.
+Like @code{Staff} but for printing rhythms.  Pitches are ignored
+when engraving; the notes are printed on one line.  The MIDI
+rendition retains pitches unchanged.
 
 @strong{@emph{TabStaff}}
 
index f6842824a83783ce7c6b880d74fb37411ab6d973..f935956922b947c7623b89a2d5a2001104146400 100644 (file)
@@ -7,7 +7,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.30"
+@c \version "2.19.0"
 
 @node Rhythms
 @section Rhythms
@@ -93,6 +93,15 @@ note.
 a a a2 a a4 a a1 a
 @end lilypond
 
+Durations occuring on their own within a music sequence will take
+their pitches from the preceding note or chord.
+
+@lilypond[quote,verbatim,relative=2]
+\time 8/1
+c \longa \breve 1 2
+4 8 16 32 64 128 128
+@end lilypond
+
 @cindex notes, dotted
 @cindex dotted notes
 @cindex notes, double-dotted
@@ -204,7 +213,7 @@ tuplets are triplets: 3@tie{}notes sound within the duration
 normally allowed for@tie{}2:
 
 @lilypond[quote,verbatim,relative=2]
-a2 \tuplet 3/2 { b4 b b }
+a2 \tuplet 3/2 { b4 4 4 }
 c4 c \tuplet 3/2 { b4 a g }
 @end lilypond
 
@@ -425,6 +434,13 @@ should be tied to the following note, which must be at the same pitch.
 a2~ a4~ a16 r r8
 @end lilypond
 
+Ties can make use of the @q{last explicit pitch} interpretation of
+isolated durations:
+
+@lilypond[quote,verbatim,relative=2]
+a2 ~ 4 ~ 16 r r8
+@end lilypond
+
 Ties are used either when the note crosses a bar line, or when
 dots cannot be used to denote the rhythm.  Ties should also be
 used when note values cross larger subdivisions of the measure:
@@ -450,7 +466,8 @@ created.  Chords may be partially tied by placing the ties inside
 the chord.
 
 @lilypond[quote,verbatim,relative=1]
-<c e g>~ <c e g c>
+<c e g>2 ~ 2
+<c e g>4~ <c e g c>
 <c~ e g~ b> <c e g b>
 @end lilypond
 
@@ -1412,12 +1429,30 @@ So the first example above could be written:
 e8 | a4 c8 b c4 |
 @end lilypond
 
-The property @code{measurePosition} contains a rational number, which
-is usually positive and indicates how much of the measure has passed
-at this point.  The @code{\partial @var{duration}} command sets it to
-a negative number, when it has a different meaning: it then says that
-the current (first) bar will be @emph{preceded} by a bar 0 (the partial
-bar) with a duration given by @var{duration}.
+The property @code{measurePosition} contains a rational number,
+which is usually positive and indicates how much of the measure
+has passed at this point.  @code{\partial @var{duration}} is
+defined such that no numbered bar gets created: when used at the
+beginning of a measure, @code{measurePosition} is set to a
+negative number, implying that the current bar will be
+@emph{preceded} by additional material.  When used after a measure
+has already started, however, it moves the requested distance
+before the @emph{end} of the bar.
+
+@lilypond[quote,verbatim,relative=1]
+\set Score.barNumberVisibility = #all-bar-numbers-visible
+\override Score.BarNumber.break-visibility =
+          #end-of-line-invisible
+\time 6/8
+\partial 8
+e8 | a4 c8 b[ c b] |
+\partial 4
+r8 e,8 | a4 \bar "||"
+\partial 4
+r8 e8 | a4
+c8 b[ c b] |
+@end lilypond
+
 
 @seealso
 Music Glossary:
@@ -1432,19 +1467,6 @@ Snippets:
 Internal Reference:
 @rinternals{Timing_translator}.
 
-@knownissues
-The @code{\partial} command should be used only at the beginning of a
-piece.  If you use it after the beginning, warnings or problems may
-occur, so use @code{\set Timing.measurePosition} instead.
-
-@lilypond[quote,verbatim,relative=1]
-\time 6/8
-\partial 8
-e8 | a4 c8 b[ c b] |
-\set Timing.measurePosition = #(ly:make-moment -1/4)
-r8 e,8 | a4 c8 b[ c b] |
-@end lilypond
-
 
 @node Unmetered music
 @unnumberedsubsubsec Unmetered music
@@ -1788,6 +1810,37 @@ inserts ties for notes.  One of its uses is to debug complex scores: if
 the measures are not entirely filled, then the ties show exactly how
 much each measure is off.
 
+The property @code{completionUnit} sets a preferred duration for
+the split notes.
+
+@lilypond[quote,verbatim,relative=2]
+\new Voice \with {
+  \remove "Note_heads_engraver"
+  \consists "Completion_heads_engraver"
+} {
+  \time 9/8 g\breve. d4. \bar "||"
+  \set completionUnit = #(ly:make-moment 3 8)
+  g\breve. d4.
+}
+@end lilypond
+
+These engravers split notes with scaled duration, such as those in tuplets,
+into notes with the same scale-factor as in the input note.
+
+@lilypond[quote,verbatim,relative=2]
+\new Voice \with {
+  \remove "Note_heads_engraver"
+  \consists "Completion_heads_engraver"
+} {
+  \time 2/4 r4
+  \tuplet 3/2 {g4 a b}
+  \scaleDurations 2/3 {g a b}
+  g4*2/3 a b
+  \tuplet 3/2 {g4 a b}
+  r4
+}
+@end lilypond
+
 @seealso
 Music Glossary:
 @rglos{tie}
@@ -1807,12 +1860,12 @@ Internals Reference:
 @rinternals{Forbid_line_break_engraver}.
 
 @knownissues
-Not all durations (especially those containing tuplets) can be
-represented exactly with normal notes and dots, but the
-@code{Completion_heads_engraver} will not insert tuplets.
-
-The @code{Completion_heads_engraver} only affects notes; it does not
-split rests.
+For consistency with previous behavior, notes and rests with
+duration longer than a measure, such as @code{c1*2}, are split into
+notes without any scale factor, @code{@{ c1 c1 @}}.  The property
+@code{completionFactor} controls this behavior, and setting it to
+@code{#f} cause split notes and rest to have the scale factor
+of the input durations.
 
 
 @node Showing melody rhythms
@@ -2015,6 +2068,7 @@ new beam starts.
 @funindex autoBeaming
 @funindex baseMoment
 @funindex beamExceptions
+@funindex \beamExceptions
 @funindex beatStructure
 @funindex measureLength
 @funindex \time
@@ -2156,42 +2210,24 @@ the time signature. Any exceptions to this default can be found in
 Special autobeaming rules (other than ending a beam on a beat)
 are defined in the @code{beamExceptions} property.
 
+The value for @code{beamExceptions}, a somewhat complex Scheme
+data structure, is easiest generated with the
+@code{\beamExceptions} function.  This function is given one or
+more manually beamed measure-length rhythmic patterns (measures
+have to be separated by a bar check@tie{}@code{|} since the
+function has no other way to discern the measure length).  Here is
+a simple example:
+
 @lilypond[quote,relative=2,verbatim]
 \time 3/16
 \set Timing.beatStructure = #'(2 1)
 \set Timing.beamExceptions =
-  #'(                         ;start of alist
-     (end .                   ;entry for end of beams
-      (                       ;start of alist of end points
-       ((1 . 32) . (2 2 2))   ;rule for 1/32 beams -- end each 1/16
-      )))                     %close all entries
+  \beamExceptions { 32[ 32] 32[ 32] 32[ 32] }
 c16 c c |
 \repeat unfold 6 { c32 } |
 @end lilypond
 
-@code{beamExceptions} is an alist with a key of rule-type and a value
-of beaming-rules.
-
-At this time the only available value of rule-type is
-@code{'end} for beam ending.
-
-Beaming-rules is a scheme alist (or list of pairs) that indicates the
-beam type and the grouping to be applied to beams containing notes with
-a shortest duration of that beam type.
-
-@example
-#'((beam-type1 . grouping-1)
-   (beam-type2 . grouping-2)
-   (beam-type3 . grouping-3))
-@end example
-
-Beam type is a scheme pair indicating the duration of the beam,
-e.g., @code{(1 . 16)}.
-
-Grouping is a scheme list indicating the grouping to be applied to
-the beam.  The grouping is in units of the beam type.
-
-@warning{ A @code{beamExceptions} value must be @emph{complete}
+@warning{A @code{beamExceptions} value must be @emph{complete}
 exceptions list.  That is, every exception that should be applied
 must be included in the setting.  It is not possible to add, remove,
 or change only one of the exceptions. While this may seem cumbersome,
index a56101b0dc14c345289ce28d24ba4f84a03e11a4..23d7cf05c57c0325b9b9bd40113e00fc291c8469 100644 (file)
@@ -394,18 +394,16 @@ default value is scaled accordingly.
 @item ragged-bottom
 @funindex ragged-bottom
 
-If set to true, systems will not spread vertically down the page.
-This does not affect the last page.  This should be set to true
-for pieces that have only two or three systems per page, for
-example orchestral scores.
+If this is set to true,
+systems will be set at their natural spacing, neither compressed
+nor stretched vertically to fit the page.
 
 @item ragged-last-bottom
 @funindex ragged-last-bottom
 
-If set to false, systems will spread vertically down the last
-page.  Pieces that amply fill two pages or more should have this
-set to false.  It also affects the last page of book parts, i.e.
-parts of a book created with @code{\bookpart} blocks.
+If this is set to false, then the last page,
+and the last page in each section created with a @code{\bookpart} block,
+will be vertically justified in the same way as the earlier pages.
 
 @end table
 
@@ -1521,10 +1519,12 @@ The @code{\pageBreak} and @code{\noPageBreak} commands may also be
 inserted at top-level, between scores and top-level markups.
 
 There are also analogous settings to @code{ragged-right} and
-@code{ragged-last} which have the same effect on vertical spacing:
-@code{ragged-bottom} and @code{ragged-last-bottom}.  If set to
-@code{#t} the systems on all pages or just the last page
-respectively will not be justified vertically.  See
+@code{ragged-last} which have the same effect on vertical spacing.
+If @code{ragged-bottom} is set to @code{#t} the systems will not
+be justified vertically.  When @code{ragged-last-bottom} is set
+to @code{#t}, as it is by default, empty space is allowed at the
+bottom of the final page (or the final page in each
+@code{\bookpart}).  See
 @ref{Fixed vertical spacing paper variables,,Fixed vertical spacing @code{@bs{}paper} variables}.
 
 Page breaks are computed by the @code{page-breaking} function.  LilyPond
@@ -2001,35 +2001,32 @@ of these reference points:
 alignToZero = \with {
   \override VerticalAxisGroup.nonstaff-relatedstaff-spacing = #zero-space
   \override VerticalAxisGroup.nonstaff-nonstaff-spacing = #zero-space
+  \override VerticalAxisGroup.staff-affinity = #DOWN
+  \remove Text_engraver % avoid having two
+  \consists Text_engraver
 }
 lowerCaseChords = \with {
   chordNameLowercaseMinor = ##t
 }
-staffAffinityDown = \with {
-  \override VerticalAxisGroup.staff-affinity = #DOWN
-}
 labelContext =
 #(define-music-function
      (parser location context)
      (string?)
-   #{ s1*0^\markup { \typewriter #context } #})
+     #{ s1*0^\markup { \upright {\typewriter #context } } #})
 
 \layout {
   \context { \Dynamics    \alignToZero }
   \context { \FiguredBass \alignToZero }
   \context { \Lyrics      \alignToZero }
-  \context { \NoteNames   \alignToZero \staffAffinityDown }
-  \context { \ChordNames  \alignToZero
-                          \staffAffinityDown
-                         \lowerCaseChords }
-  \context { \FretBoards  \alignToZero \staffAffinityDown }
+  \context { \NoteNames   \alignToZero }
+  \context { \ChordNames  \alignToZero \lowerCaseChords }
+  \context { \FretBoards  \alignToZero }
   \context { \Score
     \omit BarLine
     \override DynamicText.self-alignment-X = #-1
     \override FretBoard.X-offset = #1.75
-    \override InstrumentName.minimum-Y-extent = #'(-2 . 2)
-    \override InstrumentName.extra-offset = #'(0 . -0.5)
-    \override TextScript.minimum-Y-extent = #'(-2 . 3)
+    \override InstrumentName.minimum-Y-extent = #'(-1 . 2)
+    \textLengthOn
     \omit TimeSignature
   }
 }
@@ -2037,44 +2034,29 @@ labelContext =
 %% These contexts have reference points at the baseline:
 %%   ChordNames, NoteNames, and Lyrics
 <<
-  \new ChordNames { \chords { g1:m } }
-  \new NoteNames { s1 | g1 | }
-  \new RhythmicStaff {
-    \set RhythmicStaff.instrumentName = #"baseline "
-    \textLengthOn
-    \labelContext "ChordNames " s1 |
-    \labelContext "NoteNames "  s1 |
-    \labelContext "Lyrics"     s1 |
-  }
-  \new Lyrics { \lyrics { \skip 1*2 | ghijk1 | } }
+  \new ChordNames { \chords { \labelContext "ChordNames"  g1:m } }
+  \new NoteNames { s1 |\labelContext "NoteNames"  g1 | }
+  \new Lyrics { \lyrics { \skip 1*2 | \labelContext "Lyrics" ghijk1 | } }
+  \new RhythmicStaff \with { instrumentName = #"baseline " } s1*3
 >>
 
 %% The reference point for Dynamics is the midline of 'm' in the font
 <<
-  \new RhythmicStaff {
-    \set RhythmicStaff.instrumentName = #"mid-height "
-    \labelContext "Dynamics" s1*3
-  }
-  \new Dynamics { s1\mp s\fp }
+  \new Dynamics { \labelContext "Dynamics" s1\mp s\fp }
+  \new RhythmicStaff \with { instrumentName = #"mid-height " } s1*3
 >>
 
 %% The reference point for FiguredBass is its highest point
 <<
-  \new RhythmicStaff {
-    \set RhythmicStaff.instrumentName = #"highest point "
-    \labelContext "FiguredBass" s1
-  }
-  \new FiguredBass { \figuremode { <6 5>1 } }
+  \new FiguredBass { \labelContext "FiguredBass" \figuremode { <6 5>1 } }
+  \new RhythmicStaff \with { instrumentName = #"highest point " } s1
 >>
 
 %% The reference point for FretBoards is the top line
 \include "predefined-guitar-fretboards.ly"
 <<
-  \new FretBoards { \chordmode { e1 } }
-  \new RhythmicStaff {
-    \set RhythmicStaff.instrumentName = #"top line "
-    \labelContext "FretBoards " s1
-  }
+  \new FretBoards { \labelContext "FretBoards" \chordmode { e1 } }
+  \new RhythmicStaff \with { instrumentName = #"top line " } s1
 >>
 @end lilypond
 
@@ -3107,11 +3089,14 @@ proportional notation settings and examine how these settings interact.
 We start with the following one-measure example, which uses classical
 spacing with ragged-right turned on.
 
+@c The initial pitch is not necessary as long as RhythmicStaff is
+@c not preceded by other material in the score, but we don't want
+@c to explain that.
 @lilypond[quote,verbatim,ragged-right]
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
   >>
 }
@@ -3136,7 +3121,7 @@ setting.
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
   >>
  \layout {
@@ -3180,7 +3165,7 @@ larger reference durations space music tightly.
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
   >>
   \layout {
@@ -3194,7 +3179,7 @@ larger reference durations space music tightly.
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
   >>
   \layout {
@@ -3208,7 +3193,7 @@ larger reference durations space music tightly.
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
   >>
   \layout {
@@ -3236,10 +3221,10 @@ tuplet.
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
     \new RhythmicStaff {
-      \tuplet 9/8 { c'8 c' c' c' c' c' c' c' c' }
+      \tuplet 9/8 { c8 8 8 8 8 8 8 8 8 }
     }
   >>
 }
@@ -3254,10 +3239,10 @@ result.  Setting @code{proportionalNotationDuration} fixes this.
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
     \new RhythmicStaff {
-      \tuplet 9/8 { c'8 c' c' c' c' c' c' c' c' }
+      \tuplet 9/8 { c8 8 8 8 8 8 8 8 8 }
     }
   >>
   \layout {
@@ -3279,10 +3264,10 @@ turn on @code{uniform-stretching}, which is a property of
 \score {
   <<
     \new RhythmicStaff {
-      c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
+      c2 16 16 16 16 \tuplet 5/4 { 16 16 16 16 16 }
     }
     \new RhythmicStaff {
-      \tuplet 9/8 { c'8 c' c' c' c' c' c' c' c' }
+      \tuplet 9/8 { c8 8 8 8 8 8 8 8 8 }
     }
   >>
   \layout {
@@ -3378,13 +3363,13 @@ property of @code{SpacingSpanner}.  Compare the two scores below:
 @lilypond[quote,verbatim,ragged-right]
 \new Staff {
   \set Score.proportionalNotationDuration = #(ly:make-moment 1/16)
-  c''8 c'' c'' \clef alto d' d'2
+  c''8 8 8 \clef alto d'2 2
 }
 
 \new Staff {
   \set Score.proportionalNotationDuration = #(ly:make-moment 1/16)
   \override Score.SpacingSpanner.strict-note-spacing = ##t
-  c''8 c'' c'' \clef alto d' d'2
+  c''8 8 8 \clef alto d'2 2
 }
 @end lilypond
 
index 278ffc97c0aefb0d3e148bfb684b37adfe377bf4..e7133e3d4f6f9ffb34f84b0c3cc4712d86744e1e 100644 (file)
@@ -1355,7 +1355,7 @@ oboeNotes = \relative c'' {
 The name of the instrument playing the cue can be printed by setting
 the @code{instrumentCueName} property in a temporary @code{CueVoice}
 context.  The placement and style of the @code{instrumentCueName} is
-controlled by the @code{\instrumentSwitch} object, see
+controlled by the @code{InstrumentSwitch} object, see
 @ref{Instrument names}.  If the cue notes require a change in clef,
 this can be done manually but the original clef should also be
 restored manually at the end of the cue notes.
index f168dc9e13b82f70f493cab9dd2d5ef538c6fd29..06aa65d46d7133a6933f31facc9e9f91b438d5b2 100644 (file)
@@ -1694,9 +1694,8 @@ words = \lyricmode { la __ la __ }
 >>
 @end lilypond
 
-The @code{NullVoice} context must be inside a @code{Staff}
-context, and should only contain notes that are already being
-displayed in that staff, and in the same octave.  Otherwise the
+The @code{NullVoice} context must be placed within a @code{Staff}
+context and contain notes that are already being displayed in that staff and that are also in the same octave.  Otherwise the
 @code{NullVoice} may interact with the printed voices in
 unexpected ways.  For example, arbitrary notes in the
 @code{NullVoice} may cause accidentals to appear (or disappear) on
@@ -1718,6 +1717,10 @@ words = \lyricmode { la __ la __ }
 >>
 @end lilypond
 
+@knownissues
+The @code{\addLyrics} function only works with @code{Voice} lyrics
+and so cannot be used with @code{NullVoice}.
+
 @noindent
 The @code{\partcombine} function is described in
 @ref{Automatic part combining}.
index 6189d3f64bb714355b5813f6b7ab3e7e1f3b9434..0cbcfeb719f293ba263b5898181e9e1bfbb35e69 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.6
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index 92c409229169f066c66d2a7189d5048a8574eb0f..fbab93e75f1193105c57a6a6e5d735c2ae285472 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.20
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index c69fc05c6b262cdc1e5ff200feb76989109bb7b1..e0257869b78ebe016e8de761ffd877034f59b50b 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.11
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index 9657cfe775b0845a1eae4f61a86475282d3df652..96a6bcc153de26b30a0e29441ae687847c003706 100644 (file)
@@ -1,10 +1,11 @@
-%% DO NOT EDIT this file manually; it is automatically
-%% generated from LSR http://lsr.dsi.unimi.it
-%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
-%% and then run scripts/auxiliar/makelsr.py
-%%
-%% This file is in the public domain.
-\version "2.16.0"
+% DO NOT EDIT this file manually; it is automatically
+% generated from Documentation/snippets/new
+% Make any changes in Documentation/snippets/new/
+% and then run scripts/auxiliar/makelsr.py
+%
+% This file is in the public domain.
+%% Note: this file works from version 2.19.0
+\version "2.19.0"
 
 \header {
   lsrtags = "contemporary-notation, rhythms"
@@ -47,7 +48,7 @@ carry both a left- and right-pointing flat flag. Do this with paired
 (Note that @code{\\set stemLeftBeamCount} is always equivalent to
 @code{\\once \\set}.  In other words, the beam count settings are not
 @qq{sticky}, so the pair of flat flags attached to the lone
-@code{c'16[]} in the last example have nothing to do with the
+@code{16[]} in the last example have nothing to do with the
 @code{\\set} two notes prior.)
 
 
@@ -69,25 +70,25 @@ carry both a left- and right-pointing flat flag. Do this with paired
     \new RhythmicStaff {
       r8.
       \set stemRightBeamCount = #0
-      c16[]
+      16[]
     }
     % Example 3
     \new RhythmicStaff {
-      c16 c
+      16 16
       \set stemRightBeamCount = #2
-      c16 r r
+      16 r r
       \set stemLeftBeamCount = #2
-      c16 c c
+      16 16 16
     }
     % Example 4
     \new RhythmicStaff {
-      c16 c
+      16 16
       \set stemRightBeamCount = #2
-      c16 r
-      c16[]
+      16 r16
+      16[]
       r16
       \set stemLeftBeamCount = #2
-      c16 c
+      16 16
     }
   >>
 }
index 43f92c152f3fbe5788d0fd89fef5850828e9d01f..6b8f910d87befa5bb75c7813b931a50692890b7c 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.11
+%% Note: this file works from version 2.17.30
 % INSPIRATIONAL HEADER FOR LILYPOND DOCUMENTATION fretted-strings %
 % Passage from Johann Kaspar Mertz "Opern Revue, Op. 8, no. 17"   %
 % on melodies from Bellini's "Norma"                              %
index 205edecfdaa3e1188b9cc2517317b84a25fdeed8..e2e2b802f24fede1310cb090275fc24d0b14ca1d 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.20
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index 1a4328a58fb0ae5728d2797a22d7fed27f2b474f..b078cc0f538a3e3c5879103f08abf5429019f359 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.10
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
@@ -21,10 +21,7 @@ incipit =
 #(define-music-function (parser location incipit-music) (ly:music?)
   #{
     \once \override Staff.InstrumentName.self-alignment-X = #RIGHT
-    \once \override Staff.InstrumentName.self-alignment-Y = #UP
-    \once \override Staff.InstrumentName.Y-offset =
-      #(lambda (grob)
-         (+ 4 (system-start-text::calc-y-offset grob)))
+    \once \override Staff.InstrumentName.self-alignment-Y = ##f
     \once \override Staff.InstrumentName.padding = #0.3
     \once \override Staff.InstrumentName.stencil =
       #(lambda (grob)
@@ -35,7 +32,6 @@ incipit =
                         {
                           { \context MensuralStaff \with {
                                instrumentName = #instrument-name
-                               \override VerticalAxisGroup.Y-extent = #'(-4 . 4)
                             } $incipit-music
                           }
                           \layout { $(ly:grob-layout grob)
index 89cec8be7128c5424eae6b55afdc1946378409b0..4f0570da2c59e251d2e7572876132ae3e775a3b3 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.20
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index 572e39ca50852669f0f7751dc9e889a10af556e9..c7ad7b10a5585dd30f10c28a4fa5182ccf0a36e0 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.6
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index fd7b1e92c1cd639b9ef44b846891ca9741228555..16799a19cfde7d9a4d90cae5e2d7d1f158773331 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.6
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index bde66e61680a96f7a3d805cd5941149b5e0f8c71..f19f6bc318e0c8922cf079b8fbf223f7fec960c0 100644 (file)
@@ -1,10 +1,11 @@
-%% DO NOT EDIT this file manually; it is automatically
-%% generated from LSR http://lsr.dsi.unimi.it
-%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
-%% and then run scripts/auxiliar/makelsr.py
-%%
-%% This file is in the public domain.
-\version "2.17.11"
+% DO NOT EDIT this file manually; it is automatically
+% generated from Documentation/snippets/new
+% Make any changes in Documentation/snippets/new/
+% and then run scripts/auxiliar/makelsr.py
+%
+% This file is in the public domain.
+%% Note: this file works from version 2.19.0
+\version "2.19.0"
 
 \header {
   lsrtags = "really-simple, rhythms"
@@ -30,11 +31,11 @@ modify what material they cover.
   % ...to cover all items up to the next note
   \set tupletFullLengthNote = ##t
   \time 2/4
-  \tuplet 3/2 { c4 c c }
+  \tuplet 3/2 { c4 4 4 }
   % ...or to cover just whitespace
   \set tupletFullLengthNote = ##f
   \time 4/4
-  \tuplet 5/4 { c4 c1 }
+  \tuplet 5/4 { 1 }
   \time 3/4
-  c2.
+  2.
 }
diff --git a/Documentation/snippets/new/flat-flags-and-beam-nibs.ly b/Documentation/snippets/new/flat-flags-and-beam-nibs.ly
new file mode 100644 (file)
index 0000000..754394b
--- /dev/null
@@ -0,0 +1,86 @@
+\version "2.19.0"
+
+\header {
+  lsrtags = "contemporary-notation, rhythms"
+
+  texidoc = "
+ Flat flags on lone notes and beam nibs at the ends of beamed figures
+are both possible with a combination of @code{stemLeftBeamCount},
+@code{stemRightBeamCount} and paired @code{[]} beam indicators.
+
+
+
+
+For right-pointing flat flags on lone notes, use paired @code{[]} beam
+indicators and set @code{stemLeftBeamCount} to zero (see Example 1).
+
+
+
+
+For left-pointing flat flags, set @code{stemRightBeamCount} instead
+(Example 2).
+
+
+
+
+For right-pointing nibs at the end of a run of beamed notes, set
+@code{stemRightBeamCount} to a positive value. And for left-pointing
+nibs at the start of a run of beamed notes, set
+@code{stemLeftBeamCount} instead (Example 3).
+
+
+
+
+Sometimes it may make sense for a lone note surrounded by rests to
+carry both a left- and right-pointing flat flag. Do this with paired
+@code{[]} beam indicators alone (Example 4).
+
+
+
+
+(Note that @code{\\set stemLeftBeamCount} is always equivalent to
+@code{\\once \\set}.  In other words, the beam count settings are not
+@qq{sticky}, so the pair of flat flags attached to the lone
+@code{16[]} in the last example have nothing to do with the
+@code{\\set} two notes prior.)
+
+
+
+
+"
+  doctitle = "Flat flags and beam nibs"
+}
+\score {
+  <<
+    % Example 1
+    \new RhythmicStaff {
+      \set stemLeftBeamCount = #0
+      c16[]
+      r8.
+    }
+    % Example 2
+    \new RhythmicStaff {
+      r8.
+      \set stemRightBeamCount = #0
+      16[]
+    }
+    % Example 3
+    \new RhythmicStaff {
+      16 16
+      \set stemRightBeamCount = #2
+      16 r r
+      \set stemLeftBeamCount = #2
+      16 16 16
+    }
+    % Example 4
+    \new RhythmicStaff {
+      16 16
+      \set stemRightBeamCount = #2
+      16 r16
+      16[]
+      r16
+      \set stemLeftBeamCount = #2
+      16 16
+    }
+  >>
+}
index 09f50ff56e6d5169398400e6f5b7a0fa4a5dd1fc..3b85ef170cd384763180132e8d4208afcffd275d 100644 (file)
@@ -13,10 +13,7 @@ incipit =
 #(define-music-function (parser location incipit-music) (ly:music?)
   #{
     \once \override Staff.InstrumentName.self-alignment-X = #RIGHT
-    \once \override Staff.InstrumentName.self-alignment-Y = #UP
-    \once \override Staff.InstrumentName.Y-offset =
-      #(lambda (grob)
-         (+ 4 (system-start-text::calc-y-offset grob)))
+    \once \override Staff.InstrumentName.self-alignment-Y = ##f
     \once \override Staff.InstrumentName.padding = #0.3
     \once \override Staff.InstrumentName.stencil =
       #(lambda (grob)
@@ -27,7 +24,6 @@ incipit =
                         {
                           { \context MensuralStaff \with {
                                instrumentName = #instrument-name
-                               \override VerticalAxisGroup.Y-extent = #'(-4 . 4)
                             } $incipit-music
                           }
                           \layout { $(ly:grob-layout grob)
diff --git a/Documentation/snippets/new/modifying-tuplet-bracket-length.ly b/Documentation/snippets/new/modifying-tuplet-bracket-length.ly
new file mode 100644 (file)
index 0000000..6ee36e8
--- /dev/null
@@ -0,0 +1,33 @@
+\version "2.19.0"
+
+\header {
+  lsrtags = "really-simple, rhythms"
+
+  texidoc = "
+Tuplet brackets can be made to run to prefatory matter or the next
+note. Default tuplet brackets end at the right edge of the final note
+of the tuplet; full-length tuplet brackets extend farther to the right,
+either to cover all the non-rhythmic notation up to the following note,
+or to cover only the whitespace before the next item of notation, be
+that a clef, time signature, key signature, or another note.  The
+example shows how to switch tuplets to full length mode and how to
+modify what material they cover.
+
+"
+  doctitle = "Modifying tuplet bracket length"
+}
+
+\new RhythmicStaff {
+  % Set tuplets to be extendable...
+  \set tupletFullLength = ##t
+  % ...to cover all items up to the next note
+  \set tupletFullLengthNote = ##t
+  \time 2/4
+  \tuplet 3/2 { c4 4 4 }
+  % ...or to cover just whitespace
+  \set tupletFullLengthNote = ##f
+  \time 4/4
+  \tuplet 5/4 { 4 1 }
+  \time 3/4
+  2.
+}
index 67bc0f628684fcf2648bf96d944b717286113f70..a23b5cb06323cb9f337bc8f8b4f8789e6efad74c 100644 (file)
@@ -35,22 +35,13 @@ trompette = \relative do'' {
   do8-. r8 sib4-> |
 }
 
-tambourin = \relative do' {
+tambourin = \drummode {
   \time 2/4
-  r8 do16 do do8 do |
-  r8 do16 do do8 do |
-  r8 do r do |
-  r8 do16 do do8 do |
-  r8 do r do |
-}
-
-tambourinMidi = \drummode {
-  \time 2/4
-  r8 tamb16 tamb tamb8 tamb |
-  r8 tamb16 tamb tamb8 tamb |
-  r8 tamb r tamb |
-  r8 tamb16 tamb tamb8 tamb |
-  r8 tamb r tamb |
+  r8 tamb16 16 8 8 |
+  r8 16 16 8 8 |
+  r8 8 r8 8 |
+  r8 16 16 8 8 |
+  r8 8 r8 8 |
 }
 
 upper = \relative do' {
@@ -102,7 +93,7 @@ lower = \relative do {
       \trompette
     }
     \context DrumStaff = "tambourin" {
-      \tambourinMidi
+      \tambourin
     }
     \context Staff = "piano" <<
       \upper
@@ -113,4 +104,3 @@ lower = \relative do {
     \tempo 4 = 72
   }
 }
-
index eebc8de67a62bde28c8bdd2ef4f455d69275b750..46883755e6b6e55885e0621009982ac7962c2626 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.20
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index 6e81017f846d1341681d00a4d094468feac10a01..952b5d833f3119e982a25913472060be5c53cf39 100644 (file)
@@ -43,22 +43,13 @@ trompette = \relative do'' {
   do8-. r8 sib4-> |
 }
 
-tambourin = \relative do' {
+tambourin = \drummode {
   \time 2/4
-  r8 do16 do do8 do |
-  r8 do16 do do8 do |
-  r8 do r do |
-  r8 do16 do do8 do |
-  r8 do r do |
-}
-
-tambourinMidi = \drummode {
-  \time 2/4
-  r8 tamb16 tamb tamb8 tamb |
-  r8 tamb16 tamb tamb8 tamb |
-  r8 tamb r tamb |
-  r8 tamb16 tamb tamb8 tamb |
-  r8 tamb r tamb |
+  r8 tamb16 16 8 8 |
+  r8 16 16 8 8 |
+  r8 8 r8 8 |
+  r8 16 16 8 8 |
+  r8 8 r8 8 |
 }
 
 upper = \relative do' {
@@ -110,7 +101,7 @@ lower = \relative do {
       \trompette
     }
     \context DrumStaff = "tambourin" {
-      \tambourinMidi
+      \tambourin
     }
     \context Staff = "piano" <<
       \upper
index 8beaa131c50326e32b4a6e929c7b903902255d2a..6cc02b677d2b580cf2caf29708c8e82d3af7a543 100644 (file)
@@ -4,7 +4,7 @@
 % and then run scripts/auxiliar/makelsr.py
 %
 % This file is in the public domain.
-%% Note: this file works from version 2.17.24
+%% Note: this file works from version 2.17.30
 \version "2.17.30"
 
 \header {
index f6cbc0980cf42ed948b37922efe65dcdac290ea4..7c386ae733f802bb898d9944a068a5fbc2385fa0 100644 (file)
@@ -364,6 +364,7 @@ your @file{$HOME/.vimrc} to contain these three lines, in order:
 filetype off
 set runtimepath+=/usr/local/share/lilypond/current/vim/
 filetype on
+syntax on
 @end example
 
 @noindent
@@ -703,7 +704,7 @@ the automated method with @command{lilypond-book}.
 
 @menu
 * Many quotes from a large score::
-* Inserting LilyPond output into OpenOffice.org::
+* Inserting LilyPond output into OpenOffice and LibreOffice::
 * Inserting LilyPond output into other programs::
 @end menu
 
@@ -714,12 +715,13 @@ If you need to quote many fragments from a large score, you can also use
 the clip systems feature, see @ruser{Extracting fragments of music}.
 
 
-@node Inserting LilyPond output into OpenOffice.org
-@unnumberedsubsec Inserting LilyPond output into OpenOffice.org
+@node Inserting LilyPond output into OpenOffice and LibreOffice
+@unnumberedsubsec Inserting LilyPond output into OpenOffice and LibreOffice
 
 @cindex OpenOffice.org
+@cindex LibreOffice.org
 
-LilyPond notation can be added to OpenOffice.org with
+LilyPond notation can be added to OpenOffice.org and LibreOffice with
 @uref{http://@/ooolilypond@/.sourceforge@/.net@/,OOoLilyPond}.
 
 
index 9e736bda0139d25349a5dda61ac6e6a240dc929e..7e7692c86dff6d536474f45c3a507457c1263af9 100644 (file)
@@ -664,6 +664,17 @@ point exceptions.
 @tab Don't use directories from input files while constructing output
 file names.
 
+@item @code{strokeadjust}
+@tab @code{#f}
+@tab Force PostScript stroke adjustment.  This option is mostly
+relevant when @code{PDF} is generated from PostScript output
+(stroke adjustment is usually enabled automatically for
+low-resolution bitmap devices).  Without this option,
+@code{PDF}@tie{}previewers tend to produce widely inconsistent
+stem widths at resolutions typical for screen display.  The option
+does not noticeably affect print quality and causes large file
+size increases in @code{PDF} files.
+
 @item @code{svg-woff}
 @tab @code{#f}
 @tab Use woff font files in SVG backend.
index 06a960ac8a866faff27da9fece4208a96d395a78..ad92a834e35db8307521379f9dc4bd9789e6ce09 100644 (file)
@@ -151,8 +151,11 @@ The following options can be given:
 @item -d, --diff-version-update
 increase the @code{\version} string only if the file has actually
 been changed.  In that case, the version header will correspond to
-the version after the last actual change.  Without that option,
-the version will reflect the last @emph{attempted} conversion.
+the version after the last actual change.  An unstable version
+number will be rounded up to the next stable version number unless
+that would exceed the target version number.  Without this option,
+the version will instead reflect the last @emph{attempted}
+conversion.
 
 @item -e, --edit
 Apply the conversions direct to the input file, modifying it
index e6b077d328972fbea17a9ccbd033c75f5af90bdd..621488e92f53b98df0714c4fc46b49335a220d71 100644 (file)
@@ -306,8 +306,12 @@ Distributions will want to install lilypond.info in postinstall, doing:
 @divClass{heading-center}
 @divClass{contactBox}
 If you are aware of any other \topic\ which could be listed here,
-please let us know by following the instructions on
-@ref{Bug reports}.
+please let us know by writing a message to the bug-lilypond
+mailing list. If you're not subscribed yet you can do so on the list's
+@uref{https://lists.gnu.org/mailman/listinfo/bug-lilypond,info page}
+or post directly through the
+@uref{http://post.gmane.org/post.php?group=gmane.comp.gnu.lilypond.bugs,
+gmane lilypond.bugs web interface}.
 
 @divEnd
 @divEnd
index 91bd1a334ca98a8b106c7cffdbe0dbcd1d7c0d92..4781d161b7134486f7d446c0246a6614000d8407 100644 (file)
@@ -142,13 +142,13 @@ acknowledged.
 @divClass{column-center-top}
 @subheading Generic Packages or Distribution-Specific Packages?
 
-Many distributions include LilyPond in their normal package
-system.  These versions are easier to install and uninstall than
-the generic packages, but they may be older.  If you wish to use
-our generic packages, please uninstall the official version from
-your system using the normal package manager for your distribution.
-See your distribution's documentation about how to use their
-package manager.
+Many distributions already include LilyPond within their normal
+package repositories and these are often much easier to install than the
+generic packages found here.  However the version of LilyPond in those
+repositories may be @emph{significantly} older than the current stable
+version.  If you wish to use our generic packages, please check that
+your LilyPond editor is using the correct version of lilypond.  See
+@ref{Easier editing}.
 
 @divEnd
 
index 01172cc00fb985857e7f5e9fc20bb597eead2121..43f4e4fc3c3bc79f4d372f23b2d024e019ad5b42 100644 (file)
@@ -142,10 +142,10 @@ simply save a file for later reference.
 @subsubheading Mix music and text
 
 Put fragments of music into texts without cutting and pasting
-pictures.  Integrate music into @LaTeX{} or HTML seamlessly, or add
-music to OpenOffice.org with OOoLilyPond.  Plugins are also available
-to allow LilyPond code in various blogs and wikis, making online
-collaboration possible.
+pictures.  Integrate music into @LaTeX{} and HTML seamlessly, or add
+music to OpenOffice.org or LibreOffice with OOoLilyPond.  Plugins are
+also available to allow LilyPond code in various blogs and wikis, making
+online collaboration possible.
 
 
 @subsubheading Accessibility
@@ -497,6 +497,19 @@ Some highlights:
 @divClass{keep-bullets}
 @itemize
 
+@item
+Joe Smeets created sheet music for the children's book @emph{Zing Mee}
+(@emph{Sing along}) by Annie M.G. published by Querido -- ISBN
+9789045106205:
+@uref{http://www.queridokinderenjeugdboeken.nl/web/Boek.htm?dbid=18954&typeofpage=134707, www.queridokinderenjeugdboeken.nl}; choir
+rehearsal scores for the Dutch translation of Benjamin Britten's
+@emph{Saint Nicolas} performed by @emph{Muziektheater Hollands Diep} in
+2011.
+@uref{http://www.muziektheaterhollandsdiep.nl/nl/voorstellingen/sint_nicolaas_leeft, www.muziektheaterhollandsdiep.nl}; and is currently
+working on the score and parts for an arrangement of Moussurgsky's
+@emph{Boris Godounov} for wind quartet, piano and percussion.  To be
+performed in 2014, again by @emph{Muziektheater Hollands Diep}.
+
 @item
 A critical edition of Tommaso Traetta's @emph{Enea nel Lazio (1760)},
 opera series with libretto by Vittorio Amedeo Cigna-Santi, in four
@@ -1023,6 +1036,10 @@ correctly, when in fact it is working precisely as designed.
 
 More in-depth information is available in @ref{Manuals}.
 
+Ben Lemon, a LilyPond user, has created a range of
+@uref{http://benlemon.me/blog/music/lilypond/operation-lilypond/,video tutorials}
+on his blog and which are aimed at new users.
+
 
 @subsubheading Easier editing environments
 
@@ -1073,7 +1090,7 @@ In particular, don't link to:
 @uref{http://www.tunefl.com}
 
 With tunefl you can typeset your scores directly online
-without needing to install lilypond locally. It allows
+without needing to install LilyPond locally. It allows
 trying out all the program's features using a convenient
 web interface.
 
@@ -1301,7 +1318,7 @@ and @uref{http://canorus.org,Canorus}.
 @item
 @uref{http://lilycomp.sourceforge.net, LilyComp} is a graphical
 note entry program, acting much like a number-pad which produces
-lilypond notes.
+LilyPond notes.
 
 @end itemize
 
index 956ac12976dcbda17d8f66337de64224b3f8e64d..0484ecab20c621e0bd1edb8c69968b53872fe9ce 100644 (file)
@@ -132,6 +132,11 @@ translation status for non-English readers.
 @uref{http://lsr@/.dsi@/.unimi@/.it,LilyPond Snippet Repository}:
 user-created examples, hints and tips.
 
+@item
+@uref{http://benlemon.me/blog/music/lilypond/operation-lilypond/,Video Tutorials}:
+Ben Lemon, a LilyPond user, has created a range of video tutorials on
+his blog and which are aimed at new users.
+
 @item
 @ref{Development}:
 manuals for the unstable version.
index 8d45279fb857c7aee23067d83d36de39f509ca76..0d8b05774d703d4ce3423f1c2f26944609fb7ff0 100644 (file)
@@ -9,17 +9,16 @@
 @c used for news about the upcoming release; see CG 10.2
 
 @newsItem
-@subsubheading LilyPond 2.17.95 released!  @emph{November 3, 2013}
+@subsubheading LilyPond 2.17.97 released!  @emph{December 8, 2013}
 
-We are excited to announce the release of LilyPond@tie{}2.17.95 as
-beta release for the upcoming stable release@tie{}2.18.  The
-developers are still busy finding solutions for some last-minute
-problems, but the release is supposed to be feature-complete, the
+We are excited to announce the release of LilyPond@tie{}2.17.97 as
+a potential final beta release for the upcoming stable release@tie{}2.18.  The
+developers believe this to be feature-complete, the
 documentation to be accurate, and no important issues to be
 overlooked.  For upgrading the syntax of your input files to the
-latest version, see @rprogram{Updating files with convert-ly}.
+latest version, see @uref{http://www.lilypond.org/doc/v2.17/Documentation/usage/updating-files-with-convert_002dly, Updating files with convert-ly}.
 Please test this release and report back any problems, see
-@rweb{Bug reports}.
+@uref{http://www.lilypond.org/website/bug-reports.html, Bug reports}.
 
 @newsEnd
 
index 9a548e02d54e96d32a865527d3ed5df0b29ceacd..c0a4e9f0d55fc7de637237502cf00753fbda64a9 100644 (file)
@@ -26,6 +26,35 @@ NOTE:
   * don't duplicate entries from news-front.itexi
 @end ignore
 
+@newsItem
+@subsubheading LilyPond 2.17.96 released!  @emph{November 24, 2013}
+
+We are excited to announce the release of LilyPond@tie{}2.17.96 as
+a further beta release for the upcoming stable release@tie{}2.18.  The
+developers believe the release to be feature-complete, the
+documentation to be accurate, and no important issues to be
+overlooked.  For upgrading the syntax of your input files to the
+latest version, see @uref{http://www.lilypond.org/doc/v2.17/Documentation/usage/updating-files-with-convert_002dly, Updating files with convert-ly}.
+Please test this release and report back any problems, see
+@uref{http://www.lilypond.org/website/bug-reports.html, Bug reports}.
+
+@newsEnd
+
+@newsItem
+@subsubheading LilyPond 2.17.95 released!  @emph{November 3, 2013}
+
+We are excited to announce the release of LilyPond@tie{}2.17.95 as
+beta release for the upcoming stable release@tie{}2.18.  The
+developers are still busy finding solutions for some last-minute
+problems, but the release is supposed to be feature-complete, the
+documentation to be accurate, and no important issues to be
+overlooked.  For upgrading the syntax of your input files to the
+latest version, see @rprogram{Updating files with convert-ly}.
+Please test this release and report back any problems, see
+@rweb{Bug reports}.
+
+@newsEnd
+
 @newsItem
 @subsubheading LilyPond 2.17.29 released!  @emph{October 20, 2013}
 
index 71609b7c38c8f599883d83c242806b8ffc7535a0..d6f425ed248d9c999627df817d71c2f0c6298b19 100644 (file)
     about them on his &lt;a
     href="http://benlemon.me/blog/music/lilypond/operation-lilypond/"&gt;blog&lt;/a&gt;.
   </tweet>
+  <tweet>
+    Server Acim, composer and professor of Composition and Conducting
+    in &#304;n&#246;n&#252; University - Malatya, Turkey, wrote the
+    Turkish Ebook &lt;a href="http://yadi.sk/d/fNmncSQ3DR3Ck"&gt;
+    "GNU/LilyPond, &#214;zg&#252;r Bir Nota Yazma Program&#305;"&lt;/a&gt;.
+  </tweet>
 </tweets>
index 6b8b02c627936826d5b77fa9684a60f4f9d5d69f..783923c2abded9ffa6ea9f354fc68ec6236d321b 100644 (file)
@@ -1,3 +1,10 @@
+@misc{acim13,
+  title = {Open Book about GNU/LilyPond},
+  author = {Server Acim, Professor of Composition and Conducting at Inonu University, Turkey},
+  booktitle = {A book in the Turkish language about how to use GNU/LilyPond},
+  year = 2013,
+  note = {(@uref{http://library.inonu.edu.tr/dosya/files/gnulilypond-serveracim.pdf, PDF 2100k})}
+}
 
 @inproceedings{hanwen06,
   title = {LilyPond, Automated music formatting and the Art of Shipping},
diff --git a/VERSION b/VERSION
index e2867ac71cac4a1c81c8093519f22c08cfb56bf5..2db7fe3c6df2bc7364429222ec1288e9767d2fca 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
-MINOR_VERSION=17
-PATCH_LEVEL=96
+MINOR_VERSION=19
+PATCH_LEVEL=0
 MY_PATCH_LEVEL=
 VERSION_STABLE=2.16.2
-VERSION_DEVEL=2.17.95
+VERSION_DEVEL=2.17.97
index e7f29a8fcbb05065e0157f7c60c586b4e2309823..8275b929303a25f29d6025a31f31e439a7a2fb95 100644 (file)
@@ -30,6 +30,7 @@
 #endif
 #endif
 
+#include "config.hh"   /* needed at least for HAVE_STL_DATA_METHOD */
 #include <algorithm>   /* find, reverse, sort */
 #include <functional>  /* unary_function */
 #include <cassert>
index eebcd92708076919e17f874ddab85e8b28474270..745a98ecea6a28bec022316114991f6153eca513 100644 (file)
@@ -37,8 +37,8 @@ string
 String_convert::bin2hex (Byte bin_char)
 {
   string str;
-  str += to_string ((char) nibble2hex_byte ((Byte) (bin_char >> 4)));
-  str += to_string ((char) nibble2hex_byte (bin_char++));
+  str += ::to_string ((char) nibble2hex_byte ((Byte) (bin_char >> 4)));
+  str += ::to_string ((char) nibble2hex_byte (bin_char++));
   return str;
 }
 
@@ -49,8 +49,8 @@ String_convert::bin2hex (const string &bin_string)
   Byte const *byte = (Byte const *)bin_string.data ();
   for (ssize i = 0; i < bin_string.length (); i++)
     {
-      str += to_string ((char)nibble2hex_byte ((Byte) (*byte >> 4)));
-      str += to_string ((char)nibble2hex_byte (*byte++));
+      str += ::to_string ((char)nibble2hex_byte ((Byte) (*byte >> 4)));
+      str += ::to_string ((char)nibble2hex_byte (*byte++));
     }
   return str;
 }
@@ -127,7 +127,7 @@ String_convert::hex2bin (string hex_string, string &bin_string_r)
       int low_i = hex2nibble (*byte++);
       if (high_i < 0 || low_i < 0)
         return 1; // invalid char
-      bin_string_r += to_string ((char) (high_i << 4 | low_i), 1);
+      bin_string_r += ::to_string ((char) (high_i << 4 | low_i), 1);
       i += 2;
     }
   return 0;
@@ -165,10 +165,10 @@ String_convert::int2dec (int i, size_t length_i, char ch)
     fill_char = '0';
 
   // ugh
-  string dec_string = to_string (i);
+  string dec_string = ::to_string (i);
 
   // ugh
-  return to_string (fill_char, ssize_t (length_i - dec_string.length ())) + dec_string;
+  return ::to_string (fill_char, ssize_t (length_i - dec_string.length ())) + dec_string;
 }
 
 // stupido.  Should use int_string ()
@@ -182,14 +182,14 @@ String_convert::unsigned2hex (unsigned u, size_t length, char fill_char)
 #if 1 // both go...
   while (u)
     {
-      str = to_string ((char) ((u % 16)["0123456789abcdef"])) + str;
+      str = ::to_string ((char) ((u % 16)["0123456789abcdef"])) + str;
       u /= 16;
     }
 #else
   str += int_string (u, "%x");  // hmm. %lx vs. %x -> portability?
 #endif
 
-  str = to_string (fill_char, ssize_t (length - str.length ())) + str;
+  str = ::to_string (fill_char, ssize_t (length - str.length ())) + str;
   while ((str.length () > length) && (str[ 0 ] == 'f'))
     str = str.substr (2);
 
@@ -299,7 +299,7 @@ String_convert::pointer_string (void const *l)
 string
 String_convert::precision_string (double x, int n)
 {
-  string format = "%." + to_string (max (0, n - 1)) + "e";
+  string format = "%." + ::to_string (max (0, n - 1)) + "e";
   string str = double_string (abs (x), format.c_str ());
 
   int exp = dec2int (str.substr (str.length () - 3));
@@ -316,9 +316,9 @@ String_convert::precision_string (double x, int n)
   str = str.substr (0, 1) + str.substr (2);
   ssize dot = 1 + exp;
   if (dot <= 0)
-    str = "0." + to_string ('0', -dot) + str;
+    str = "0." + ::to_string ('0', -dot) + str;
   else if (dot >= str.length ())
-    str += to_string ('0', dot - str.length ());
+    str += ::to_string ('0', dot - str.length ());
   else if ((dot > 0) && (dot < str.length ()))
     str = str.substr (0, dot) + "." + str.substr (dot);
   else
index 676bb3aafb27846a4aa5215650621a56acb4b177..b7d553b1234e03d6266caf29898b84d543ddb63e 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.16.0"
+\version "2.19.0"
 
 \header {
 
 
 \relative c' {
   \time 2/4
-  \set Score.beamExceptions = #'(
-    ( end .
-      (
-        ( (1 . 32) . (4 4 4 4) )
-      )
-    )
-  )
+  \set Score.beamExceptions =
+    \beamExceptions \repeat unfold 4 { 32[ 32 32 32] }
   \repeat unfold 16 c32
   \time 3/4
-  \set Score.beamExceptions = #'(
-    ( end .
-      (
-        ( (1 . 32) . (4 4 4 4 4 4) )
-      )
-    )
-  )
+  \set Score.beamExceptions =
+    \beamExceptions \repeat unfold 6 { 32[ 32 32 32] }
   \repeat unfold 24 c32
   c8 c32 c32 c32 c32 c16 c16 c32 c32 c32 c32 c16 c32 c32 c32 c32 c32 c32
   \time 4/4
-  \set Score.beamExceptions = #'(
-    ( end .
-      (
-        ( (1 . 32) . (4 4 4 4 4 4 4 4) )
-      )
-    )
-  )
+  \set Score.beamExceptions =
+    \beamExceptions \repeat unfold 8 { 32[ 32 32 32] }
   \repeat unfold 32 c32
   \time 6/8
-  \set Score.beamExceptions = #'(
-    ( end .
-      (
-        ( (1 . 32) . (4 4 4 4 4 4) )
-      )
-    )
-  )
+  \set Score.beamExceptions =
+    \beamExceptions \repeat unfold 6 { 32[ 32 32 32] }
   \repeat unfold 24 c32
 }
diff --git a/input/regression/chord-dots.ly b/input/regression/chord-dots.ly
new file mode 100644 (file)
index 0000000..957788d
--- /dev/null
@@ -0,0 +1,17 @@
+\version "2.17.16"
+
+\header {
+  texidoc =
+"The column of dots on a chord is limited to the height
+of the chord plus @code{chord-dots-limit} staff-positions."
+}
+
+\layout{ ragged-right = ##t }
+
+\new Staff \transpose c c' {
+  \override Staff.DotColumn.chord-dots-limit = #1
+  <<
+    { <g a b c' d' e'>4. r8 <c' d' e' f' g' a' b'>4. r8 } \\
+    { f4.. r16 <c d e f g a b>4.. r16}
+  >>
+}
index 79510e1484513a4c2e03097277aa8056cb9de885..cc29f58d4eb1a96f1249907fe6188d66c69ef25a 100644 (file)
@@ -1,12 +1,12 @@
-\version "2.16.0"
+\version "2.19.0"
 
 \header{
 texidoc="
 
 If the @code{Note_heads_engraver} is replaced by the @code{Completion_heads_engraver},
-notes with a duration factor still keep their requested appearance.
-
-"
+long notes, longer than @code{measureLength}, are split into un-scaled notes,
+even if the original note used a scale-factor.
+@code{completionFactor} controls this behavior."
 }
 
 \layout { ragged-right= ##t }
@@ -20,5 +20,11 @@ notes with a duration factor still keep their requested appearance.
   c\breve |
   c1*2 |
   c2*4 |
-  c8*20
+  c8*20 r2 \break
+  \tuplet 3/2 { d1 d d }
+  % \breve*2/3 is longer than a measure, but we want a tuplet, not repeats.
+  \set completionFactor = ##f
+  \tuplet 3/2 { e\breve e e }
+  \set completionFactor = #2/3
+  \tuplet 3/2 { e\breve e e }
 }
index e39e17aff898419e01a3bd6726af65430e79b3db..365b7372e2a6a1ae1f86367664fc96e0625bdd0f 100644 (file)
@@ -1,12 +1,12 @@
-\version "2.16.0"
+\version "2.19.0"
 
 \header{
 texidoc="
 
 If the @code{Rest_engraver} is replaced by the @code{Completion_rest_engraver},
-rests with a duration factor still keep their requested appearance.
-
-"
+long rests, longer than @code{measureLength}, are split into
+un-scaled rests, even if the original duration used a scale-factor.
+@code{completionFactor} controls this behavior."
 }
 
 \layout { ragged-right= ##t }
@@ -20,5 +20,9 @@ rests with a duration factor still keep their requested appearance.
   r\breve |
   r1*2 |
   r2*4 |
-  r8*20
+  r8*20 r2 \break
+  \bar "||" \time 2/4
+  r\breve.*2/3
+  \set completionFactor = #1/2
+  r\breve.*2/3^"explicity request r1*1/2 rests"
 }
index a4abc604d1c09dbd86791a4e4e0a08caa3c1c4ae..10dccdded23fe18fc05ba38c22ff89e8b3d2f09b 100644 (file)
@@ -183,6 +183,9 @@ stderr of this run."
 \test ##[ \tuplet 3/2 { c4 d e \tuplet 5/2 { f4 e d2 d4 } c4 } #]
 \test ##[ \tuplet 3/2 2 { c4 d e \tuplet 5/2 2 { f4 e d2 d4 } c4 } #]
 
+%% pure rhythm
+\test ##[ { 4 4 8 \tuplet 3/2 { 8[ 16] } 16 } #]
+
 %% \relative and \tranpose
 \test #"NOT A BUG" ##[ \relative c' { c b } #] % RelativeOctaveMusic
 \test #"NOT A BUG" ##[ \transpose c d { c d } #]       % TransposedMusic
diff --git a/input/regression/header-score-reordered.ly b/input/regression/header-score-reordered.ly
new file mode 100644 (file)
index 0000000..acbe127
--- /dev/null
@@ -0,0 +1,22 @@
+\version "2.19.0"
+\header {
+  texidoc="
+Header blocks may appear before and after the actual music in a score.
+"
+}
+
+\markup \vspace #3
+\markup { \bold Note: expect piece and opus. }
+\markup \vspace #3
+
+\score {
+  \header {
+    piece = "Piece correct (set in score)"
+    opus = "Opus incorrect (to be superseded at score level)"
+  }
+  \new Staff { c'1 }
+  \header {
+    % This should NOT overwrite the piece from above!
+    opus = "Opus correct (superseded at score level)"
+  }
+}
index c87772419dd455a914c337282834c897bbabd9d4..61b79eccd4d12acdfbecdc6980be62a0018c3f6e 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.10"
+\version "2.19.0"
 
 \header {
     composer = "ARTHUR GRAY"
@@ -233,8 +233,9 @@ middleDynamics = {
 theScore = \score{
     \context PianoStaff <<
         \new Staff = "treble" <<
-            \set beamExceptions = #'((end . (((1 . 8) . (2 2 2 2))
-                                           ((1 . 32) . (4 4 4 4 4 4 4 4)))))
+            \set beamExceptions =
+             \beamExceptions { 8[ 8] 8[ 8] 8[ 8] 8[ 8] |
+                               \repeat unfold 8 { 32[ 32 32 32] } }
            \treble
            \trebleTwo
         >>
diff --git a/input/regression/make-relative-copies.ly b/input/regression/make-relative-copies.ly
new file mode 100644 (file)
index 0000000..93c9fe9
--- /dev/null
@@ -0,0 +1,29 @@
+\header {
+  texidoc = "@code{make-relative} has to copy its argument expressions
+in case the generated music expression is getting copied and modified.
+
+The code here defines a @code{\\reltranspose} function working inside
+of @code{\\relative} and uses it.  Both staves should appear
+identical."
+}
+
+\layout {
+  ragged-right = ##t
+}
+
+reltranspose =
+#(define-music-function (parser location from to music)
+  (ly:pitch? ly:pitch? ly:music?)
+  (make-relative (music) music
+   #{ \transpose #from #to $music #}))
+
+mus =
+\reltranspose c g {
+  \partial 4. c8 e g |
+  c2 r8 c, e g c1 | \bar "|."
+}
+
+<<
+  \new Staff \relative \mus
+  \new Staff \relative \mus
+>>
diff --git a/input/regression/make-relative-music.ly b/input/regression/make-relative-music.ly
new file mode 100644 (file)
index 0000000..58266b2
--- /dev/null
@@ -0,0 +1,32 @@
+\version "2.19.0"
+
+\header {
+  texidoc = "@code{make-relative} can make relativization on music
+function calls behave as one would expect from looking at the
+function's arguments rather than at the actually resulting
+expressions.  This regtest defines an example function
+@code{\\withOctave} which works equally well inside and outside of
+@code{\\relative}." 
+}
+
+withOctave =
+#(define-music-function (parser location music)
+  (ly:music?)
+  (make-relative
+   (music) music
+   #{ \context Bottom << $music \transpose c c' $music >> #}))
+
+mus = {
+  \partial 4. c'8 e g |
+  c2 e,4 g |
+  c,8 c' b a <g d'> <f c'> <e b'> <d a'> |
+  <c g'>1 | \bar "|."
+}
+
+<<
+  \relative \new Staff { <>^"original" \mus }
+  \relative \new Staff { <>^\markup \typewriter "\\relative \\withOctave"
+                        \withOctave \mus }
+  \new Staff { <>^\markup \typewriter "\\withOctave \\relative"
+              \withOctave \relative \mus }
+>>
index 706bdb9adc3aec8508d29fa938f06931ecef5d2f..04bbed39005636ea0403f70745c5e4cb84eba9aa 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.11"
+\version "2.19.0"
 \header {
 
   texidoc = "@code{make-relative} is a Scheme utility macro mainly
@@ -16,7 +16,7 @@ The fragment should appear identical in both cases."
 ph =
 #(define-music-function (parser location p1 p2 p3 p4 p5)
   (ly:pitch? ly:pitch? ly:pitch? ly:pitch? ly:pitch?)
-  (make-relative (p1 p2 p3 p4 p5) p1
+  (make-relative (p1 p2 p3 p4 p5) (make-event-chord (list p1 p2 p3 p4 p5))
    #{
      \repeat unfold 2 { $p1 2 } |
      \repeat unfold 2 { r16 $p2 8. ~ $p2 4 } |
diff --git a/input/regression/midi-grace-after-rest.ly b/input/regression/midi-grace-after-rest.ly
new file mode 100644 (file)
index 0000000..8a99cdd
--- /dev/null
@@ -0,0 +1,14 @@
+\header {
+  texidoc = "Grace notes shorten previous notes only if they'd overlap
+them. The A should be a full quarter note, but the C should be shortened
+to 1/4 - 9/40 * 1/8 = 71/320 (rounded down to 340/384 in MIDI)."
+}
+\version "2.18.0"
+\score {
+ \relative c' {
+   a4 r
+   \grace b8 c8... r64
+   \grace d8 e4
+ }
+ \midi { }
+}
index 83ebf7886a6201b9e3463c94ec7a1a8ce8576ada..c92c6a143b3d6caa2b2d49938a29ae5a391d3e6c 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.15"
+\version "2.19.0"
 
 \header{
   texidoc= "Test optional music function arguments.
@@ -10,23 +10,18 @@ the rest is skipped."
 
 \layout { ragged-right = ##t }
 
-% Get following pitch into Scheme
-pitch = #(define-scheme-function (parser location p) (ly:pitch?) p)
-% The same with a duration
-dur = #(define-scheme-function (parser location p) (ly:duration?) p)
-
 % Just like \relative, but defaulting to f as reference, making the
 % first note of the music the same as if written as absolute pitch
 ablative =
 #(define-music-function (parser location ref music)
-  ((ly:pitch? #{ \pitch f #}) ly:music?)
+  ((ly:pitch? #{ f #}) ly:music?)
   #{ \relative $ref $music #})
 
 % Let's take a duration and four pitches, defaulting to 2 c' d' e'
 zap = 
 #(define-music-function (parser location dur a b c d)
-  ((ly:duration? #{ \dur 2 #}) (ly:pitch? #{ \pitch c' #})
-   (ly:pitch? #{ \pitch d' #}) (ly:pitch? #{ \pitch e' #})
+  ((ly:duration? #{ 2 #}) (ly:pitch? #{ c' #})
+   (ly:pitch? #{ d' #}) (ly:pitch? #{ e' #})
    ly:music?) #{ $a $dur $b $c ^\markup{!} $d  #})
 
 \new Voice { \relative c' e' \relative c' { e' } \ablative c' e' \ablative { e' }
diff --git a/input/regression/rhythmic-sequence.ly b/input/regression/rhythmic-sequence.ly
new file mode 100644 (file)
index 0000000..df647ce
--- /dev/null
@@ -0,0 +1,11 @@
+\version "2.19.0"
+
+\header {
+  texidoc = "Durations without pitches are placed into note events
+without pitch information.  Those are directly useful in
+@code{RhythmicStaff}."
+}
+
+\layout { ragged-right = ##t }
+
+\new RhythmicStaff { 4 4. r | 4 \tuplet 3/2 { 2 4 } 4 }
diff --git a/input/regression/score-lines.ly b/input/regression/score-lines.ly
new file mode 100644 (file)
index 0000000..edb300f
--- /dev/null
@@ -0,0 +1,40 @@
+\version "2.19.0"
+
+\header {
+  texidoc = "The @code{\\score-lines} markup returns individual score
+lines as stencils rather than a single stencil.  Calling a function 
+like @code{\\rotate} on @code{\\score-lines} rotates the lines
+individually, as contrasted with rotating an entire @code{\\score}
+markup."
+}
+
+\markup \fill-line {
+  \null
+  \column \rotate #-15 {
+    \score-lines
+    {
+      \new Staff \with { instrumentName = \markup \typewriter
+                        "\\score-lines" }
+      \repeat unfold 16 c'4
+      \layout {
+       short-indent = 0
+       indent = 0
+       line-width = 4\cm
+      }
+    }
+  }
+  \column \rotate #-15 {
+    \score
+    {
+      \new Staff \with { instrumentName = \markup \typewriter
+                        "\\score" }
+      \repeat unfold 16 c'4
+      \layout {
+       short-indent = 0
+       indent = 0
+       line-width = 4\cm
+      }
+    }
+  }
+  \null
+}
index 1425ed680710cf7be2f5b5daff30d5b0e368b24b..69d68c0fa9e0d94cce7b408f1c7d11777c2f4946 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.20"
+\version "2.19.0"
 
 \header
 {
@@ -10,7 +10,8 @@ either automatic or manual beaming.
 
 guitarSolo = {
   \time 3/4
-  \set Timing.beamExceptions = #'((end . (((1 . 8) . (4 2)))))
+  \set Timing.beamExceptions =
+    \beamExceptions { 8[ 8 8 8] 8[ 8] }
   <<
     {bes'2( aes'8-. r)} \\
     {r8 cis(-\tag #'beam [ b f'-\tag #'beam ]) <d f'>-. r}
index ce05dfff722f6ed9d7847714415000babf2538cb..3d2906ee85c5e4394455337ebd10b41ce8707bf4 100644 (file)
@@ -163,15 +163,17 @@ Accidental_interface::get_stencil (Grob *me)
   SCM alist = me->get_property ("glyph-name-alist");
   SCM alt = me->get_property ("alteration");
   SCM glyph_name = ly_assoc_get (alt, alist, SCM_BOOL_F);
+  Stencil mol;
 
   if (!scm_is_string (glyph_name))
     {
       me->warning (_f ("Could not find glyph-name for alteration %s",
                        ly_scm_write_string (alt).c_str ()));
-      return SCM_EOL;
+      mol = fm->find_by_name ("noteheads.s1cross");
     }
+  else
+    mol = fm->find_by_name (ly_scm2string (glyph_name));
 
-  Stencil mol (fm->find_by_name (ly_scm2string (glyph_name)));
   if (to_boolean (me->get_property ("restore-first")))
     {
       /*
index 8a2a8d9b819a4469f2b60c73f75f1d0899963d91..266016d5734b4e2ce764129547c140ac6d45e5f4 100644 (file)
@@ -61,85 +61,73 @@ Align_interface::align_to_ideal_distances (SCM smob)
   return SCM_BOOL_T;
 }
 
-/* for each grob, find its upper and lower skylines. If the grob has
-   an empty extent, delete it from the list instead. If the extent is
-   non-empty but there is no skyline available (or pure is true), just
+/* Return upper and lower skylines for VerticalAxisGroup g. If the extent
+   is non-empty but there is no skyline available (or pure is true), just
    create a flat skyline from the bounding box */
 // TODO(jneem): the pure and non-pure parts seem to share very little
 // code. Split them into 2 functions, perhaps?
-static void
-get_skylines (Grob *me,
-              vector<Grob *> *const elements,
+static Skyline_pair
+get_skylines (Grob *g,
               Axis a,
-              bool pure, int start, int end,
-              vector<Skyline_pair> *const ret)
+              Grob *other_common,
+              bool pure, int start, int end)
 {
-  Grob *other_common = common_refpoint_of_array (*elements, me, other_axis (a));
+  Skyline_pair skylines;
 
-  for (vsize i = elements->size (); i--;)
+  if (!pure)
     {
-      Grob *g = (*elements)[i];
-      Skyline_pair skylines;
-
-      if (!pure)
-        {
-          Skyline_pair *skys = Skyline_pair::unsmob (g->get_property (a == Y_AXIS
-                                                                      ? "vertical-skylines"
-                                                                      : "horizontal-skylines"));
-          if (skys)
-            skylines = *skys;
-
-          /* This skyline was calculated relative to the grob g. In order to compare it to
-             skylines belonging to other grobs, we need to shift it so that it is relative
-             to the common reference. */
-          Real offset = g->relative_coordinate (other_common, other_axis (a));
-          skylines.shift (offset);
-        }
-      else
+      Skyline_pair *skys = Skyline_pair::unsmob (g->get_property (a == Y_AXIS
+                                                                  ? "vertical-skylines"
+                                                                  : "horizontal-skylines"));
+      if (skys)
+        skylines = *skys;
+
+      /* This skyline was calculated relative to the grob g. In order to compare it to
+         skylines belonging to other grobs, we need to shift it so that it is relative
+         to the common reference. */
+      Real offset = g->relative_coordinate (other_common, other_axis (a));
+      skylines.shift (offset);
+    }
+  else if (Hara_kiri_group_spanner::request_suicide (g, start, end))
+    return skylines;
+  else
+    {
+      assert (a == Y_AXIS);
+      Interval extent = g->pure_height (g, start, end);
+
+      // This is a hack to get better accuracy on the pure-height of VerticalAlignment.
+      // It's quite common for a treble clef to be the highest element of one system
+      // and for a low note (or lyrics) to be the lowest note on another. The two will
+      // never collide, but the pure-height stuff only works with bounding boxes, so it
+      // doesn't know that. The result is a significant over-estimation of the pure-height,
+      // especially on systems with many staves. To correct for this, we build a skyline
+      // in two parts: the part we did above contains most of the grobs (note-heads, etc.)
+      // while the bit we're about to do only contains the breakable grobs at the beginning
+      // of the system. This way, the tall treble clefs are only compared with the treble
+      // clefs of the other staff and they will be ignored if the staff above is, for example,
+      // lyrics.
+      if (Axis_group_interface::has_interface (g))
         {
-          assert (a == Y_AXIS);
-          Interval extent = g->pure_height (g, start, end);
-
-          // This is a hack to get better accuracy on the pure-height of VerticalAlignment.
-          // It's quite common for a treble clef to be the highest element of one system
-          // and for a low note (or lyrics) to be the lowest note on another. The two will
-          // never collide, but the pure-height stuff only works with bounding boxes, so it
-          // doesn't know that. The result is a significant over-estimation of the pure-height,
-          // especially on systems with many staves. To correct for this, we build a skyline
-          // in two parts: the part we did above contains most of the grobs (note-heads, etc.)
-          // while the bit we're about to do only contains the breakable grobs at the beginning
-          // of the system. This way, the tall treble clefs are only compared with the treble
-          // clefs of the other staff and they will be ignored if the staff above is, for example,
-          // lyrics.
-          if (Axis_group_interface::has_interface (g)
-              && !Hara_kiri_group_spanner::request_suicide (g, start, end))
-            {
-              extent = Axis_group_interface::rest_of_line_pure_height (g, start, end);
-              Interval begin_of_line_extent = Axis_group_interface::begin_of_line_pure_height (g, start);
-              if (!begin_of_line_extent.is_empty ())
-                {
-                  Box b;
-                  b[a] = begin_of_line_extent;
-                  b[other_axis (a)] = Interval (-infinity_f, -1);
-                  skylines.insert (b, other_axis (a));
-                }
-            }
-
-          if (!extent.is_empty ())
+          extent = Axis_group_interface::rest_of_line_pure_height (g, start, end);
+          Interval begin_of_line_extent = Axis_group_interface::begin_of_line_pure_height (g, start);
+          if (!begin_of_line_extent.is_empty ())
             {
               Box b;
-              b[a] = extent;
-              b[other_axis (a)] = Interval (0, infinity_f);
+              b[a] = begin_of_line_extent;
+              b[other_axis (a)] = Interval (-infinity_f, -1);
               skylines.insert (b, other_axis (a));
             }
         }
 
-      if (skylines.is_empty ())
-        elements->erase (elements->begin () + i);
-      else
-        ret->push_back (skylines);
+      if (!extent.is_empty ())
+        {
+          Box b;
+          b[a] = extent;
+          b[other_axis (a)] = Interval (0, infinity_f);
+          skylines.insert (b, other_axis (a));
+        }
     }
-  reverse (*ret);
+  return skylines;
 }
 
 vector<Real>
@@ -177,7 +165,7 @@ Align_interface::get_minimum_translations_without_min_dist (Grob *me,
 //   else centered dynamics will break when there is a fixed alignment).
 vector<Real>
 Align_interface::internal_get_minimum_translations (Grob *me,
-                                                    vector<Grob *> const &all_grobs,
+                                                    vector<Grob *> const &elems,
                                                     Axis a,
                                                     bool include_fixed_spacing,
                                                     bool pure, int start, int end)
@@ -204,15 +192,14 @@ Align_interface::internal_get_minimum_translations (Grob *me,
 
   Direction stacking_dir = robust_scm2dir (me->get_property ("stacking-dir"),
                                            DOWN);
-  vector<Grob *> elems (all_grobs); // writable copy
-  vector<Skyline_pair> skylines;
 
-  get_skylines (me, &elems, a, pure, start, end, &skylines);
+  Grob *other_common = common_refpoint_of_array (elems, me, other_axis (a));
 
   Real where = 0;
   Real default_padding = robust_scm2double (me->get_property ("padding"), 0.0);
   vector<Real> translates;
   Skyline down_skyline (stacking_dir);
+  Grob *last_nonempty_element = 0;
   Real last_spaceable_element_pos = 0;
   Grob *last_spaceable_element = 0;
   Skyline last_spaceable_skyline (stacking_dir);
@@ -222,14 +209,26 @@ Align_interface::internal_get_minimum_translations (Grob *me,
       Real dy = 0;
       Real padding = default_padding;
 
-      if (j == 0)
-        dy = skylines[j][-stacking_dir].max_height () + padding;
+      Skyline_pair skyline = get_skylines (elems[j], a, other_common, pure, start, end);
+
+      if (skyline.is_empty ())
+        {
+          translates.push_back (where);
+          continue;
+        }
+
+      if (!last_nonempty_element)
+        {
+          dy = skyline[-stacking_dir].max_height () + padding;
+          for (vsize k = j; k-- > 0;)
+            translates[k] = stacking_dir * dy;
+        }
       else
         {
-          SCM spec = Page_layout_problem::get_spacing_spec (elems[j - 1], elems[j], pure, start, end);
+          SCM spec = Page_layout_problem::get_spacing_spec (last_nonempty_element, elems[j], pure, start, end);
           Page_layout_problem::read_spacing_spec (spec, &padding, ly_symbol2scm ("padding"));
 
-          dy = down_skyline.distance (skylines[j][-stacking_dir]) + padding;
+          dy = down_skyline.distance (skyline[-stacking_dir]) + padding;
 
           Real spec_distance = 0;
           if (Page_layout_problem::read_spacing_spec (spec, &spec_distance, ly_symbol2scm ("minimum-distance")))
@@ -249,7 +248,7 @@ Align_interface::internal_get_minimum_translations (Grob *me,
               Page_layout_problem::read_spacing_spec (spec,
                                                       &spaceable_padding,
                                                       ly_symbol2scm ("padding"));
-              dy = max (dy, (last_spaceable_skyline.distance (skylines[j][-stacking_dir])
+              dy = max (dy, (last_spaceable_skyline.distance (skyline[-stacking_dir])
                              + stacking_dir * (last_spaceable_element_pos - where) + spaceable_padding));
 
               Real spaceable_min_distance = 0;
@@ -263,12 +262,9 @@ Align_interface::internal_get_minimum_translations (Grob *me,
             }
         }
 
-      if (isinf (dy)) /* if the skyline is empty, maybe max_height is infinity_f */
-        dy = 0.0;
-
       dy = max (0.0, dy);
       down_skyline.raise (-stacking_dir * dy);
-      down_skyline.merge (skylines[j][stacking_dir]);
+      down_skyline.merge (skyline[stacking_dir]);
       where += stacking_dir * dy;
       translates.push_back (where);
 
@@ -279,32 +275,18 @@ Align_interface::internal_get_minimum_translations (Grob *me,
           last_spaceable_element_pos = where;
           last_spaceable_skyline = down_skyline;
         }
-    }
-
-  // So far, we've computed the translates for all the non-empty elements.
-  // Here, we set the translates for the empty elements: an empty element
-  // gets the same translation as the last non-empty element before it.
-  vector<Real> all_translates;
-  if (!translates.empty ())
-    {
-      Real w = translates[0];
-      for (vsize i = 0, j = 0; j < all_grobs.size (); j++)
-        {
-          if (i < elems.size () && all_grobs[j] == elems[i])
-            w = translates[i++];
-          all_translates.push_back (w);
-        }
+      last_nonempty_element = elems[j];
     }
 
   if (pure)
     {
       SCM mta = me->get_property ("minimum-translations-alist");
       mta = scm_cons (scm_cons (scm_cons (scm_from_int (start), scm_from_int (end)),
-                                ly_floatvector2scm (all_translates)),
+                                ly_floatvector2scm (translates)),
                       mta);
       me->set_property ("minimum-translations-alist", mta);
     }
-  return all_translates;
+  return translates;
 }
 
 void
index 018d9cd22df116282bbaff4ef63d62355ebeb195..4de173da061b38b32d4c7652291ad3c290cd5514 100644 (file)
@@ -163,7 +163,7 @@ Arpeggio::print (SCM smob)
   if (dir)
     {
       Font_metric *fm = Font_interface::get_default_font (me);
-      arrow = fm->find_by_name ("scripts.arpeggio.arrow." + to_string (dir));
+      arrow = fm->find_by_name ("scripts.arpeggio.arrow." + ::to_string (dir));
       heads[dir] -= dir * arrow.extent (Y_AXIS).length ();
     }
 
index a41357b28f296239350e38e770af2c01b7df7d21..7934c34c4a1e86e3eea155c94298c36870c1aa68 100644 (file)
@@ -44,11 +44,13 @@ Audio_item::Audio_item ()
 {
 }
 
-Audio_note::Audio_note (Pitch p, Moment m, bool tie_event, Pitch transposing)
+Audio_note::Audio_note (Pitch p, Moment m, bool tie_event, Pitch transposing,
+                        int velocity)
   : pitch_ (p),
     length_mom_ (m),
     transposing_ (transposing),
     dynamic_ (0),
+    extra_velocity_ (velocity),
     tied_ (0),
     tie_event_ (tie_event)
 {
index 52a7d6c0bd4d0a64db0fb6610a889c313f9c0781..bddca70abbd3faa3175969eaa769363e067c6ec5 100644 (file)
@@ -188,25 +188,24 @@ Completion_heads_engraver::process_music ()
         note that note_dur may be strictly less than left_to_do_
         (say, if left_to_do_ == 5/8)
       */
-      if (factor_.denominator () == 1 && factor_ > Rational (1, 1))
-        note_dur = Duration (left_to_do_, false);
-      else
-        note_dur = Duration (left_to_do_ / factor_, false).compressed (factor_);
+      note_dur = Duration (left_to_do_ / factor_, false).compressed (factor_);
     }
   else
     {
       orig = unsmob_duration (note_events_[0]->get_property ("duration"));
       note_dur = *orig;
-      factor_ = note_dur.factor ();
+      SCM factor = get_property ("completionFactor");
+      if (ly_is_procedure (factor))
+        factor = scm_call_2 (factor,
+                             context ()->self_scm (),
+                             note_dur.smobbed_copy ());
+      factor_ = robust_scm2rational (factor, note_dur.factor ());
       left_to_do_ = orig->get_length ();
     }
   Moment nb = next_moment (note_dur.get_length ());
   if (nb.main_part_ && nb < note_dur.get_length ())
     {
-      if (factor_.denominator () == 1 && factor_.numerator () > 1)
-        note_dur = Duration (nb.main_part_, false);
-      else
-        note_dur = Duration (nb.main_part_ / factor_, false).compressed (factor_);
+      note_dur = Duration (nb.main_part_ / factor_, false).compressed (factor_);
     }
 
   do_nothing_until_ = now.main_part_ + note_dur.get_length ();
@@ -314,6 +313,7 @@ ADD_TRANSLATOR (Completion_heads_engraver,
                 "TieColumn ",
 
                 /* read */
+                "completionFactor "
                 "completionUnit "
                 "measureLength "
                 "measurePosition "
index 61255226eac4eb53b385f1eadbde873507199bdd..aeb6673f3725eb9f5522ae460718bc581a181e94 100644 (file)
@@ -184,25 +184,24 @@ Completion_rest_engraver::process_music ()
         note that rest_dur may be strictly less than left_to_do_
         (say, if left_to_do_ == 5/8)
       */
-      if (factor_.denominator () == 1 && factor_ > Rational (1, 1))
-        rest_dur = Duration (left_to_do_, false);
-      else
-        rest_dur = Duration (left_to_do_ / factor_, false).compressed (factor_);
+      rest_dur = Duration (left_to_do_ / factor_, false).compressed (factor_);
     }
   else
     {
       orig = unsmob_duration (rest_events_[0]->get_property ("duration"));
       rest_dur = *orig;
-      factor_ = rest_dur.factor ();
+      SCM factor = get_property ("completionFactor");
+      if (ly_is_procedure (factor))
+        factor = scm_call_2 (factor,
+                             context ()->self_scm (),
+                             rest_dur.smobbed_copy ());
+      factor_ = robust_scm2rational (factor, rest_dur.factor());
       left_to_do_ = orig->get_length ();
     }
   Moment nb = next_moment (rest_dur.get_length ());
   if (nb.main_part_ && nb < rest_dur.get_length ())
     {
-      if (factor_.denominator () == 1 && factor_.numerator () > 1)
-        rest_dur = Duration (nb.main_part_, false);
-      else
-        rest_dur = Duration (nb.main_part_ / factor_, false).compressed (factor_);
+      rest_dur = Duration (nb.main_part_ / factor_, false).compressed (factor_);
     }
 
   do_nothing_until_ = now.main_part_ + rest_dur.get_length ();
@@ -268,6 +267,7 @@ ADD_TRANSLATOR (Completion_rest_engraver,
                 "Rest ",
 
                 /* read */
+                "completionFactor "
                 "completionUnit "
                 "middleCPosition "
                 "measurePosition "
index 6cba432639deb7f8fd899a53a577987253787762..9b4a3831b0199b46d98ed4e0436175b88d38fd10 100644 (file)
@@ -59,7 +59,7 @@ Dot_column::calc_positioning_done (SCM smob)
   vector<Grob *> dots
     = extract_grob_array (me, "dots");
 
-  vector<Grob *> main_heads;
+  vector<Grob *> parent_stems;
   Real ss = 0;
 
   Grob *commonx = me;
@@ -73,7 +73,7 @@ Dot_column::calc_positioning_done (SCM smob)
           commonx = stem->common_refpoint (commonx, X_AXIS);
 
           if (Stem::first_head (stem) == n)
-            main_heads.push_back (n);
+            parent_stems.push_back (stem);
         }
     }
 
@@ -83,8 +83,8 @@ Dot_column::calc_positioning_done (SCM smob)
   extract_grob_set (me, "side-support-elements", support);
 
   Interval base_x;
-  for (vsize i = 0; i < main_heads.size (); i++)
-    base_x.unite (main_heads[i]->extent (commonx, X_AXIS));
+  for (vsize i = 0; i < parent_stems.size (); i++)
+    base_x.unite (Stem::first_head (parent_stems[i])->extent (commonx, X_AXIS));
 
   for (vsize i = 0; i < support.size (); i++)
     {
@@ -152,6 +152,36 @@ Dot_column::calc_positioning_done (SCM smob)
     we instead must use their pure Y positions.
   */
   vector_sort (dots, pure_position_less);
+
+  SCM chord_dots_limit = me->get_property ("chord-dots-limit");
+  if (scm_is_number (chord_dots_limit))
+    {
+      // Sort dots by stem, then check for dots above the limit for each stem
+      vector <vector <Grob *> > dots_each_stem (parent_stems.size ());
+      for (vsize i = 0; i < dots.size (); i++)
+        if (Grob *stem = unsmob_grob (dots[i]->get_parent (Y_AXIS)
+                                      -> get_object ("stem")))
+          for (vsize j = 0; j < parent_stems.size (); j++)
+            if (stem == parent_stems[j])
+              {
+                dots_each_stem[j].push_back (dots[i]);
+                break;
+              }
+      for (vsize j = 0; j < parent_stems.size (); j++)
+        {
+          Interval chord = Stem::head_positions (parent_stems[j]);
+          int total_room = ((int) chord.length () + 2
+                            + scm_to_int (chord_dots_limit)) / 2;
+          int total_dots = dots_each_stem[j].size ();
+          // remove excessive dots from the ends of the stem
+          for (int first_dot = 0; total_dots > total_room; total_dots--)
+            if (0 == (total_dots - total_room) % 2)
+              dots_each_stem[j][first_dot++]->suicide ();
+            else
+              dots_each_stem[j][first_dot + total_dots - 1]->suicide ();
+        }
+    }
+
   for (vsize i = dots.size (); i--;)
     {
       if (!dots[i]->is_live ())
@@ -236,6 +266,7 @@ ADD_INTERFACE (Dot_column,
                " dots so they do not clash with staff lines.",
 
                /* properties */
+               "chord-dots-limit "
                "dots "
                "positioning-done "
                "direction "
index 94c2d55ea319b0edc6c3e6730a706f323095ffc4..09ab3f7cf4417130ed165fca35edf3e1ad5d2dc9 100644 (file)
@@ -62,9 +62,9 @@ Drum_note_performer::process_music ()
         {
           SCM articulations = n->get_property ("articulations");
           Stream_event *tie_event = 0;
-          for (SCM s = articulations;
-               !tie_event && scm_is_pair (s);
-               s = scm_cdr (s))
+          Moment len = get_event_length (n, now_mom ());
+          int velocity = 0;
+          for (SCM s = articulations; scm_is_pair (s); s = scm_cdr (s))
             {
               Stream_event *ev = unsmob_stream_event (scm_car (s));
               if (!ev)
@@ -72,12 +72,16 @@ Drum_note_performer::process_music ()
 
               if (ev->in_event_class ("tie-event"))
                 tie_event = ev;
+              SCM f = ev->get_property ("midi-length");
+              if (ly_is_procedure (f))
+                len = robust_scm2moment (scm_call_2 (f, len.smobbed_copy (),
+                                                     context ()->self_scm ()),
+                                         len);
+              velocity += robust_scm2int (ev->get_property ("midi-extra-velocity"), 0);
             }
 
-          Moment len = get_event_length (n, now_mom ());
-
           Audio_note *p = new Audio_note (*pit, len,
-                                          tie_event, Pitch (0, 0, 0));
+                                          tie_event, Pitch (0, 0, 0), velocity);
           Audio_element_info info (p, n);
           announce_element (info);
         }
index 31ddf349c92cf1098836fa98b11252ea19cf2b00..f4fcce8e0e96a8db468846208a8ab193ec7952b8 100644 (file)
@@ -105,7 +105,7 @@ Flag::glyph_name (SCM smob)
 
   char dir = (d == UP) ? 'u' : 'd';
   string font_char = flag_style
-                     + to_string (dir) + staffline_offs + to_string (log);
+                     + ::to_string (dir) + staffline_offs + ::to_string (log);
   return ly_string2scm ("flags." + font_char);
 }
 
@@ -143,11 +143,11 @@ Flag::print (SCM smob)
       string stroke_style = ly_scm2string (stroke_style_scm);
       if (!stroke_style.empty ())
         {
-          string font_char = flag_style + to_string (dir) + stroke_style;
+          string font_char = flag_style + ::to_string (dir) + stroke_style;
           Stencil stroke = fm->find_by_name ("flags." + font_char);
           if (stroke.is_empty ())
             {
-              font_char = to_string (dir) + stroke_style;
+              font_char = ::to_string (dir) + stroke_style;
               stroke = fm->find_by_name ("flags." + font_char);
             }
           if (stroke.is_empty ())
index f9773e5ec5a4878b12f66f1535970a5696e6ff8a..32ff49124dff37919c6e21b5b8778874338c188b 100644 (file)
@@ -197,8 +197,17 @@ SCM
 Grob::internal_get_pure_property (SCM sym, int start, int end) const
 {
   SCM val = internal_get_property_data (sym);
-  if (ly_is_procedure (val) || is_unpure_pure_container (val))
+  if (ly_is_procedure (val))
     return call_pure_function (val, scm_list_1 (self_scm ()), start, end);
+
+  if (is_unpure_pure_container (val)) {
+    // Do cache, if the function ignores 'start' and 'end'
+    if (is_unchanging_unpure_pure_container (val))
+      return internal_get_property (sym);
+    else
+      return call_pure_function (val, scm_list_1 (self_scm ()), start, end);
+  }
+
   if (is_simple_closure (val))
     return evaluate_with_simple_closure (self_scm (),
                                          simple_closure_expression (val),
index 40e165dd6d0ffe35c9cfff0051e19133129037ed..1d9007441b108f2c285c7597d95e01238f191ae5 100644 (file)
@@ -236,7 +236,8 @@ Hairpin::print (SCM smob)
                 }
               else
                 {
-                  if (Note_column::has_interface (b)
+                  if (d == RIGHT // end at the left edge of a rest
+                      && Note_column::has_interface (b)
                       && Note_column::has_rests (b))
                     x_points[d] = e[-d];
                   else
index 43ed2e05a91e6fd8ccb80b8ff351354be927fb02..9ded5301a1cc5d443b173848d8d99068a8effab7 100644 (file)
@@ -82,7 +82,7 @@ public:
 class Audio_note : public Audio_item
 {
 public:
-  Audio_note (Pitch p, Moment m, bool tie_event, Pitch transposition);
+  Audio_note (Pitch p, Moment m, bool tie_event, Pitch transposition, int velocity);
 
   // with tieWaitForNote, there might be a skip between the tied notes!
   void tie_to (Audio_note *, Moment skip = 0);
@@ -93,6 +93,7 @@ public:
   Moment length_mom_;
   Pitch transposing_;
   Audio_dynamic *dynamic_;
+  int extra_velocity_;
 
   Audio_note *tied_;
   bool tie_event_;
index 4bc4cbe887403eb685cecf84442c2f741ad0f7f7..9659abbd198634a29efa25be19e9c8ac51ba858c 100644 (file)
@@ -49,7 +49,6 @@ private:
   Keyword_table *keytable_;
   SCM scopes_;
   SCM start_module_;
-  int hidden_state_;
   Input override_input_;
   SCM eval_scm (SCM, char extra_token = 0);
 public:
@@ -94,7 +93,9 @@ public:
   SCM keyword_list () const;
   SCM lookup_identifier (const string &s);
   SCM lookup_identifier_symbol (SCM s);
-  void push_extra_token (int token_type, SCM scm = SCM_UNSPECIFIED);
+  void push_extra_token (Input const &where,
+                         int token_type, SCM scm = SCM_UNSPECIFIED);
+  int pop_extra_token ();
   void push_chord_state (SCM alist);
   void push_figuredbass_state ();
   void push_lyric_state ();
index 75b1ae8e4623cd75c45917e968a5a24f472cae30..7db1ba417c5c78836a8d0614e9881a010d064ec1 100644 (file)
@@ -40,6 +40,8 @@ struct Slur_score_parameters
   Real free_head_distance_;
   Real extra_encompass_collision_distance_;
   Real extra_encompass_free_distance_;
+  Real gap_to_staffline_inside_;
+  Real gap_to_staffline_outside_;
   Real absolute_closeness_measure_;
   Real edge_slope_exponent_;
   Real close_to_edge_length_;
index e5ff38d6112c73750aab1d89e0baa8d1cbff4303..2fc069b9023c06d9a6f7c1a3e5214ae0d45d184a 100644 (file)
@@ -100,6 +100,7 @@ struct Slur_score_state
   Drul_array<Offset> base_attachments_;
   vector<Slur_configuration *> configurations_;
   Real staff_space_;
+  Real line_thickness_;
   Real thickness_;
 
   Slur_score_state ();
index ccf0971844aa7721662321e96a883b2e676d69e3..e4347b4d0a293045ad18301517a1459ea49b7c77 100644 (file)
@@ -23,6 +23,7 @@
 #include "lily-guile.hh"
 
 bool is_unpure_pure_container (SCM s);
+bool is_unchanging_unpure_pure_container (SCM s);
 SCM unpure_pure_container_unpure_part (SCM smob);
 SCM unpure_pure_container_pure_part (SCM smob);
 SCM ly_make_unpure_pure_container (SCM, SCM);
index a091ef9855c72111c069d77d4931599bc3df9e83..2b29c828bac6f18d80b151445d014b83578dc51f 100644 (file)
@@ -142,7 +142,7 @@ string
 Input::line_number_string () const
 {
   if (source_file_)
-    return to_string (source_file_->get_line (start_));
+    return ::to_string (source_file_->get_line (start_));
   return "?";
 }
 
index 285de24267d372d2ca7498a9c5bcf96f0006d003..51a33fbb4b2a57b446ef954c4af9c1b962f27003 100644 (file)
@@ -123,7 +123,6 @@ SCM (* scm_parse_error_handler) (void *);
 %option never-interactive 
 %option warn
 
-%x extratoken
 %x chords
 %x figures
 %x incl
@@ -186,36 +185,6 @@ BOM_UTF8   \357\273\277
        // swallow and ignore carriage returns
 }
 
-<extratoken>{ANY_CHAR} {
-  /* Generate a token without swallowing anything */
-
-  /* First unswallow the eaten character */
-  add_lexed_char (-YYLeng ());
-  yyless (0);
-
-  /* produce requested token */
-  int type = scm_to_int (scm_caar (extra_tokens_));
-  yylval = scm_cdar (extra_tokens_);
-  extra_tokens_ = scm_cdr (extra_tokens_);
-  if (scm_is_null (extra_tokens_))
-    yy_pop_state ();
-
-  return type;
-}
-
-<extratoken><<EOF>>    {
-  /* Generate a token without swallowing anything */
-
-  /* produce requested token */
-  int type = scm_to_int (scm_caar (extra_tokens_));
-  yylval = scm_cdar (extra_tokens_);
-  extra_tokens_ = scm_cdr (extra_tokens_);
-  if (scm_is_null (extra_tokens_))
-    yy_pop_state ();
-
-  return type;
-}
-
    /* Use the trailing context feature. Otherwise, the BOM will not be
       found if the file starts with an identifier definition. */
 <INITIAL,chords,lyrics,figures,notes>{BOM_UTF8}/.* {
@@ -673,6 +642,10 @@ BOM_UTF8   \357\273\277
                 yylval = SCM_UNSPECIFIED;
                return SCORE;
        }
+       \\score-lines {
+               yylval = SCM_UNSPECIFIED;
+               return SCORELINES;
+       }
        \\\"    {
                start_command_quote ();
        }
@@ -713,17 +686,17 @@ BOM_UTF8  \357\273\277
                // value (for token type MARKUP_FUNCTION or
                // MARKUP_LIST_FUNCTION).
 
-               push_extra_token(EXPECT_NO_MORE_ARGS);
+               push_extra_token (here_input (), EXPECT_NO_MORE_ARGS);
                s = scm_cdr(s);
                for (; scm_is_pair(s); s = scm_cdr(s)) {
                  SCM predicate = scm_car(s);
 
                  if (predicate == ly_lily_module_constant ("markup-list?"))
-                   push_extra_token(EXPECT_MARKUP_LIST);
+                   push_extra_token (here_input (), EXPECT_MARKUP_LIST);
                  else if (predicate == ly_lily_module_constant ("markup?"))
-                   push_extra_token(EXPECT_MARKUP);
+                   push_extra_token (here_input (), EXPECT_MARKUP);
                  else
-                   push_extra_token(EXPECT_SCM, predicate);
+                   push_extra_token (here_input (), EXPECT_SCM, predicate);
                }
                return token_type;
        }
@@ -842,15 +815,25 @@ BOM_UTF8  \357\273\277
 /* Make the lexer generate a token of the given type as the next token. 
  TODO: make it possible to define a value for the token as well */
 void
-Lily_lexer::push_extra_token (int token_type, SCM scm)
+Lily_lexer::push_extra_token (Input const &where, int token_type, SCM scm)
+{
+       extra_tokens_ = scm_cons (scm_cons2 (make_input (where),
+                                            scm_from_int (token_type),
+                                            scm), extra_tokens_);
+}
+
+int
+Lily_lexer::pop_extra_token ()
 {
        if (scm_is_null (extra_tokens_))
-       {
-               if (YY_START != extratoken)
-                       hidden_state_ = YY_START;
-               yy_push_state (extratoken);
-       }
-       extra_tokens_ = scm_acons (scm_from_int (token_type), scm, extra_tokens_);
+               return -1;
+
+  /* produce requested token */
+       yylloc = *unsmob_input (scm_caar (extra_tokens_));
+       int type = scm_to_int (scm_cadar (extra_tokens_));
+       yylval = scm_cddar (extra_tokens_);
+       extra_tokens_ = scm_cdr (extra_tokens_);
+       return type;
 }
 
 void
@@ -891,32 +874,17 @@ Lily_lexer::push_markup_state ()
 void
 Lily_lexer::push_note_state (SCM alist)
 {
-       bool extra = (YYSTATE == extratoken);
-
        SCM p = scm_assq (alist, pitchname_tab_stack_);
 
-       if (extra)
-               yy_pop_state ();
-
        if (scm_is_false (p))
                p = scm_cons (alist, alist_to_hashq (alist));
        pitchname_tab_stack_ = scm_cons (p, pitchname_tab_stack_);
        yy_push_state (notes);
-
-       if (extra) {
-               hidden_state_ = YYSTATE;
-               yy_push_state (extratoken);
-       }
 }
 
 void
 Lily_lexer::pop_state ()
 {
-       bool extra = (YYSTATE == extratoken);
-
-       if (extra)
-               yy_pop_state ();
-
        if (YYSTATE == notes || YYSTATE == chords)
                pitchname_tab_stack_ = scm_cdr (pitchname_tab_stack_);
 
@@ -924,10 +892,6 @@ Lily_lexer::pop_state ()
        if (YYSTATE != maininput)
                yy_pop_state ();
 
-       if (extra) {
-               hidden_state_ = YYSTATE;
-               yy_push_state (extratoken);
-       }
 }
 
 int
@@ -954,7 +918,7 @@ Lily_lexer::scan_escaped_word (const string &str)
        SCM sid = lookup_identifier (str);
        if (Music *m = unsmob_music (sid))
        {
-               m->set_spot (override_input (last_input_));
+               m->set_spot (override_input (here_input ()));
        }
 
        if (sid != SCM_UNDEFINED)
@@ -974,7 +938,7 @@ Lily_lexer::scan_shorthand (const string &str)
        SCM sid = lookup_identifier (str);
        if (Music *m = unsmob_music (sid))
        {
-               m->set_spot (override_input (last_input_));
+               m->set_spot (override_input (here_input ()));
        }
 
        if (sid != SCM_UNDEFINED)
@@ -1013,7 +977,7 @@ Lily_lexer::scan_scm_id (SCM sid)
                        funtype = SCM_FUNCTION;
                else programming_error ("Bad syntax function predicate");
 
-               push_extra_token (EXPECT_NO_MORE_ARGS);
+               push_extra_token (here_input (), EXPECT_NO_MORE_ARGS);
                for (s = scm_cdr (s); scm_is_pair (s); s = scm_cdr (s))
                {
                        SCM optional = SCM_UNDEFINED;
@@ -1026,14 +990,14 @@ Lily_lexer::scan_scm_id (SCM sid)
                        }
                        
                        if (ly_is_procedure (cs))
-                               push_extra_token (EXPECT_SCM, cs);
+                               push_extra_token (here_input (), EXPECT_SCM, cs);
                        else
                        {
                                programming_error ("Function parameter without type-checking predicate");
                                continue;
                        }
                        if (!scm_is_eq (optional, SCM_UNDEFINED))
-                               push_extra_token (EXPECT_OPTIONAL, optional);
+                               push_extra_token (here_input (), EXPECT_OPTIONAL, optional);
                }
                return funtype;
        }
@@ -1071,10 +1035,7 @@ Lily_lexer::scan_bare_word (const string &str)
 int
 Lily_lexer::get_state () const
 {
-       if (YY_START == extratoken)
-               return hidden_state_;
-       else
-               return YY_START;
+       return YY_START;
 }
 
 bool
@@ -1140,7 +1101,7 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
                                if (Music *m = unsmob_music (v))
                                {
                                        if (!unsmob_input (m->get_property ("origin")))
-                                               m->set_spot (override_input (last_input_));
+                                               m->set_spot (override_input (here_input ()));
                                }
                                        
                                int token;
@@ -1148,10 +1109,12 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
                                case '$':
                                        token = scan_scm_id (v);
                                        if (!scm_is_eq (yylval, SCM_UNSPECIFIED))
-                                               push_extra_token (token, yylval);
+                                               push_extra_token (here_input (),
+                                                                 token, yylval);
                                        break;
                                case '#':
-                                       push_extra_token (SCM_IDENTIFIER, v);
+                                       push_extra_token (here_input (),
+                                                         SCM_IDENTIFIER, v);
                                        break;
                                }
                        }
@@ -1163,7 +1126,7 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
        if (Music *m = unsmob_music (sval))
        {
                if (!unsmob_input (m->get_property ("origin")))
-                       m->set_spot (override_input (last_input_));
+                       m->set_spot (override_input (here_input ()));
        }
 
        return sval;
index cd7819e9c8d5f6823592e310783025ed15933280..65906beeef4d52cf85ff62652ceed84d8a8c100d 100644 (file)
@@ -167,7 +167,7 @@ Lily_parser::parse_string_expression (const string &ly_code, const string &filen
   SCM mod = lexer_->set_current_scope ();
   SCM parser = lexer_->lookup_identifier_symbol (ly_symbol2scm ("parser"));
   lexer_->set_identifier (ly_symbol2scm ("parser"), self_scm ());
-  lexer_->push_extra_token (EMBEDDED_LILY);
+  lexer_->push_extra_token (Input (), EMBEDDED_LILY);
   SCM result = do_yyparse ();
 
   lexer_->set_identifier (ly_symbol2scm ("parser"), parser);
index 3bffcb841c87f205f7b9fbd6127c42240ba2ede4..4695eef98683831400df09c3a337368ea12266f9 100644 (file)
@@ -168,7 +168,7 @@ internal_brew_primitive (Grob *me)
       duration_log--;
     case MLP_BREVIS:
       duration_log--;
-      suffix = to_string (duration_log) + color
+      suffix = ::to_string (duration_log) + color
                + (duration_log < -1 ? "lig" : "") + "mensural";
       index = prefix + "s";
       out = fm->find_by_name (index + "r" + suffix);
index 54d00ff683d59ce4f1ffc98975c492e91de9c26b..f98e3d05e1ec0049a022fd3400b31d9a252948eb 100644 (file)
@@ -193,8 +193,10 @@ Midi_time_signature::to_string () const
 Midi_note::Midi_note (Audio_note *a)
   : Midi_channel_item (a),
     audio_ (a),
-    dynamic_byte_ (a->dynamic_ && a->dynamic_->volume_ >= 0
-                   ? Byte (a->dynamic_->volume_ * 0x7f) : Byte (0x5a))
+    dynamic_byte_ (min (max (Byte ((a->dynamic_ && a->dynamic_->volume_ >= 0
+                                    ? a->dynamic_->volume_ * 0x7f : 0x5a)
+                                   + a->extra_velocity_),
+                             Byte (0)), Byte (0x7f)))
 {
 }
 
index b97630b0d147ed8ebc05d63c111b8928c3667cad..0ae5265bd370dd92aa93fb25b381fab1ad87f9cf 100644 (file)
@@ -58,7 +58,9 @@ Midi_walker::Midi_walker (Audio_staff *audio_staff, Midi_track *track)
   index_ = 0;
   items_ = audio_staff->audio_items_;
   vector_sort (items_, audio_item_less);
-  last_tick_ = 0;
+  //Pieces that begin with grace notes start at negative times. This
+  //is OK - MIDI output doesn't use absolute ticks, only differences.
+  last_tick_ = items_.empty () ? 0 : items_[0]->audio_column_->ticks ();
   percussion_ = audio_staff->percussion_;
   merge_unisons_ = audio_staff->merge_unisons_;
 }
index eea6a9ca818a58552a5d4cdda7a159754696d186..629986d3463a479d0694bde8bfbb49288bef35f7 100644 (file)
@@ -211,20 +211,6 @@ transpose_mutable (SCM alist, Pitch delta)
       if (Pitch *p = unsmob_pitch (val))
         {
           Pitch transposed = p->transposed (delta);
-          if (transposed.get_alteration ().abs () > Rational (1, 1))
-            {
-              string delta_str;
-              if (delta.get_alteration ().abs () > Rational (1, 1))
-                delta_str = (delta.normalized ().to_string ()
-                             + " " + _ ("(normalized pitch)"));
-              else
-                delta_str = delta.to_string ();
-
-              warning (_f ("Transposing %s by %s makes alteration larger than double",
-                           p->to_string (),
-                           delta_str));
-              transposed = transposed.normalized ();
-            }
 
           if (prop == ly_symbol2scm ("tonic"))
             transposed = Pitch (-1, transposed.get_notename (),
index 4bf8168eb1092c4fe34b147bbfc5d17e318774fa..5d8352e72df32240749dcaa3d0f80dda8d16e6df 100644 (file)
@@ -38,7 +38,7 @@ internal_print (Grob *me, string *font_char)
 {
   string style = robust_symbol2string (me->get_property ("style"), "default");
 
-  string suffix = to_string (min (robust_scm2int (me->get_property ("duration-log"), 2), 2));
+  string suffix = ::to_string (min (robust_scm2int (me->get_property ("duration-log"), 2), 2));
   if (style != "default")
     suffix = robust_scm2string (me->get_property ("glyph-name"), "");
 
index ddf9fe39213e0d74910ce75a268808ad254d424c..81f35d70ac1a8d3c6b140840750620f9309e37ff 100644 (file)
@@ -36,6 +36,7 @@ protected:
   void process_music ();
 
   DECLARE_TRANSLATOR_LISTENER (note);
+  DECLARE_TRANSLATOR_LISTENER (breathing);
 private:
   vector<Stream_event *> note_evs_;
   vector<Audio_note *> notes_;
@@ -65,9 +66,9 @@ Note_performer::process_music ()
         {
           SCM articulations = n->get_property ("articulations");
           Stream_event *tie_event = 0;
-          for (SCM s = articulations;
-               !tie_event && scm_is_pair (s);
-               s = scm_cdr (s))
+          Moment len = get_event_length (n, now_mom ());
+          int velocity = 0;
+          for (SCM s = articulations; scm_is_pair (s); s = scm_cdr (s))
             {
               Stream_event *ev = unsmob_stream_event (scm_car (s));
               if (!ev)
@@ -75,19 +76,23 @@ Note_performer::process_music ()
 
               if (ev->in_event_class ("tie-event"))
                 tie_event = ev;
+              SCM f = ev->get_property ("midi-length");
+              if (ly_is_procedure (f))
+                len = robust_scm2moment (scm_call_2 (f, len.smobbed_copy (),
+                                                     context ()->self_scm ()),
+                                         len);
+              velocity += robust_scm2int (ev->get_property ("midi-extra-velocity"), 0);
             }
 
-          Moment len = get_event_length (n, now_mom ());
-
           Audio_note *p = new Audio_note (*pitp, len,
-                                          tie_event, transposing);
+                                          tie_event, transposing, velocity);
           Audio_element_info info (p, n);
           announce_element (info);
           notes_.push_back (p);
 
           /*
-            Shorten previous note. If it was part of a tie, shorten
-            the first note in the tie.
+            Grace notes shorten the previous non-grace note. If it was
+            part of a tie, shorten the first note in the tie.
            */
           if (now_mom ().grace_part_)
             {
@@ -96,7 +101,11 @@ Note_performer::process_music ()
                   for (vsize i = 0; i < last_notes_.size (); i++)
                     {
                       Audio_note *tie_head = last_notes_[i]->tie_head ();
-                      tie_head->length_mom_ += Moment (0, now_mom ().grace_part_);
+                      Moment start = tie_head->audio_column_->when ();
+                      //Shorten the note if it would overlap. It might
+                      //not if there's a rest in between.
+                      if (start + tie_head->length_mom_ > now_mom ())
+                        tie_head->length_mom_ = now_mom () - start;
                     }
                 }
             }
@@ -124,6 +133,26 @@ Note_performer::listen_note (Stream_event *ev)
   note_evs_.push_back (ev);
 }
 
+IMPLEMENT_TRANSLATOR_LISTENER (Note_performer, breathing)
+void
+Note_performer::listen_breathing (Stream_event *ev)
+{
+  //Shorten previous note if needed
+  SCM f = ev->get_property ("midi-length");
+  if (ly_is_procedure (f))
+    for (vsize i = 0; i < last_notes_.size (); i++)
+      {
+        Audio_note *tie_head = last_notes_[i]->tie_head ();
+        //Give midi-length the available time since the note started,
+        //including rests. It returns how much is left for the note.
+        Moment available = now_mom () - tie_head->audio_column_->when ();
+        Moment len = robust_scm2moment (scm_call_2 (f, available.smobbed_copy (),
+                                                    context ()->self_scm ()), available);
+        if (len < tie_head->length_mom_)
+          tie_head->length_mom_ = len;
+      }
+}
+
 ADD_TRANSLATOR (Note_performer,
                 /* doc */
                 "",
index 3bddcad4ba66815806fa1e691a2c2f229e1fc8f9..3ff29d01bd0d67d2bf8a644483dbbda3ef5d262a 100644 (file)
@@ -75,7 +75,9 @@ Optimal_page_breaking::solve ()
           if (page_count > 1 && best.systems_per_page_[page_count - 2] > 1)
             min_sys_count -= best.systems_per_page_[page_count - 2];
 
-          min_sys_count = max (min_sys_count, (vsize)1);
+          if (min_sys_count > ideal_sys_count  // subtraction wrapped around
+              || min_sys_count <= 0)
+            min_sys_count = 1;
         }
     }
   else
index 9a6f8f40f25c0edbe47f45ecde1780c2babc89b6..7220857d9194e1c7ff4ff5c0c89b91b78b484645 100644 (file)
@@ -195,7 +195,6 @@ compress_lines (const vector<Line_details> &orig)
       else
         {
           ret.push_back (orig[i]);
-          ret.back ().force_ = 0;
         }
     }
   return ret;
@@ -632,7 +631,11 @@ Page_breaking::make_pages (vector<vsize> lines_per_page, SCM systems)
       else
         config = layout.solution (rag);
 
-      last_page_force = layout.force ();
+      if ((ragged () && layout.force () < 0.0)
+          || isinf (layout.force ()))
+        warning (_f ("page %d has been compressed", page_num));
+      else
+        last_page_force = layout.force ();
 
       systems_configs_fncounts = scm_cons (scm_cons (lines, config), systems_configs_fncounts);
       footnote_count += fn_lines;
@@ -1169,9 +1172,8 @@ Page_breaking::min_page_count (vsize configuration, vsize first_page_num)
       cur_page_height -= min_whitespace_at_top_of_page (cached_line_details_[page_starter]);
       cur_page_height -= min_whitespace_at_bottom_of_page (cached_line_details_.back ());
 
-      Real cur_height = cur_rod_height + ((ragged_last () || ragged ()) ? cur_spring_height : 0);
       if (!too_few_lines (line_count - cached_line_details_.back ().compressed_nontitle_lines_count_)
-          && cur_height > cur_page_height
+          && cur_rod_height > cur_page_height
           /* don't increase the page count if the last page had only one system */
           && cur_rod_height > cached_line_details_.back ().full_height ())
         ret++;
@@ -1437,7 +1439,9 @@ Page_breaking::finalize_spacing_result (vsize configuration, Page_spacing_result
       line_penalty += uncompressed_line_details_[i].break_penalty_;
     }
 
-  for (vsize i = 0; i < res.force_.size (); i++)
+  for (vsize i = ragged () ? res.force_.size () - 1 : 0;
+       i < res.force_.size () - ragged_last ();
+       i++)
     {
       Real f = res.force_[i];
 
@@ -1545,9 +1549,11 @@ Page_breaking::space_systems_on_2_pages (vsize configuration, vsize first_page_n
       page1_penalty[i] = line_count_penalty (page1_line_count);
       page1_status[i] = line_count_status (page1_line_count);
 
-      if (ragged2)
+      if (ragged1)
         page2_force[page2_force.size () - 1 - i]
           = (page2.force_ < 0 && i + 1 < page1_force.size ()) ? infinity_f : 0;
+      else if (ragged2 && page2.force_ > 0)
+        page2_force[page2_force.size () - 1 - i] = 0.0;
       else
         page2_force[page2_force.size () - 1 - i] = page2.force_;
       page2_penalty[page2_penalty.size () - 1 - i] = line_count_penalty (page2_line_count);
index 5885a661359b6accd9055228bd11b10cf8f19f88..8b0be3a5f704205e3e1001832be1f09118624596 100644 (file)
@@ -728,12 +728,12 @@ Page_layout_problem::solve_rod_spring_problem (bool ragged, Real fixed_force)
       Real overflow = spacer.configuration_length (spacer.force ())
                       - page_height_;
       if (ragged && overflow < 1e-6)
-        warning (_ ("cannot fit music on page: ragged-spacing was requested, but page was compressed"));
+        warning (_ ("ragged-bottom was specified, but page must be compressed"));
       else
         {
-          warning (_f ("cannot fit music on page: overflow is %f",
+          warning (_f ("compressing over-full page by %.1f staff-spaces",
                        overflow));
-          warning (_ ("compressing music to fit"));
+          force_ = -infinity_f;
           vsize space_count = solution_.size ();
           Real spacing_increment = overflow / (space_count - 2);
           for (vsize i = 2; i < space_count; i++)
index a705827d2274df700b56503bc8b60bb06d58dcb8..a2915febb20197470a4e316436881f103a94e435 100644 (file)
@@ -329,7 +329,7 @@ Page_spacer::calc_subproblem (vsize page, vsize line)
       space.prepend_system (lines_[page_start]);
 
       bool overfull = (space.rod_height_ > paper_height
-                       || (ragged
+                       || (ragged_
                            && (space.rod_height_ + space.spring_len_ > paper_height)));
       // This 'if' statement is a little hard to parse. It won't consider this configuration
       // if it is overfull unless the current configuration is the first one with this start
index 2055214c8262e5c093f01cab74646b4b2f944e34..047ba6a82fee8fedf396505ebf3ea62a992795d7 100644 (file)
@@ -232,7 +232,7 @@ Page_turn_page_breaking::solve ()
   for (vsize i = 0; i < last_break_position (); i++)
     {
       calc_subproblem (i);
-      progress_indication (string ("[") + to_string (i + 1) + "]");
+      progress_indication (string ("[") + ::to_string (i + 1) + "]");
     }
   progress_indication ("\n");
 
index cdbb2e8b004ba5435f800baf781bc081306f3888..cb39f58d1e2d7e48c473e9f4519b5f62ed36e6e8 100644 (file)
@@ -50,7 +50,7 @@ void
 Paper_column_engraver::finalize ()
 {
   if (! (breaks_ % 8))
-    progress_indication ("[" + to_string (breaks_) + "]");
+    progress_indication ("[" + ::to_string (breaks_) + "]");
 
   if (!made_columns_)
     {
@@ -269,7 +269,7 @@ Paper_column_engraver::stop_translation_timestep ()
       breaks_++;
 
       if (! (breaks_ % 8))
-        progress_indication ("[" + to_string (breaks_) + "]");
+        progress_indication ("[" + ::to_string (breaks_) + "]");
     }
 
   context ()->get_score_context ()->unset_property (ly_symbol2scm ("forbidBreak"));
index d586058fa0cbb2c0c58aa9fda9b727423ad704aa..4379ce1a1d1228c8288485eb95c3b18fd1041f9f 100644 (file)
@@ -237,7 +237,7 @@ Paper_column::print (SCM p)
 {
   Paper_column *me = dynamic_cast<Paper_column *> (unsmob_grob (p));
 
-  string r = to_string (Paper_column::get_rank (me));
+  string r = ::to_string (Paper_column::get_rank (me));
 
   Moment *mom = unsmob_moment (me->get_property ("when"));
   string when = mom ? mom->to_string () : "?/?";
index ab09f537b2a8693f413c4121d9dcb82e13916d12..e4355a50fbf36a6b039d7b4fd331f1d4dbd42fe0 100644 (file)
@@ -62,7 +62,7 @@ deleting them.  Let's hope that a stack overflow doesn't trigger a move
 of the parse stack onto the heap. */
 
 %left PREC_BOT
-%nonassoc REPEAT REPEAT_IDENTIFIER
+%nonassoc REPEAT
 %nonassoc ALTERNATIVE
 
 /* The above precedences tackle the shift/reduce problem
@@ -81,7 +81,7 @@ or
 %left ADDLYRICS
 
 %right ':' UNSIGNED REAL E_UNSIGNED EVENT_IDENTIFIER EVENT_FUNCTION '^' '_'
-       HYPHEN EXTENDER DURATION_IDENTIFIER
+       HYPHEN EXTENDER DURATION_IDENTIFIER '!'
 
  /* The above are needed for collecting tremoli and other items (that
     could otherwise be interpreted as belonging to the next function
@@ -146,32 +146,36 @@ Lily_parser::parser_error (Input const *i, Lily_parser *parser, SCM *, const str
        parser->parser_error (*i, s);
 }
 
+// The following are somewhat precarious constructs as they may change
+// the value of the lookahead token.  That implies that the lookahead
+// token must not yet have made an impact on the state stack other
+// than causing the reduction of the current rule, or switching the
+// lookahead token while Bison is mulling it over will cause trouble.
+
 #define MYBACKUP(Token, Value, Location)                               \
-do                                                                     \
-       if (yychar == YYEMPTY)                                          \
-       {                                                               \
+       do {                                                            \
+               if (yychar != YYEMPTY)                                  \
+                       parser->lexer_->push_extra_token                \
+                               (yylloc, yychar, yylval);               \
                if (Token)                                              \
-                       parser->lexer_->push_extra_token (Token, Value); \
-               parser->lexer_->push_extra_token (BACKUP);              \
-       } else {                                                        \
-               parser->parser_error                                    \
-                       (Location, _("Too much lookahead"));            \
-       }                                                               \
-while (0)
+                       parser->lexer_->push_extra_token                \
+                               (Location, Token, Value);               \
+               parser->lexer_->push_extra_token (Location, BACKUP);    \
+               yychar = YYEMPTY;                                       \
+       } while (0)
 
 
 #define MYREPARSE(Location, Pred, Token, Value)                                \
-do                                                                     \
-       if (yychar == YYEMPTY)                                          \
-       {                                                               \
-               parser->lexer_->push_extra_token (Token, Value);        \
-               parser->lexer_->push_extra_token (REPARSE,              \
-                                                 Pred);                \
-       } else {                                                        \
-               parser->parser_error                                    \
-                       (Location, _("Too much lookahead"));            \
-       }                                                               \
-while (0)
+       do {                                                            \
+               if (yychar != YYEMPTY)                                  \
+                       parser->lexer_->push_extra_token                \
+                               (yylloc, yychar, yylval);               \
+               parser->lexer_->push_extra_token                        \
+                       (Location, Token, Value);                       \
+               parser->lexer_->push_extra_token                        \
+                       (Location, REPARSE, Pred);                      \
+               yychar = YYEMPTY;                                       \
+       } while (0)
 
 %}
 
@@ -269,6 +273,7 @@ int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser);
 %token REST "\\rest"
 %token REVERT "\\revert"
 %token SCORE "\\score"
+%token SCORELINES "\\score-lines"
 %token SEQUENTIAL "\\sequential"
 %token SET "\\set"
 %token SIMULTANEOUS "\\simultaneous"
@@ -325,7 +330,6 @@ If we give names, Bison complains.
 %token EMBEDDED_LILY "#{"
 
 %token BOOK_IDENTIFIER
-%token CHORD_BODY_IDENTIFIER
 %token CHORD_MODIFIER
 %token CHORD_REPETITION
 %token CONTEXT_DEF_IDENTIFIER
@@ -347,7 +351,6 @@ If we give names, Bison complains.
 %token NUMBER_IDENTIFIER
 %token OUTPUT_DEF_IDENTIFIER
 %token REAL
-%token REPEAT_IDENTIFIER
 %token RESTNAME
 %token SCM_ARG
 %token SCM_FUNCTION
@@ -405,6 +408,13 @@ toplevel_expression:
                SCM proc = parser->lexer_->lookup_identifier ("toplevel-bookpart-handler");
                scm_call_2 (proc, parser->self_scm (), $1);
        }
+       | BOOK_IDENTIFIER {
+               SCM proc = parser->lexer_->lookup_identifier
+                       (unsmob_book($1)->paper_
+                        ? "toplevel-book-handler"
+                        : "toplevel-bookpart-handler");
+               scm_call_2 (proc, parser->self_scm (), $1);
+       }
        | score_block {
                SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
                scm_call_2 (proc, parser->self_scm (), $1);
@@ -436,6 +446,10 @@ toplevel_expression:
                {
                        SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
                        scm_call_2 (proc, parser->self_scm (), out);
+               } else if (unsmob_score ($1))
+               {
+                       SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
+                       scm_call_2 (proc, parser->self_scm (), $1);
                } else if (!scm_is_eq ($1, SCM_UNSPECIFIED))
                        parser->parser_error (@1, _("bad expression type"));
        }
@@ -473,6 +487,7 @@ embedded_scm_bare_arg:
        {
                $$ = parser->lexer_->eval_scm_token ($1);
        }
+       | FRACTION
        | full_markup_list
        | context_modification
        | score_block
@@ -511,6 +526,18 @@ scm_function_call:
        }
        ;
 
+embedded_lilypond_number:
+       '-' embedded_lilypond_number
+       {
+               $$ = scm_difference ($2, SCM_UNDEFINED);
+       }
+       | bare_number_common
+       | UNSIGNED NUMBER_IDENTIFIER
+       {
+               $$ = scm_product ($1, $2);
+       }
+       ;
+
 embedded_lilypond:
        /* empty */
        {
@@ -520,7 +547,31 @@ embedded_lilypond:
                // contains no source location.
                $$ = MAKE_SYNTAX ("void-music", @$);
        }
-       | identifier_init
+       | identifier_init_nonumber
+       | embedded_lilypond_number
+       | post_event post_events
+       {
+               $$ = scm_reverse_x ($2, SCM_EOL);
+               if (Music *m = unsmob_music ($1))
+               {
+                       if (m->is_mus_type ("post-event-wrapper"))
+                               $$ = scm_append
+                                       (scm_list_2 (m->get_property ("elements"),
+                                                    $$));
+                       else
+                               $$ = scm_cons ($1, $$);
+               }
+               if (scm_is_pair ($$)
+                   && scm_is_null (scm_cdr ($$)))
+                       $$ = scm_car ($$);
+               else
+               {
+                       Music * m = MY_MAKE_MUSIC ("PostEvents", @$);
+                       m->set_property ("elements", $$);
+                       $$ = m->unprotect ();
+               }
+       }
+       | multiplied_duration
        | music_embedded music_embedded music_list {
                $3 = scm_reverse_x ($3, SCM_EOL);
                if (unsmob_music ($2))
@@ -573,16 +624,17 @@ assignment:
                parser->lexer_->set_identifier (path, $4);
                 $$ = SCM_UNSPECIFIED;
        }
+       | assignment_id '.' property_path '=' identifier_init {
+               SCM path = scm_cons (scm_string_to_symbol ($1), $3);
+               parser->lexer_->set_identifier (path, $5);
+                $$ = SCM_UNSPECIFIED;
+       }
        ;
 
 
 identifier_init:
-       score_block
-       | book_block
-       | bookpart_block
-       | output_def
-       | context_def_spec_block
-       | music_assign
+       identifier_init_nonumber
+       | number_expression
        | post_event_nofinger post_events
        {
                $$ = scm_reverse_x ($2, SCM_EOL);
@@ -605,7 +657,16 @@ identifier_init:
                        $$ = m->unprotect ();
                }
        }
-       | number_expression
+       ;
+
+identifier_init_nonumber:
+       score_block
+       | book_block
+       | bookpart_block
+       | output_def
+       | context_def_spec_block
+       | music_assign
+       | pitch_or_music
        | FRACTION
        | string
         | embedded_scm
@@ -746,6 +807,10 @@ book_body:
                {
                        SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
                        scm_call_2 (proc, $1, out);
+               } else if (unsmob_score ($2))
+               {
+                       SCM proc = parser->lexer_->lookup_identifier ("book-score-handler");
+                       scm_call_2 (proc, $1, $2);
                } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
                        parser->parser_error (@2, _("bad expression type"));
        }
@@ -812,6 +877,10 @@ bookpart_body:
                {
                        SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
                        scm_call_2 (proc, $1, out);
+               } else if (unsmob_score ($2))
+               {
+                       SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler");
+                       scm_call_2 (proc, $1, $2);
                } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
                        parser->parser_error (@2, _("bad expression type"));
        }
@@ -831,27 +900,69 @@ bookpart_body:
 
 score_block:
        SCORE '{' score_body '}'        {
+               unsmob_score ($3)->origin ()->set_spot (@$);
                $$ = $3;
        }
        ;
 
+score_headers:
+       /* empty */
+       {
+               $$ = SCM_EOL;
+       }
+       | score_headers
+       {
+               if (!scm_is_pair ($1)
+                   || !ly_is_module (scm_car ($1)))
+                       $1 = scm_cons (ly_make_module (false), $1);
+               parser->lexer_->add_scope (scm_car ($1));
+       } lilypond_header
+       {
+               $$ = $1;
+       }
+       | score_headers output_def
+       {
+                Output_def *od = unsmob_output_def ($2);
+               if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
+               {
+                       parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
+
+               }
+               else
+               {
+                       if (scm_is_pair ($1) && ly_is_module (scm_car ($1)))
+                               scm_set_cdr_x ($1, scm_cons ($2, scm_cdr ($1)));
+                       else
+                               $$ = scm_cons ($2, $1);
+               }
+       }
+       ;
+
+               
+
 score_body:
-       music {
+       score_headers music {
                SCM scorify = ly_lily_module_constant ("scorify-music");
-               $$ = scm_call_2 (scorify, $1, parser->self_scm ());
+               $$ = scm_call_2 (scorify, $2, parser->self_scm ());
 
-               unsmob_score ($$)->origin ()->set_spot (@$);
+               if (scm_is_pair ($1) && ly_is_module (scm_car ($1)))
+               {
+                       unsmob_score ($$)->set_header (scm_car ($1));
+                       $1 = scm_cdr ($1);
+               }
+               for (SCM p = scm_reverse_x ($1, SCM_EOL);
+                    scm_is_pair (p); p = scm_cdr (p))
+               {
+                       unsmob_score ($$)->
+                               add_output_def (unsmob_output_def (scm_car (p)));
+               }
        }
        | embedded_scm_active {
-               Score *score;
-               if (unsmob_score ($1))
-                       score = new Score (*unsmob_score ($1));
-               else {
-                       score = new Score;
+               if (!unsmob_score ($1))
+               {
+                       $$ = (new Score)->unprotect ();
                        parser->parser_error (@1, _("score expected"));
                }
-               unsmob_score ($$)->origin ()->set_spot (@$);
-               $$ = score->unprotect ();
        }
        | score_body
        {
@@ -937,7 +1048,7 @@ output_def_head_with_mode_switch:
 // is still time to escape from notes mode.
 
 music_or_context_def:
-       music_arg
+       music_assign
        | context_def_spec_block
        ;
 
@@ -1020,8 +1131,17 @@ braced_music_list:
        }
        ;
 
-music: music_arg
+music: music_assign
        | lyric_element_music
+       | pitch_or_music
+       {
+               $$ = make_music_from_simple (parser, @1, $1);
+                if (!unsmob_music ($$))
+               {
+                        parser->parser_error (@1, _ ("music expected"));
+                       $$ = MAKE_SYNTAX ("void-music", @$);
+               }
+       }
        ;
 
 music_embedded:
@@ -1040,6 +1160,18 @@ music_embedded:
        {
                $$ = $3;
        }
+       | multiplied_duration post_events
+       {
+               Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
+
+               parser->default_duration_ = *unsmob_duration ($1);
+               n->set_property ("duration", $1);
+
+               if (scm_is_pair ($2))
+                       n->set_property ("articulations",
+                                        scm_reverse_x ($2, SCM_EOL));
+               $$ = n->unprotect ();
+       }
        ;
 
 music_embedded_backup:
@@ -1064,19 +1196,8 @@ music_embedded_backup:
        }
        ;
 
-music_arg:
-       simple_music
-       {
-               $$ = make_music_from_simple (parser, @1, $1);
-                if (!unsmob_music ($$))
-               {
-                        parser->parser_error (@1, _ ("music expected"));
-                       $$ = MAKE_SYNTAX ("void-music", @$);
-               }
-       }
-       | composite_music %prec COMPOSITE
-       ;
-
+// music_assign does not need to contain lyrics: there are no
+// assignments in lyricmode.
 music_assign:
        simple_music
        | composite_music %prec COMPOSITE
@@ -1087,20 +1208,10 @@ repeated_music:
        {
                $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, SCM_EOL);
        }
-       | REPEAT_IDENTIFIER music
-       {
-               $$ = MAKE_SYNTAX ("repeat", @$, scm_car ($1), scm_cdr ($1),
-                                 $2, SCM_EOL);
-       }
        | REPEAT simple_string unsigned_number music ALTERNATIVE braced_music_list
        {
                $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, $6);
        }
-       | REPEAT_IDENTIFIER music ALTERNATIVE braced_music_list
-       {
-               $$ = MAKE_SYNTAX ("repeat", @$, scm_car ($1), scm_cdr ($1),
-                                 $2, $4);
-       }
        ;
 
 sequential_music:
@@ -1161,7 +1272,7 @@ context_modification:
         ;
 
 context_modification_arg:
-       embedded_scm_closed
+       embedded_scm
        | MUSIC_IDENTIFIER
        ;
 
@@ -1199,16 +1310,6 @@ composite_music:
        | music_bare
        ;
 
-/* Music that can be parsed without lookahead */
-closed_music:
-       music_bare
-       | complex_music_prefix closed_music
-       {
-               $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
-       }
-       | music_function_call_closed
-       ;
-
 music_bare:
        mode_changed_music
        | MUSIC_IDENTIFIER
@@ -1248,13 +1349,6 @@ grouped_music_list:
  * will match and whether or not \default will be appearing in the
  * argument list, and where.
  *
- * Many of the basic nonterminals used for argument list scanning come
- * in a "normal" and a "closed" flavor.  A closed expression is one
- * that can be parsed without a lookahead token.  That makes it
- * feasible for an optional argument that may need to be skipped:
- * skipping can only be accomplished by pushing back the token into
- * the lexer, and that only works when there is no lookahead token.
- *
  * Sequences of 0 or more optional arguments are scanned using either
  * function_arglist_backup or function_arglist_nonbackup.  The first
  * is used when optional arguments are followed by at least one
@@ -1280,71 +1374,6 @@ grouped_music_list:
  *
  */
 
-function_arglist_nonbackup_common:
-       EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup FRACTION
-       {
-               $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup post_event_nofinger
-       {
-               $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' UNSIGNED
-       {
-               SCM n = scm_difference ($5, SCM_UNDEFINED);
-               if (scm_is_true (scm_call_1 ($2, n)))
-                       $$ = scm_cons (n, $3);
-               else {
-                       Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
-                       t->set_property ("digit", $5);
-                       $$ = check_scheme_arg (parser, @4, t->unprotect (),
-                                              $3, $2, n);
-               }
-               
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL
-       {
-               $$ = check_scheme_arg (parser, @4,
-                                      scm_difference ($5, SCM_UNDEFINED),
-                                      $3, $2);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' NUMBER_IDENTIFIER
-       {
-               $$ = check_scheme_arg (parser, @4,
-                                      scm_difference ($5, SCM_UNDEFINED),
-                                      $3, $2);
-       }
-       ;
-
-function_arglist_closed_nonbackup:
-       function_arglist_nonbackup_common
-       | function_arglist_closed_common
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg_closed
-       {
-               $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup bare_number_closed
-       {
-               $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
-       {
-               $$ = check_scheme_arg (parser, @4,
-                                      try_string_variants ($2, $4),
-                                      $3, $2, $4);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
-       {
-               $$ = check_scheme_arg (parser, @4,
-                                      try_string_variants ($2, $4),
-                                      $3, $2, $4);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup full_markup
-       {
-               $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-       }
-       ;
-
 symbol_list_arg:
        SYMBOL_LIST
        | SYMBOL_LIST '.' symbol_list_rev
@@ -1384,8 +1413,36 @@ symbol_list_element:
 
 
 function_arglist_nonbackup:
-       function_arglist_nonbackup_common
-       | function_arglist_common
+       function_arglist_common
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup post_event_nofinger
+       {
+               $$ = check_scheme_arg (parser, @4, $4, $3, $2);
+       }
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' UNSIGNED
+       {
+               SCM n = scm_difference ($5, SCM_UNDEFINED);
+               if (scm_is_true (scm_call_1 ($2, n)))
+                       $$ = scm_cons (n, $3);
+               else {
+                       Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
+                       t->set_property ("digit", $5);
+                       $$ = check_scheme_arg (parser, @4, t->unprotect (),
+                                              $3, $2, n);
+               }
+               
+       }
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL
+       {
+               $$ = check_scheme_arg (parser, @4,
+                                      scm_difference ($5, SCM_UNDEFINED),
+                                      $3, $2);
+       }
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' NUMBER_IDENTIFIER
+       {
+               $$ = check_scheme_arg (parser, @4,
+                                      scm_difference ($5, SCM_UNDEFINED),
+                                      $3, $2);
+       }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg
        {
                if (scm_is_true (scm_call_1 ($2, $4)))
@@ -1400,6 +1457,16 @@ function_arglist_nonbackup:
        {
                $$ = check_scheme_arg (parser, @4, $4, $3, $2);
        }
+       | function_arglist_nonbackup_reparse REPARSE pitch_or_music
+       {
+               if (scm_is_true (scm_call_1 ($2, $3)))
+                       $$ = scm_cons ($3, $1);
+               else
+                       $$ = check_scheme_arg (parser, @3,
+                                              make_music_from_simple
+                                              (parser, @3, $3),
+                                              $1, $2);
+       }
        | function_arglist_nonbackup_reparse REPARSE duration_length
        {
                $$ = check_scheme_arg (parser, @3, $3, $1, $2);
@@ -1440,6 +1507,28 @@ function_arglist_nonbackup_reparse:
                else
                        MYREPARSE (@4, $2, SCM_ARG, $4);
        }
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup pitch
+       {
+               $$ = $3;
+               if (scm_is_true
+                   (scm_call_1
+                    ($2, make_music_from_simple
+                     (parser, @4, $4))))
+                       MYREPARSE (@4, $2, PITCH_IDENTIFIER, $4);
+               else
+                       MYREPARSE (@4, $2, SCM_ARG, $4);
+       }
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup steno_tonic_pitch
+       {
+               $$ = $3;
+               if (scm_is_true
+                   (scm_call_1
+                    ($2, make_music_from_simple
+                     (parser, @4, $4))))
+                       MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
+               else
+                       MYREPARSE (@4, $2, SCM_ARG, $4);
+       }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
        {
                $$ = $3;
@@ -1490,55 +1579,65 @@ function_arglist_nonbackup_reparse:
        ;
 
 
+// function_arglist_backup can't occur at the end of an argument
+// list.
 function_arglist_backup:
-       function_arglist_backup_common
-       | function_arglist_common
-       ;
-
-function_arglist_backup_common:
-       EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup embedded_scm_arg_closed
+       function_arglist_common
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup embedded_scm_arg
        {
                if (scm_is_true (scm_call_1 ($2, $4)))
-               {
                        $$ = scm_cons ($4, $3);
-               } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (SCM_ARG, $4, @4);
+               else {
+                       $$ = make_music_from_simple (parser, @4, $4);
+                       if (scm_is_true (scm_call_1 ($2, $$)))
+                               $$ = scm_cons ($$, $3);
+                       else
+                       {
+                               $$ = scm_cons (loc_on_music (@3, $1), $3);
+                               MYBACKUP (SCM_ARG, $4, @4);
+                       }
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup REPEAT simple_string unsigned_number
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup post_event_nofinger
        {
-               $4 = MAKE_SYNTAX ("repeat", @4, $5, $6,
-                                 MY_MAKE_MUSIC ("Music", @4)->unprotect (),
-                                 SCM_EOL);
                if (scm_is_true (scm_call_1 ($2, $4)))
                {
-                       $$ = $3;
-                       MYREPARSE (@4, $2, REPEAT_IDENTIFIER, scm_cons ($5, $6));
+                       $$ = scm_cons ($4, $3);
                } else {
                        $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (REPEAT_IDENTIFIER, scm_cons ($5, $6), @4);
+                       MYBACKUP (EVENT_IDENTIFIER, $4, @4);
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup chord_body
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup pitch
        {
-               if (scm_is_true (scm_call_1 ($2, $4)))
+               if (scm_is_true
+                   (scm_call_1
+                    ($2, make_music_from_simple
+                     (parser, @4, $4))))
                {
                        $$ = $3;
-                       MYREPARSE (@4, $2, CHORD_BODY_IDENTIFIER, $4);
-               } else {
+                       MYREPARSE (@4, $2, PITCH_IDENTIFIER, $4);
+               } else if (scm_is_true (scm_call_1 ($2, $4)))
+                       $$ = scm_cons ($4, $3);
+               else {
                        $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (CHORD_BODY_IDENTIFIER, $4, @4);
+                       MYBACKUP (PITCH_IDENTIFIER, $4, @4);
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup post_event_nofinger
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup steno_tonic_pitch
        {
-               if (scm_is_true (scm_call_1 ($2, $4)))
+               if (scm_is_true
+                   (scm_call_1
+                    ($2, make_music_from_simple
+                     (parser, @4, $4))))
                {
+                       $$ = $3;
+                       MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
+               } else if (scm_is_true (scm_call_1 ($2, $4)))
                        $$ = scm_cons ($4, $3);
-               else {
+               else {
                        $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (EVENT_IDENTIFIER, $4, @4);
+                       MYBACKUP (TONICNAME_PITCH, $4, @4);
                }
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup full_markup
@@ -1589,16 +1688,6 @@ function_arglist_backup_common:
                        MYBACKUP (NUMBER_IDENTIFIER, $4, @4);
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup FRACTION
-       {
-               if (scm_is_true (scm_call_1 ($2, $4)))
-               {
-                       $$ = scm_cons ($4, $3);
-               } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (FRACTION, $4, @4);
-               }
-       }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' UNSIGNED
        {
                SCM n = scm_difference ($5, SCM_UNDEFINED);
@@ -1614,7 +1703,7 @@ function_arglist_backup_common:
                        else {
                                $$ = scm_cons (loc_on_music (@3, $1), $3);
                                MYBACKUP (UNSIGNED, $5, @5);
-                               parser->lexer_->push_extra_token ('-');
+                               parser->lexer_->push_extra_token (@4, '-');
                        }
                }
                
@@ -1640,38 +1729,6 @@ function_arglist_backup_common:
                        MYBACKUP (NUMBER_IDENTIFIER, n, @5);
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup PITCH_IDENTIFIER
-       {
-               if (scm_is_true (scm_call_1 ($2, $4)))
-               {
-                       $$ = scm_cons ($4, $3);
-               } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (PITCH_IDENTIFIER, $4, @4);
-               }
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup NOTENAME_PITCH
-       {
-               if (scm_is_true (scm_call_1 ($2, $4)))
-               {
-                       MYREPARSE (@4, $2, NOTENAME_PITCH, $4);
-                       $$ = $3;
-               } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (NOTENAME_PITCH, $4, @4);
-               }
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup TONICNAME_PITCH
-       {
-               if (scm_is_true (scm_call_1 ($2, $4)))
-               {
-                       MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
-                       $$ = $3;
-               } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (TONICNAME_PITCH, $4, @4);
-               }
-       }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup DURATION_IDENTIFIER
        {
                if (scm_is_true (scm_call_1 ($2, $4)))
@@ -1713,7 +1770,7 @@ function_arglist_backup_common:
                        MYBACKUP (STRING, $4, @4);
                }
        }
-       | function_arglist_backup REPARSE music_assign
+       | function_arglist_backup REPARSE pitch_or_music
        {
                if (scm_is_true (scm_call_1 ($2, $3)))
                        $$ = scm_cons ($3, $1);
@@ -1774,11 +1831,6 @@ function_arglist_common:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $2, $1);
        }
-       | EXPECT_SCM function_arglist_optional FRACTION
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $2, $1);
-       }
        | EXPECT_SCM function_arglist_optional post_event_nofinger
        {
                $$ = check_scheme_arg (parser, @3,
@@ -1799,6 +1851,16 @@ function_arglist_common:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $1, $2);
        }
+       | function_arglist_common_reparse REPARSE pitch_or_music
+       {
+               if (scm_is_true (scm_call_1 ($2, $3)))
+                       $$ = scm_cons ($3, $1);
+               else
+                       $$ = check_scheme_arg (parser, @3,
+                                              make_music_from_simple
+                                              (parser, @3, $3),
+                                              $1, $2);
+       }
        | function_arglist_common_reparse REPARSE bare_number_common
        {
                $$ = check_scheme_arg (parser, @3,
@@ -1834,6 +1896,28 @@ function_arglist_common_reparse:
                        // know the predicate to be false.
                        MYREPARSE (@3, $1, SCM_ARG, $3);
        }
+       | EXPECT_SCM function_arglist_optional pitch
+       {
+               $$ = $2;
+               if (scm_is_true
+                   (scm_call_1
+                    ($1, make_music_from_simple
+                     (parser, @3, $3))))
+                       MYREPARSE (@3, $1, PITCH_IDENTIFIER, $3);
+               else
+                       MYREPARSE (@3, $1, SCM_ARG, $3);
+       }
+       | EXPECT_SCM function_arglist_optional steno_tonic_pitch
+       {
+               $$ = $2;
+               if (scm_is_true
+                   (scm_call_1
+                    ($1, make_music_from_simple
+                     (parser, @3, $3))))
+                       MYREPARSE (@3, $1, TONICNAME_PITCH, $3);
+               else
+                       MYREPARSE (@3, $1, SCM_ARG, $3);
+       }
        | EXPECT_SCM function_arglist_optional STRING
        {
                $$ = $2;
@@ -1909,60 +1993,6 @@ function_arglist_common_reparse:
        }
        ;
 
-function_arglist_closed:
-       function_arglist_closed_nonbackup
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
-       {
-               $$ = scm_cons (loc_on_music (@4, $1), $3);
-       }
-       ;
-
-function_arglist_closed_common:
-       EXPECT_NO_MORE_ARGS {
-               $$ = SCM_EOL;
-       }
-       | EXPECT_SCM function_arglist_optional embedded_scm_arg_closed
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $2, $1);
-       }
-       | EXPECT_SCM function_arglist_optional bare_number_common_closed
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $2, $1);
-       }
-       | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      scm_difference ($4, SCM_UNDEFINED),
-                                      $2, $1);
-       }
-       | EXPECT_SCM function_arglist_optional post_event_nofinger
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $2, $1);
-       }
-       | EXPECT_SCM function_arglist_optional FRACTION
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $2, $1);
-       }
-       | function_arglist_common_reparse REPARSE SCM_ARG
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $1, $2);
-       }
-       | function_arglist_common_reparse REPARSE bare_number_common_closed
-       {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $1, $2);
-       }
-       | function_arglist_common_reparse REPARSE symbol_list_arg
-       {
-               $$ = check_scheme_arg (parser, @3, $3, $1, $2);
-       }
-       ;
-
 function_arglist_optional:
        function_arglist_backup
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup DEFAULT
@@ -1980,24 +2010,6 @@ function_arglist_skip_backup:
        }
        ;
 
-embedded_scm_closed:
-       embedded_scm_bare
-       | scm_function_call_closed
-       ;
-
-embedded_scm_arg_closed:
-       embedded_scm_bare_arg
-       | scm_function_call_closed
-       | closed_music
-       ;
-
-scm_function_call_closed:
-       SCM_FUNCTION function_arglist_closed {
-               $$ = MAKE_SYNTAX ("music-function", @$,
-                                        $1, $2);
-       }
-       ;
-
 music_function_call:
        MUSIC_FUNCTION function_arglist {
                $$ = MAKE_SYNTAX ("music-function", @$,
@@ -2155,8 +2167,8 @@ re_rhythmed_music:
        ;
 
 context_change:
-       CHANGE STRING '=' STRING  {
-               $$ = MAKE_SYNTAX ("context-change", @$, scm_string_to_symbol ($2), $4);
+       CHANGE symbol '=' simple_string  {
+               $$ = MAKE_SYNTAX ("context-change", @$, $2, $4);
        }
        ;
 
@@ -2402,10 +2414,10 @@ simple_revert_context:
                    (scm_object_property (scm_car ($1),
                                          ly_symbol2scm ("is-grob?")))) {
                        $$ = ly_symbol2scm ("Bottom");
-                       parser->lexer_->push_extra_token (SCM_IDENTIFIER, $1);
+                       parser->lexer_->push_extra_token (@1, SCM_IDENTIFIER, $1);
                } else {
                        $$ = scm_car ($1);
-                       parser->lexer_->push_extra_token (SCM_IDENTIFIER,
+                       parser->lexer_->push_extra_token (@1, SCM_IDENTIFIER,
                                                          scm_cdr ($1));
                }
        }
@@ -2463,6 +2475,7 @@ symbol:
 
 scalar:
        embedded_scm_arg
+       | pitch_or_music
        | SCM_IDENTIFIER
        | bare_number
        // The following is a rather defensive variant of admitting
@@ -2476,35 +2489,17 @@ scalar:
        {
                $$ = scm_difference ($2, SCM_UNDEFINED);
        }
-       | FRACTION
-       | STRING
-       | full_markup
+       | string
        ;
 
 event_chord:
        simple_element post_events {
                // Let the rhythmic music iterator sort this mess out.
                if (scm_is_pair ($2)) {
-                       $$ = make_music_from_simple (parser, @1, $1);
-                       if (unsmob_music ($$))
-                                unsmob_music ($$)->set_property ("articulations",
-                                                                 scm_reverse_x ($2, SCM_EOL));
-                        else
-                       {
-                                parser->parser_error (@1, _("music expected"));
-                               $$ = MAKE_SYNTAX ("void-music", @1);
-                       }
+                       unsmob_music ($$)->set_property ("articulations",
+                                                        scm_reverse_x ($2, SCM_EOL));
                }
        } %prec ':'
-       | simple_chord_elements post_events     {
-               SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
-
-               Input i;
-               /* why is this giving wrong start location? -ns
-                * i = @$; */
-               i.set_location (@1, @2);
-               $$ = MAKE_SYNTAX ("event-chord", i, elts);
-       } %prec ':'
        | CHORD_REPETITION optional_notemode_duration post_events {
                Input i;
                i.set_location (@1, @3);
@@ -2517,7 +2512,7 @@ event_chord:
                $$ = MAKE_SYNTAX ("multi-measure-rest", i, $2,
                                  scm_reverse_x ($3, SCM_EOL));
        } %prec ':'
-       | command_element
+       | tempo_event
        | note_chord_element
        ;
 
@@ -2545,7 +2540,6 @@ chord_body:
        {
                $$ = MAKE_SYNTAX ("event-chord", @$, scm_reverse_x ($2, SCM_EOL));
        }
-       | CHORD_BODY_IDENTIFIER
        ;
 
 chord_body_elements:
@@ -2614,38 +2608,13 @@ music_function_chord_body:
        | MUSIC_IDENTIFIER
        ;
 
-// Event functions may only take closed arglists, otherwise it would
-// not be clear whether a following postevent should be associated
-// with the last argument of the event function or with the expression
-// for which the function call acts itself as event.
-
-music_function_call_closed:
-       MUSIC_FUNCTION function_arglist_closed {
-               $$ = MAKE_SYNTAX ("music-function", @$,
-                                        $1, $2);
-       }
-       ;
-
 event_function_event:
-       EVENT_FUNCTION function_arglist_closed {
+       EVENT_FUNCTION function_arglist {
                $$ = MAKE_SYNTAX ("music-function", @$,
                                         $1, $2);
        }
        ;
 
-command_element:
-       command_event {
-               $$ = $1;
-       }
-       ;
-
-command_event:
-       tempo_event {
-               $$ = $1;
-       }
-       ;
-
-
 post_events:
        /* empty */ {
                $$ = SCM_EOL;
@@ -2674,7 +2643,7 @@ post_event_nofinger:
        direction_less_event {
                $$ = $1;
        }
-       | script_dir music_function_call_closed {
+       | script_dir music_function_call {
                $$ = $2;
                if (!unsmob_music ($2)->is_mus_type ("post-event")) {
                        parser->parser_error (@2, _ ("post-event expected"));
@@ -2756,11 +2725,21 @@ direction_reqd_event:
        }
        | script_abbreviation {
                SCM s = parser->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
-               Music *a = MY_MAKE_MUSIC ("ArticulationEvent", @$);
-               if (scm_is_string (s))
+               if (scm_is_string (s)) {
+                       Music *a = MY_MAKE_MUSIC ("ArticulationEvent", @$);
                        a->set_property ("articulation-type", s);
-               else parser->parser_error (@1, _ ("expecting string as script definition"));
-               $$ = a->unprotect ();
+                       $$ = a->unprotect ();
+               } else {
+                       Music *original = unsmob_music (s);
+                       if (original && original->is_mus_type ("post-event")) {
+                               Music *a = original->clone ();
+                               a->set_spot (parser->lexer_->override_input (@$));
+                               $$ = a->unprotect ();
+                       } else {
+                               parser->parser_error (@1, _ ("expecting string or post-event as script definition"));
+                               $$ = MY_MAKE_MUSIC ("PostEvents", @$)->unprotect ();
+                       }
+               }
        }
        ;
 
@@ -2824,7 +2803,14 @@ steno_tonic_pitch:
 
 pitch:
        steno_pitch
-       | PITCH_IDENTIFIER
+       | PITCH_IDENTIFIER quotes {
+                if (!scm_is_eq (SCM_INUM0, $2))
+                {
+                        Pitch p = *unsmob_pitch ($1);
+                        p = p.transposed (Pitch (scm_to_int ($2),0,0));
+                        $$ = p.smobbed_copy ();
+                }
+       }
        ;
 
 gen_text_def:
@@ -2839,7 +2825,7 @@ gen_text_def:
                        make_simple_markup ($1));
                $$ = t->unprotect ();
        }
-       | embedded_scm_closed
+       | embedded_scm
        {
                Music *m = unsmob_music ($1);
                if (m && m->is_mus_type ("post-event"))
@@ -3077,15 +3063,16 @@ optional_rest:
        | REST { $$ = SCM_BOOL_T; }
        ;
 
-simple_element:
-       pitch exclamations questions octave_check maybe_notemode_duration optional_rest {
+pitch_or_music:
+       pitch exclamations questions octave_check maybe_notemode_duration optional_rest post_events {
                if (!parser->lexer_->is_note_state ())
                        parser->parser_error (@1, _ ("have to be in Note mode for notes"));
                if (!SCM_UNBNDP ($2)
                     || !SCM_UNBNDP ($3)
                     || scm_is_number ($4)
                     || !SCM_UNBNDP ($5)
-                    || scm_is_true ($6))
+                    || scm_is_true ($6)
+                   || scm_is_pair ($7))
                {
                        Music *n = 0;
                        if (scm_is_true ($6))
@@ -3110,11 +3097,31 @@ simple_element:
                                n->set_property ("cautionary", SCM_BOOL_T);
                        if (to_boolean ($2) || to_boolean ($3))
                                n->set_property ("force-accidental", SCM_BOOL_T);
-                       
+                       if (scm_is_pair ($7))
+                               n->set_property ("articulations",
+                                                scm_reverse_x ($7, SCM_EOL));
                        $$ = n->unprotect ();
                }
-       }
-       | DRUM_PITCH optional_notemode_duration {
+       } %prec ':'
+       | simple_chord_elements post_events {
+               if (scm_is_pair ($2)) {
+                       if (unsmob_pitch ($1))
+                               $1 = make_chord_elements (@1,
+                                                         $1,
+                                                         parser->default_duration_.smobbed_copy (),
+                                                         SCM_EOL);
+
+                       SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
+
+                       $$ = MAKE_SYNTAX ("event-chord", @1, elts);
+               } else if (!unsmob_pitch ($1))
+                       $$ = MAKE_SYNTAX ("event-chord", @1, $1);
+               // A mere pitch drops through.
+       } %prec ':'
+       ;
+
+simple_element:
+       DRUM_PITCH optional_notemode_duration {
                Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
                n->set_property ("duration", $2);
                n->set_property ("drum-type", $1);
@@ -3136,6 +3143,7 @@ simple_element:
        }
        ;
 
+// Can return a single pitch rather than a list.
 simple_chord_elements:
        new_chord {
                 if (!parser->lexer_->is_chord_state ())
@@ -3174,9 +3182,13 @@ lyric_element_music:
        } %prec ':'
        ;
 
+// Can return a single pitch rather than a list.
 new_chord:
-       steno_tonic_pitch optional_notemode_duration   {
-               $$ = make_chord_elements (@$, $1, $2, SCM_EOL);
+       steno_tonic_pitch maybe_notemode_duration   {
+               if (SCM_UNBNDP ($2))
+                       $$ = $1;
+               else
+                       $$ = make_chord_elements (@$, $1, $2, SCM_EOL);
        }
        | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
                SCM its = scm_reverse_x ($4, SCM_EOL);
@@ -3240,10 +3252,10 @@ step_number:
        ;
 
 tempo_range:
-       UNSIGNED {
+       unsigned_number {
                $$ = $1;
-       }
-       | UNSIGNED '-' UNSIGNED {
+       } %prec ':'
+       | unsigned_number '-' unsigned_number {
                $$ = scm_cons ($1, $3);
        }
        ;
@@ -3284,18 +3296,14 @@ number_factor:
        ;
 
 bare_number_common:
-       bare_number_common_closed
+       REAL
+       | NUMBER_IDENTIFIER
        | REAL NUMBER_IDENTIFIER
        {
                $$ = scm_product ($1, $2);
        }
        ;
 
-bare_number_common_closed:
-       REAL
-       | NUMBER_IDENTIFIER
-       ;
-
 bare_number:
        bare_number_common
        | UNSIGNED
@@ -3304,14 +3312,26 @@ bare_number:
        }
        ;
 
-bare_number_closed:
-       UNSIGNED
-       | bare_number_common_closed
-       ;
-
 unsigned_number:
        UNSIGNED
        | NUMBER_IDENTIFIER
+       {
+               if (!scm_is_integer ($1)
+                   || scm_is_true (scm_negative_p ($1)))
+               {
+                       parser->parser_error (@1, _("not an unsigned integer"));
+                       $$ = SCM_INUM0;
+               }
+       }
+       | embedded_scm
+       {
+               if (!scm_is_integer ($1)
+                   || scm_is_true (scm_negative_p ($1)))
+               {
+                       parser->parser_error (@1, _("not an unsigned integer"));
+                       $$ = SCM_INUM0;
+               }
+       }
        ;
 
 exclamations:
@@ -3326,7 +3346,13 @@ exclamations:
        ;
 
 questions:
-       { $$ = SCM_UNDEFINED; }
+// This precedence rule is rather weird.  It triggers when '!' is
+// encountered after a pitch, and is used for deciding whether to save
+// this instead for a figure modification.  This should not actually
+// occur in practice as pitches and figures are generated in different
+// modes.  Using a greedy (%right) precedence makes sure that we don't
+// get stuck in a wrong interpretation.
+       { $$ = SCM_UNDEFINED; } %prec ':'
        | questions '?'
         {
                 if (SCM_UNBNDP ($1))
@@ -3355,7 +3381,7 @@ full_markup:
        ;
 
 markup_top:
-       simple_markup_list {
+       markup_list {
                $$ = scm_list_2 (ly_lily_module_constant ("line-markup"),  $1);
        }
        | markup_head_1_list simple_markup
@@ -3383,7 +3409,7 @@ markup_scm:
        ;
                        
 
-simple_markup_list:
+markup_list:
        markup_composed_list {
                $$ = $1;
        }
@@ -3401,22 +3427,12 @@ markup_uncomposed_list:
        {
                $$ = $2;
        }
-       ;
-
-markup_list:
-       simple_markup_list
-       | markup_score
-       {
-               $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $1));
-       }
-       ;
-
-markup_score:
-       SCORE {
+       | SCORELINES {
                SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
                parser->lexer_->push_note_state (nn);
        } '{' score_body '}' {
-               $$ = $4;
+               unsmob_score ($4)->origin ()->set_spot (@$);
+               $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $4));
                parser->lexer_->pop_state ();
        }
        ;
@@ -3439,7 +3455,7 @@ markup_braced_list_body:
        | markup_braced_list_body markup {
                $$ = scm_cons ($2, $1);
        }
-       | markup_braced_list_body simple_markup_list {
+       | markup_braced_list_body markup_list {
                $$ = scm_reverse_x ($2, $1);
        }
        ;
@@ -3454,7 +3470,7 @@ markup_command_basic_arguments:
        EXPECT_MARKUP_LIST markup_command_list_arguments markup_list {
          $$ = scm_cons ($3, $2);
        }
-       | EXPECT_SCM markup_command_list_arguments embedded_scm_closed {
+       | EXPECT_SCM markup_command_list_arguments embedded_scm {
          $$ = check_scheme_arg (parser, @3, $3, $2, $1);
        }
        | EXPECT_NO_MORE_ARGS {
@@ -3488,6 +3504,14 @@ simple_markup:
        STRING {
                $$ = make_simple_markup ($1);
        }
+       | SCORE {
+               SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
+               parser->lexer_->push_note_state (nn);
+       } '{' score_body '}' {
+               unsmob_score ($4)->origin ()->set_spot (@$);
+               $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $4);
+               parser->lexer_->pop_state ();
+       }
        | MARKUP_FUNCTION markup_command_basic_arguments {
                $$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
        }
@@ -3495,10 +3519,6 @@ simple_markup:
        {
                $$ = $2;
        }
-       | markup_score
-       {
-               $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $1);
-       }
        ;
 
 markup:
@@ -3580,6 +3600,9 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
                *destination = p->self_scm ();
                p->unprotect ();
                return OUTPUT_DEF_IDENTIFIER;
+       } else if (unsmob_score (sid)) {
+               *destination = unsmob_score (sid)->clone ()->unprotect ();
+               return SCM_IDENTIFIER;
        }
 
        return -1;
@@ -3736,9 +3759,12 @@ make_music_from_simple (Lily_parser *parser, Input loc, SCM simple)
                                            parser->default_duration_.smobbed_copy ());
        } else if (parser->lexer_->is_chord_state ()) {
                if (unsmob_pitch (simple))
-                       return make_chord_elements (loc, simple,
-                                                   parser->default_duration_.smobbed_copy (),
-                                                   SCM_EOL);
+                       return MAKE_SYNTAX
+                               ("event-chord",
+                                loc,
+                                make_chord_elements (loc, simple,
+                                                     parser->default_duration_.smobbed_copy (),
+                                                     SCM_EOL));
        }
        return simple;
 }
@@ -3801,6 +3827,9 @@ yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser)
 
        lex->lexval_ = s;
        lex->lexloc_ = loc;
+       int tok = lex->pop_extra_token ();
+       if (tok >= 0)
+               return tok;
        lex->prepare_for_next_token ();
        return lex->yylex ();
 }
index 7c3b3e965b56f171ef2e3761c7c9a85867581ad0..681479a69efb9b4b587025f81241608184d5c294 100644 (file)
@@ -38,14 +38,34 @@ Partial_iterator::process (Moment m)
   if (Duration * dur
       = unsmob_duration (get_music ()->get_property ("duration")))
     {
-      Context *ctx = get_outlet ();
-      Moment now = ctx->now_mom ();
-      if (now.main_part_ > Rational (0))
-        get_music ()->origin ()->
-        warning (_ ("trying to use \\partial after the start of a piece"));
-      Moment length = Moment (dur->get_length ());
-      now = Moment (0, now.grace_part_);
-      ctx->set_property ("measurePosition", (now - length).smobbed_copy ());
+      // Partial_iterator is an iterator rather than an engraver, so
+      // the active context it is getting called in does not depend on
+      // which context definition the engraver might be defined.
+      //
+      // Using where_defined to find the context where measurePosition
+      // should be overwritten does not actually work since the
+      // Timing_translator does not set measurePosition when
+      // initializing.
+
+      Context *timing = unsmob_context (scm_call_2 (ly_lily_module_constant ("ly:context-find"),
+                                                    get_outlet ()->self_scm (),
+                                                    ly_symbol2scm ("Timing")));
+
+      if (!timing)
+        programming_error ("missing Timing in \\partial");
+      else
+        {
+          Moment mp = robust_scm2moment (timing->get_property ("measurePosition"),
+                                         Rational (0));
+
+          if (mp.main_part_ > Rational (0))
+            mp.main_part_ = measure_length (timing);
+          else
+            mp.main_part_ = 0;
+
+          Moment length = Moment (dur->get_length ());
+          timing->set_property ("measurePosition", (mp - length).smobbed_copy ());
+        }
     }
   else
     programming_error ("invalid duration in \\partial");
index 4e19544d41823b6e21a5e0003d0a6616641a4745..dfd23a871af1080ce57e8b4d9b862c6745c4d7f3 100644 (file)
@@ -56,7 +56,7 @@ Performance::output (Midi_stream &midi_stream) const
   for (vsize i = 0; i < audio_staffs_.size (); i++)
     {
       Audio_staff *s = audio_staffs_[i];
-      debug_output ("[" + to_string (i), true);
+      debug_output ("[" + ::to_string (i), true);
       s->output (midi_stream, i, ports_);
       debug_output ("]", false);
     }
index c4c5de1e73a19f5e1cadc839f2d7f70d0a63efc4..3a448546b05f74b034436da5a6df1d905062eb4d 100644 (file)
@@ -217,7 +217,7 @@ Rest::glyph_name (Grob *me, int durlog, const string &style, bool try_ledgers,
       actual_style = "";
     }
 
-  return ("rests." + to_string (durlog) + (is_ledgered ? "o" : "")
+  return ("rests." + ::to_string (durlog) + (is_ledgered ? "o" : "")
           + actual_style);
 }
 
index 0a014a38008bb3e57aafb92a3671aa90b0c8ac95..8c963929bff878ac9773ca64b147fd0294a5ae84 100644 (file)
@@ -152,11 +152,12 @@ Script_column::order_grobs (vector<Grob *> grobs)
             {
               SCM last_outside_staff = last->get_property ("outside-staff-priority");
               /*
-                if outside_staff_priority is missing for previous grob, just
-                use it as a support for the current grob
+                if outside_staff_priority is missing for previous grob,
+                use all the scripts so far as support for the current grob
               */
               if (!scm_is_number (last_outside_staff))
-                Side_position_interface::add_support (g, last);
+                for (SCM t = ss; !scm_is_eq (t, s); t = scm_cdr (t))
+                  Side_position_interface::add_support (g, unsmob_grob (scm_car (t)));
               /*
                 if outside_staff_priority is missing or is equal to original
                 outside_staff_priority of previous grob, set new
index 3b891e8e79f1e978f6ab82ded8ff45f9e37a4bb2..3e0ad4fae72cc504185da470df43bc4c8b2c9ff3 100644 (file)
@@ -63,7 +63,7 @@ Simultaneous_music_iterator::construct_children ()
 
       SCM name = ly_symbol2scm (get_outlet ()->context_name ().c_str ());
       Context *c = (j && create_separate_contexts_)
-                   ? get_outlet ()->find_create_context (name, to_string (j), SCM_EOL)
+                   ? get_outlet ()->find_create_context (name, ::to_string (j), SCM_EOL)
                    : get_outlet ();
 
       if (!c)
index 332995ac99ef051d760cf1a786080a16f8bf6314..46e9d917a119de2c03d2c985ddbdae878b3c3431 100644 (file)
@@ -43,27 +43,41 @@ avoid_staff_line (Slur_score_state const &state,
       && (state.extremes_[LEFT].staff_ == state.extremes_[RIGHT].staff_)
       && state.extremes_[LEFT].staff_ && state.extremes_[RIGHT].staff_)
     {
-      Real y = bez.curve_point (ts[0])[Y_AXIS];
+      Real t = ts[0]; //the first (usually only) point where slur is horizontal
+      Real y = bez.curve_point (t)[Y_AXIS];
+      // A Bezier curve at t moves 3t-3t² as far as the middle control points
+      Real factor = 3.0 * t * (1.0 - t);
 
       Grob *staff = state.extremes_[LEFT].staff_;
 
       Real p = 2 * (y - staff->relative_coordinate (state.common_[Y_AXIS], Y_AXIS))
                / state.staff_space_;
 
-      Real const round = my_round (p);
-      Real const frac = p - round;
-      if (fabs (frac) < 4 * state.thickness_
-          && Staff_symbol_referencer::on_staff_line (staff, int (round)))
+      int round_p = (int) my_round (p);
+      if (!Staff_symbol_referencer::on_staff_line (staff, round_p))
+        round_p += (p > round_p) ? 1 : -1;
+      if (!Staff_symbol_referencer::on_staff_line (staff, round_p))
+        return bez;
+
+      Real const distance = (p - round_p) * state.staff_space_ / 2.0;
+      // Allow half the thickness of the slur at the point t, plus one basic
+      // blot-diameter (half for the slur outline, half for the staff line)
+      Real const min_distance = 0.5 * state.thickness_ * factor
+        + state.line_thickness_
+        + ((state.dir_ * distance > 0.0)
+           ? state.parameters_.gap_to_staffline_inside_
+           : state.parameters_.gap_to_staffline_outside_);
+      if (fabs (distance) < min_distance)
         {
-          Direction resolution_dir = frac ? state.dir_ : CENTER;
+          Direction resolution_dir = (distance > 0.0) ? UP : DOWN;
 
-          // TODO: parameter
-          Real newp = round + resolution_dir * 5 * state.thickness_;
-
-          Real dy = (newp - p) * state.staff_space_ / 2.0;
+          Real dy = resolution_dir * (min_distance - fabs (distance));
 
+          // Shape the curve, moving the horizontal point by factor * dy
           bez.control_[1][Y_AXIS] += dy;
           bez.control_[2][Y_AXIS] += dy;
+          // Move the entire curve by the remaining amount
+          bez.translate (Offset (0.0, dy - factor * dy));
         }
     }
   return bez;
index a8cbe4b7f90b7d610ad240633f6153de0e0cdc95..789e31ea4b4fbafaf1cecf576365f2bfd7b94ecd 100644 (file)
@@ -56,6 +56,10 @@ Slur_score_parameters::fill (Grob *me)
     = get_detail (details, ly_symbol2scm ("max-slope-factor"));
   free_head_distance_
     = get_detail (details, ly_symbol2scm ("free-head-distance"));
+  gap_to_staffline_inside_
+    = get_detail (details, ly_symbol2scm ("gap-to-staffline-inside"));
+  gap_to_staffline_outside_
+    = get_detail (details, ly_symbol2scm ("gap-to-staffline-outside"));
   absolute_closeness_measure_
     = get_detail (details, ly_symbol2scm ("absolute-closeness-measure"));
   extra_object_collision_penalty_
index 47bb40611c483018713bae43ec380b3ed1cd9461..98e3f2a45d0766b878343b0e6782906715d2bae9 100644 (file)
@@ -226,8 +226,8 @@ Slur_score_state::fill (Grob *me)
 
   Slur::replace_breakable_encompass_objects (me);
   staff_space_ = Staff_symbol_referencer::staff_space (me);
-  Real lt = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
-  thickness_ = robust_scm2double (me->get_property ("thickness"), 1.0) * lt;
+  line_thickness_ = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
+  thickness_ = robust_scm2double (me->get_property ("thickness"), 1.0) * line_thickness_;
 
   dir_ = slur_direction ();
   parameters_.fill (me);
index 0aa96c787d1d7ba482ed0170e3990ee703258236..10069aacd4323505577d4dea430569f545a56393 100644 (file)
@@ -542,6 +542,12 @@ ADD_INTERFACE (Slur,
                "@item head-slur-distance-max-ratio\n"
                "The maximum value for the ratio of distance between a"
                " note head and slur.\n"
+               "@item gap-to-staffline-inside\n"
+               "Minimum gap inside the curve of the slur"
+               " where the slur is parallel to a staffline.\n"
+               "@item gap-to-staffline-outside\n"
+               "Minimum gap outside the curve of the slur"
+               " where the slur is parallel to a staffline.\n"
                "@item free-slur-distance\n"
                "The amount of vertical free space that must exist"
                " between adjacent slurs.  This subproperty only works"
index 26426ae8af1e80824e2626f41c1ff1449e134d99..788c78a69ee6239795b5026fbf8cb37c1995e522 100644 (file)
@@ -181,8 +181,8 @@ Source_file::file_line_column_string (char const *context_str0) const
       int l, ch, col, offset;
       get_counts (context_str0, &l, &ch, &col, &offset);
 
-      return name_string () + ":" + to_string (l)
-             + ":" + to_string (col + 1);
+      return name_string () + ":" + ::to_string (l)
+             + ":" + ::to_string (col + 1);
     }
 }
 
@@ -196,8 +196,8 @@ Source_file::quote_input (char const *pos_str0) const
   get_counts (pos_str0, &l, &ch, &col, &offset);
   string line = line_string (pos_str0);
   string context = line.substr (0, offset)
-                   + to_string ('\n')
-                   + to_string (' ', col)
+                   + ::to_string ('\n')
+                   + ::to_string (' ', col)
                    + line.substr (offset, line.length () - offset);
   return context;
 }
index d4b523c06c63b82094346bc1d13d08af83ae4a4a..a45b7dd13a6c0fd87936da38584331e1f73cda87 100644 (file)
@@ -169,7 +169,7 @@ System_start_delimiter::staff_brace (Grob *me, Real y)
     }
   while (hi - lo > 1);
 
-  Stencil stil (fm->find_by_name ("brace" + to_string (lo)));
+  Stencil stil (fm->find_by_name ("brace" + ::to_string (lo)));
   stil.translate_axis (-b[X_AXIS].length () / 2, X_AXIS);
 
   stil.translate_axis (-0.2, X_AXIS);
index 1ec46fbaf655c342d3e9a6e20faae3df9f352c0f..ad4d0bab772453f4007edd23b6519c429eed347e 100644 (file)
@@ -223,7 +223,7 @@ System::get_paper_systems ()
       scm_vector_set_x (lines, scm_from_int (i),
                         system->get_paper_system ());
 
-      debug_output (to_string (i) + "]", false);
+      debug_output (::to_string (i) + "]", false);
     }
   return lines;
 }
index f00c2563f6fe4f71922577e5f0d4963ad41c2547..89f20278bfbe35290e836e61a851e2af1313c772 100644 (file)
@@ -67,7 +67,7 @@ Time_signature::special_time_signature (Grob *me, SCM scm_style, int n, int d)
     return numbered_time_signature (me, n, d);
 
   if ((style == "default") || (style == ""))
-    style = to_string ("C");
+    style = ::to_string ("C");
 
   if (style == "C")
     {
@@ -77,7 +77,7 @@ Time_signature::special_time_signature (Grob *me, SCM scm_style, int n, int d)
         return numbered_time_signature (me, n, d);
     }
 
-  string char_name = style + to_string (n) + to_string (d);
+  string char_name = style + ::to_string (n) + ::to_string (d);
   me->set_property ("font-encoding", ly_symbol2scm ("fetaMusic"));
   Stencil out = Font_interface::get_default_font (me)
                 ->find_by_name ("timesig." + char_name);
@@ -100,9 +100,9 @@ Time_signature::numbered_time_signature (Grob *me, int num, int den)
                     chain);
 
   SCM sn = Text_interface::interpret_markup (me->layout ()->self_scm (), chain,
-                                             ly_string2scm (to_string (num)));
+                                             ly_string2scm (::to_string (num)));
   SCM sd = Text_interface::interpret_markup (me->layout ()->self_scm (), chain,
-                                             ly_string2scm (to_string (den)));
+                                             ly_string2scm (::to_string (den)));
 
   Stencil n = *unsmob_stencil (sn);
   Stencil d = *unsmob_stencil (sd);
index 9b2f871769356ea1de2f47900d8a5a6fb5ffb037..b8d1e2d4a5a84d5458c30af1b1a4fcd64754946d 100644 (file)
@@ -32,6 +32,17 @@ is_unpure_pure_container (SCM s)
   return (SCM_NIMP (s) && SCM_CELL_TYPE (s) == unpure_pure_container_tag);
 }
 
+bool
+is_unchanging_unpure_pure_container (SCM s)
+// A container that has the same callback for both 'pure' and 'unpure' lookups
+// and which ignores the 'start' and 'end' columnns.
+// Such a callback will give the same answer for tentative or final layouts.
+{
+  LY_ASSERT_TYPE (is_unpure_pure_container, s, 1);
+  SCM pure_part = SCM_SMOB_OBJECT_2 (s);
+  return (SCM_UNBNDP (pure_part));
+}
+
 SCM
 unpure_pure_container_unpure_part (SCM smob)
 {
index 2e386e6fd18bba885a63cd6e3c1426fe29db2e29..e9b858de3991a9e7e4848ecacd677847ab3f2623 100644 (file)
@@ -33,17 +33,27 @@ protected:
   virtual void next_element (bool);
   virtual void construct_children ();
   virtual void process (Moment);
+  virtual void derived_mark () const;
 
   bool first_time_;
   int alt_count_;
   int rep_count_;
   int done_count_;
+  SCM alt_restores_;
 };
 
 Volta_repeat_iterator::Volta_repeat_iterator ()
 {
   done_count_ = alt_count_ = rep_count_ = 0;
   first_time_ = true;
+  alt_restores_ = SCM_EOL;
+}
+
+void
+Volta_repeat_iterator::derived_mark () const
+{
+  scm_gc_mark (alt_restores_);
+  Sequential_iterator::derived_mark ();
 }
 
 SCM
@@ -94,17 +104,46 @@ Volta_repeat_iterator::next_element (bool side_effect)
     {
       if (alt_count_)
         {
-          string repstr = to_string (rep_count_ - alt_count_ + done_count_) + ".";
-          if (done_count_ > 1)
+          string repstr = ::to_string (rep_count_ - alt_count_ + done_count_) + ".";
+          if (done_count_ <= 1)
             {
+              alt_restores_ = SCM_EOL;
+              if (to_boolean (get_outlet ()->get_property ("timing")))
+                {
+                  for (SCM lst = get_outlet ()->get_property ("alternativeRestores");
+                       scm_is_pair (lst);
+                       lst = scm_cdr (lst))
+                    {
+                      SCM res = SCM_EOL;
+                      Context *t = get_outlet ()->where_defined (scm_car (lst),
+                                                                 &res);
+                      if (t)
+                        {
+                          alt_restores_ = scm_cons
+                            (scm_list_3 (t->self_scm (), scm_car (lst), res),
+                             alt_restores_);
+                        }
+                    }
+                }
+            }
+          else
+            {
+
               add_repeat_command (scm_list_n (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
 
               if (done_count_ - 1 < alt_count_)
                 add_repeat_command (ly_symbol2scm ("end-repeat"));
+
+              if (to_boolean (get_outlet ()->get_property ("timing")))
+                {
+                  for (SCM p = alt_restores_; scm_is_pair (p); p = scm_cdr (p))
+                    scm_apply_0 (ly_lily_module_constant ("ly:context-set-property!"),
+                                 scm_car (p));
+                }
             }
 
           if (done_count_ == 1 && alt_count_ < rep_count_)
-            repstr = "1.--" + to_string (rep_count_ - alt_count_ + done_count_) + ".";
+            repstr = "1.--" + ::to_string (rep_count_ - alt_count_ + done_count_) + ".";
 
           if (done_count_ <= alt_count_)
             add_repeat_command (scm_list_n (ly_symbol2scm ("volta"),
index 9c8547dd7d024f8e6b0f6b07d9683e7ede62dd94..dfaa47e12faf136a7a5e8ac63e345e3b9858141c 100644 (file)
@@ -169,7 +169,6 @@ contained staves are not connected vertically."
   \name RhythmicStaff
   \alias "Staff"
 
-  \override BarLine.bar-extent = #'(-2 . 2)
   \override VoltaBracket.staff-padding = #3
   \override StaffSymbol.line-count = #1
 
@@ -609,6 +608,7 @@ automatically when an output definition (a @code{\\score} or
   doubleRepeatType = #":..:"
   startRepeatType = #".|:"
   endRepeatType = #":|."
+  alternativeRestores = #'(measurePosition measureLength)
   barNumberVisibility = #first-bar-number-invisible-and-no-parenthesized-bar-numbers
   barNumberFormatter = #robust-bar-number-function
   clefTranspositionFormatter = #clef-transposition-markup
@@ -634,6 +634,8 @@ automatically when an output definition (a @code{\\score} or
   autoBeaming = ##t
   autoBeamCheck = #default-auto-beam-check
 
+  completionFactor = #unity-if-multimeasure
+
   scriptDefinitions = #default-script-alist
 
   pedalSustainStrings = #'("Ped." "*Ped." "*")
index bf738074cda120346f26b231c6854bd427ac72e7..7310b8d0ff880e3cc3dec444b7f5281bd21f2cc7 100644 (file)
@@ -221,6 +221,14 @@ barNumberCheck =
                                         "Barcheck failed got ~a expect ~a"
                                         cbn n))))))
 
+beamExceptions =
+#(define-scheme-function (parser location music) (ly:music?)
+   (_i "Extract a value suitable for setting
+@code{Timing.beamExceptions} from the given pattern with explicit
+beams in @var{music}.  A bar check @code{|} has to be used between
+bars of patterns in order to reset the timing.")
+   (extract-beam-exceptions music))
+
 bendAfter =
 #(define-event-function (parser location delta) (real?)
    (_i "Create a fall or doit of pitch interval @var{delta}.")
@@ -245,7 +253,15 @@ bookOutputSuffix =
 breathe =
 #(define-music-function (parser location) ()
    (_i "Insert a breath mark.")
-   (make-music 'BreathingEvent))
+   (make-music 'BreathingEvent
+     'midi-length
+     (lambda (len context)
+       ;;Shorten by half, or by up to a second, but always by a power of 2
+       (let* ((desired (min (ly:moment-main (seconds->moment 1 context))
+                            (* (ly:moment-main len) 1/2)))
+              (scale (inexact->exact (ceiling (/ (log desired) (log 1/2)))))
+              (breath (ly:make-moment (expt 1/2 scale))))
+         (ly:moment-sub len breath)))))
 
 clef =
 #(define-music-function (parser location type) (string?)
@@ -328,25 +344,30 @@ in a CueVoice oriented by @var{dir}.")
 
 
 displayLilyMusic =
-#(define-music-function (parser location music) (ly:music?)
+#(define-music-function (parser location port music) ((output-port?) ly:music?)
    (_i "Display the LilyPond input representation of @var{music}
-to the console.")
-   (newline)
-   (display-lily-music music parser)
+to @var{port}, defaulting to the console.")
+   (let ((port (or port (current-output-port))))
+     (newline port)
+     (display-lily-music music parser port))
    music)
 
 displayMusic =
-#(define-music-function (parser location music) (ly:music?)
-   (_i "Display the internal representation of @var{music} to the console.")
-   (newline)
-   (display-scheme-music music)
+#(define-music-function (parser location port music) ((output-port?) ly:music?)
+   (_i "Display the internal representation of @var{music} to
+@var{port}, default to the console.")
+   (let ((port (or port (current-output-port))))
+     (newline port)
+     (display-scheme-music music port))
    music)
 
 displayScheme =
-#(define-scheme-function (parser location expr) (scheme?)
-   (_i "Display the internal representation of @var{expr} to the console.")
-   (newline)
-   (display-scheme-music expr)
+#(define-scheme-function (parser location port expr) ((output-port?) scheme?)
+   (_i "Display the internal representation of @var{expr} to
+@var{port}, default to the console.")
+   (let ((port (or port (current-output-port))))
+     (newline port)
+     (display-scheme-music expr port))
    expr)
 
 
index 0a1ac2d3748e6de857e21e51b1d4801f8d6efe74..1a383607f1ea2c4d068edcf322f3cb5cf0ef2e6f 100644 (file)
@@ -26,6 +26,7 @@
   \name Staff
   \accepts Voice
   \accepts CueVoice
+  \accepts NullVoice
   \defaultchild Voice
 
   \consists "Staff_performer"
   \name "Devnull"
 }
 
+\context {
+  \type "Performer_Group"
+  \name NullVoice
+  \alias Staff
+  \alias Voice
+  %% needed for melismata
+  %% TODO: at least the tie performer likely does not work without the
+  %% Note_performer, but I don't know how to shut note output off in
+  %% MIDI.
+  \consists "Tie_performer"
+  \consists "Beam_performer"
+  \consists "Slur_performer"
+}
+
 \context {
   \Staff
   \name TabStaff
index 0cb37947e7294cb1f98b97a4a83dbe26d059ac31..3b3e39ed31d11b1ca86e8d5f7a80e0f214070023 100644 (file)
@@ -2,18 +2,10 @@
 
 \version "2.17.25"
 
-% code char abbreviations
-dashHat = "marcato"
-dashPlus = "stopped"
-dashDash = "tenuto"
-dashBang = "staccatissimo"
-dashLarger = "accent"
-dashDot = "staccato"
-dashUnderscore = "portato"
-
 harmonic = #(make-music 'HarmonicEvent)
 
-accent = #(make-articulation "accent")
+accent = #(make-articulation "accent"
+          'midi-extra-velocity 20)
 coda = #(make-articulation "coda")
 downbow = #(make-articulation "downbow")
 downmordent = #(make-articulation "downmordent")
@@ -26,10 +18,15 @@ lheel = #(make-articulation "lheel")
 lineprall = #(make-articulation "lineprall")
 longfermata = #(make-articulation "longfermata")
 ltoe = #(make-articulation "ltoe")
-marcato = #(make-articulation "marcato")
+marcato = #(make-articulation "marcato"
+           'midi-extra-velocity 40)
 mordent = #(make-articulation "mordent")
 open = #(make-articulation "open")
-portato = #(make-articulation "portato")
+
+portato = #(make-articulation "portato"
+           'midi-length
+           (lambda (len context)
+            (ly:moment-mul len (ly:make-moment 3/4))))
 prall = #(make-articulation "prall")
 pralldown = #(make-articulation "pralldown")
 prallmordent = #(make-articulation "prallmordent")
@@ -42,8 +39,17 @@ segno = #(make-articulation "segno")
 shortfermata = #(make-articulation "shortfermata")
 signumcongruentiae = #(make-articulation "signumcongruentiae")
 snappizzicato = #(make-articulation "snappizzicato")
-staccatissimo = #(make-articulation "staccatissimo")
-staccato = #(make-articulation "staccato")
+staccatissimo = #(make-articulation "staccatissimo"
+                 'midi-length
+                 (lambda (len context)
+                   (seconds->moment 1/8 context))
+                 'midi-extra-velocity 6)
+staccato = #(make-articulation "staccato"
+            'midi-length
+            (lambda (len context)
+              (moment-min (ly:moment-mul len (ly:make-moment 1/2))
+                          (seconds->moment 1/2 context)))
+            'midi-extra-velocity 4)
 stopped = #(make-articulation "stopped")
 tenuto = #(make-articulation "tenuto")
 thumb = \finger \markup \scale #(cons (magstep 5) (magstep 5))
@@ -55,3 +61,12 @@ upmordent = #(make-articulation "upmordent")
 upprall = #(make-articulation "upprall")
 varcoda = #(make-articulation "varcoda")
 verylongfermata = #(make-articulation "verylongfermata")
+
+% code char abbreviations
+dashHat = \marcato
+dashPlus = \stopped
+dashDash = \tenuto
+dashBang = \staccatissimo
+dashLarger = \accent
+dashDot = \staccato
+dashUnderscore = \portato
diff --git a/mf/common-modules-and-initialization.mf b/mf/common-modules-and-initialization.mf
new file mode 100644 (file)
index 0000000..764dbd6
--- /dev/null
@@ -0,0 +1,7 @@
+
+staffsize# := design_size * pt#;
+input debugging-settings;
+input feta-autometric;
+input feta-macros;
+mode_setup;
+input feta-params;
diff --git a/mf/debugging-settings.mf b/mf/debugging-settings.mf
new file mode 100644 (file)
index 0000000..e867713
--- /dev/null
@@ -0,0 +1,14 @@
+
+% Used for example to print glyphs with stafflines
+test := 0;
+
+if test = -1:
+        % TODO: what's this?  Seems to be broken...
+        mode := smoke;
+fi;
+
+% change this to 0.5 to have glyphs positioned on
+% staff spaces instead of stafflines in testing mode
+% (useful e.g. to check how accidentals visually interact
+% with stafflines in different configurations).
+stafflines_y_offset := 0;
diff --git a/mf/declare-autometric-parameters.mf b/mf/declare-autometric-parameters.mf
new file mode 100644 (file)
index 0000000..89bf921
--- /dev/null
@@ -0,0 +1,9 @@
+% TODO: i'm not sure if the name is right - is this declaring or something else?
+
+autometric_parameter ("staffsize", staffsize#);
+autometric_parameter ("stafflinethickness", stafflinethickness#);
+autometric_parameter ("staff_space", staff_space#);
+autometric_parameter ("linethickness", linethickness#);
+autometric_parameter ("black_notehead_width", black_notehead_width#);
+autometric_parameter ("ledgerlinethickness", ledgerlinethickness#);
+autometric_parameter ("blot_diameter", blot_diameter#);
index 11306724402b1424d5c947ab3bbac15a0538d61c..d2585a195414ca8c2a97da7f9da73c72f805bfb7 100644 (file)
 % along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 
-%
-% also show in other configuration wrt staff lines.
-%
-def draw_shifted_too =
-if test > 0:
-       fet_beginchar ("shifted too", "");
-               set_char_box (0, 0, 0, 0);
-               currentpicture := remember_pic;
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-enddef;
-
-
 %
 % Accidentals from various sources, notably
 %
@@ -56,1266 +41,9 @@ enddef;
 
 
 fet_begingroup ("accidentals");
-
-%
-% Draw an arrow
-%
-% * `stemslant' gives the direction of the stem's left boundary
-%   (needed for brushed stems, equals "up" for straight stems)
-% * `extend' is used to make the stem longer or shorter (if negative);
-%   different kinds of accidentals need different values here
-%
-def draw_arrow (expr attach, stemwidth, stemslant, extend, pointingdown) =
-begingroup;
-       save htip;  % tip height
-       save wwing; % wing `radius'
-       save angle_wing_bot, angle_wing_top, angle_tip;
-       save upshift;
-       clearxy;
-
-       wwing := 0.26 stemwidth;
-       htip := staff_space * 0.85 + stafflinethickness - wwing;
-
-       % `flip' is used to reflect the arrow vertically
-       % if arrow points downward
-       transform flip;
-       if pointingdown:
-               flip = identity reflectedabout (origin, right);
-       else:
-               flip = identity;
-       fi;
-
-       z1 = attach shifted (-stemwidth / 2, 0);
-       upshift := max (0, wwing + 0.1 staff_space + extend);
-       z2 = z1 shifted (((unitvector stemslant)
-                         scaled upshift) transformed flip);
-
-       z7 = attach shifted ((stemwidth/2),0);
-       z6 = z7 shifted (((unitvector (-xpart stemslant, ypart stemslant))
-                         scaled upshift) transformed flip);
-       z2 - z3 = ( 0.38 staff_space, 0.05 htip) transformed flip;
-       z6 - z5 = (-0.38 staff_space, 0.05 htip) transformed flip;
-
-       z4 = attach shifted ((-0.2 stemwidth, upshift + htip)
-                            transformed flip);
-       z4'= attach shifted (( 0.2 stemwidth, upshift + htip)
-                            transformed flip);
-
-       % `angle_wing_bot' is the angle at which the arc
-       % from z2 to z3a enters z3a
-       % `angle_wing_top' is the angle at which the arc
-       % from z3b to z4 leaves z3b
-       % `angle_tip' is the angle at which the arc
-       % from z4 to z4' leaves z4
-       angle_wing_bot = 30;
-       angle_wing_top = 55;
-       angle_tip = 68;
-
-       z3a = z3 shifted ((((dir angle_wing_bot) rotated -90)
-                          scaled wwing) transformed flip);
-       z3b = z3 shifted ((((dir angle_wing_top) rotated 90)
-                          scaled wwing) transformed flip);
-
-       z5a = z5 shifted ((((dir (180 - angle_wing_bot)) rotated 90)
-                          scaled wwing) transformed flip);
-       z5b = z5 shifted ((((dir (180 - angle_wing_top)) rotated -90)
-                          scaled wwing) transformed flip);
-
-       % Draw the arrow
-       pickup pencircle scaled 1;
-       fill z1
-            -- z2{stemslant transformed flip}
-            .. {(-dir angle_wing_bot) transformed flip}z3a
-            .. z3b{(dir angle_wing_top) transformed flip}
-            .. z4{(dir angle_tip) transformed flip}
-            .. z4'{(dir (-angle_tip)) transformed flip}
-            .. {(dir (-angle_wing_top)) transformed flip}z5b
-            .. z5a{(-dir (-angle_wing_bot)) transformed flip}
-            .. z6{((-stemslant) reflectedabout (origin, up)) transformed flip}
-            -- z7
-            -- cycle;
-
-       labels (range 0 thru 7, 4', 3a, 3b, 5a, 5b);
-endgroup;
-enddef;
-
-save remember_pic;
-picture remember_pic;
-
-save sharp_beamheight;
-sharp_beamheight# := 0.3 staff_space# + stafflinethickness#;
-
-%
-% The beams of most sharps have horizontal endings (as if drawn with
-% a square pen).  [Wanske] does not mention this, so we'll just ignore
-% this fact.
-%
-
-def draw_meta_sharp (expr width, offset) =
-       save beamwidth, beamslope;
-       save ne, nw_dist;
-       pair ne, nw_dist;
-
-       beamwidth := width;
-
-       define_whole_vertical_blacker_pixels (sharp_beamheight);
-
-       clearxy;
-
-       beamslope = sharp_beamheight / beamwidth;
-
-       pickup pencircle scaled 2 blot_diameter;
-
-       rt x2 - lft x1 = beamwidth;
-       z2 = z1 + whatever * (beamwidth, sharp_beamheight);
-       .5 [z1, z3] = (.5 w, offset);
-       x3 = x2;
-       top y2 - bot y3 = sharp_beamheight;
-       x4 = x1;
-       top y1 - bot y4 = sharp_beamheight;
-
-       ne = unitvector (z2 - z1);
-       nw_dist = (ne rotated 90) * blot_diameter;
-
-       fill lft z1{up}
-            ... (z1 + nw_dist){ne}
-            -- (z2 + nw_dist){ne}
-            ... rt z2{down}
-            -- rt z3{down}
-            ... (z3 - nw_dist){-ne}
-            -- (z4 - nw_dist){-ne}
-            ... lft z4{up}
-            -- cycle;
-
-       labels (1, 2, 3, 4);
-enddef;
-
-
-def draw_sharp(expr arrowup, arrowdown) =
-       save stem, stemx, stemwidth;
-       save outer_space, interbeam;
-       save stemlength, extendleft, extendright, height, depth;
-
-       stemwidth# := stafflinethickness# + .05 staff_space#;
-       define_whole_blacker_pixels (stemwidth);
-
-       interbeam := 1.05 staff_space_rounded;
-
-       stemlength# := 1.5 staff_space#;
-       define_pixels (stemlength);
-
-       height# = stemlength#;
-       depth# = stemlength#;
-       extendright# = 0;
-       extendleft# = 0;
-       if arrowup:
-               height# := height# + 1.2 staff_space#;
-               extendright# := extendright# + 1.5 stafflinethickness#;
-       fi;
-       if arrowdown:
-               depth# := depth# + 1.2 staff_space#;
-               extendleft# := extendleft# + 1.5 stafflinethickness#;
-       fi;
-       define_pixels (extendleft, extendright);
-       set_char_box (extendleft#, 1.1 staff_space#, depth#, height#);
-
-       stem := 7 / 16 * w;
-       stemx := hround stem;
-       outer_space := hround ((w - stemx - stemwidth) / 2);
-
-       w := 2 outer_space + stemx + stemwidth;
-       d := d - feta_space_shift;
-
-       draw_meta_sharp (w, -.5 interbeam);
-       draw_meta_sharp (w, -.5 interbeam + vround interbeam);
-
-       % expand the charbox so that it encloses the whole arrow;
-       % this must not happen earlier because some commands above
-       % still rely on the old width
-       w := w + extendright;
-
-       pickup pencircle scaled stemwidth;
-
-       lft x5 = lft x6 = outer_space;
-       lft x7 = lft x8 = outer_space + stemx;
-       bot y5 = -stemlength;
-       top y6 = vround (1.5 staff_space - stem * beamslope);
-       bot y7 = -top y6 + feta_space_shift;
-       top y8 = stemlength;
-
-       labels (5, 6, 7, 8);
-
-       draw_gridline (z5, z6, stemwidth);
-       draw_gridline (z7, z8, stemwidth);
-
-       if arrowup:
-               draw_arrow (z8, stemwidth, up,
-                           stafflinethickness / 2 + stemwidth / 2, false);
-       fi;
-       if arrowdown:
-               draw_arrow (z5, stemwidth, up,
-                           stafflinethickness / 2 + stemwidth / 2, true);
-       fi;
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-enddef;
-
-
-fet_beginchar ("Sharp", "sharp");
-       draw_sharp (false, false);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Sharp (arrow up)", "sharp.arrowup");
-       draw_sharp (true, false);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Sharp (arrow down)", "sharp.arrowdown");
-       draw_sharp (false, true);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Sharp (arrows up and down)", "sharp.arrowboth");
-       draw_sharp (true, true);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("1/2 Sharp", "sharp.slashslash.stem");
-       save stem, stemwidth;
-       save outer_space, interbeam;
-
-       stemwidth# := stafflinethickness# + .05 staff_space#;
-       define_whole_blacker_pixels (stemwidth);
-
-       interbeam := 1.05 staff_space_rounded;
-
-       set_char_box (0, 0.7 staff_space#,
-                     1.5 staff_space#, 1.5 staff_space#);
-
-       stem := 7 / 16 * w;
-       outer_space := hround ((w - stemwidth) / 2);
-
-       w := 2 outer_space + stemwidth;
-       d := d - feta_space_shift;
-
-       draw_meta_sharp (w, -.5 interbeam);
-       draw_meta_sharp (w, -.5 interbeam + vround interbeam);
-
-       pickup pencircle scaled stemwidth;
-
-       lft x5 = lft x6 = outer_space;
-       top y6 = vround (1.5 staff_space - .5 stem);
-       bot y5 = -top y6 + feta_space_shift;
-
-       labels (5, 6);
-
-       draw_gridline (z5, z6, stemwidth);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Sharp (3 beams)", "sharp.slashslashslash.stemstem");
-       save stem, stemx, stemwidth;
-       save outer_space, interbeam;
-       save sharp_beamheight;
-
-       sharp_beamheight# := 0.22 staff_space# + stafflinethickness#;
-
-       stemwidth# := stafflinethickness# + .05 staff_space#;
-       define_whole_blacker_pixels (stemwidth);
-
-       interbeam := 1.2 staff_space_rounded;
-
-       set_char_box (0, 1.1 staff_space#,
-                     1.5 staff_space#, 1.5 staff_space#);
-
-       stem := 7 / 16 * w;
-       stemx := hround stem;
-       outer_space := hround ((w - stemx - stemwidth) / 2);
-
-       w := 2 outer_space + stemx + stemwidth;
-       d := d - feta_space_shift;
-
-       draw_meta_sharp (.88 w, -.5 interbeam);
-       draw_meta_sharp (.88 w, -.5 interbeam + vround interbeam);
-       sharp_beamheight# := 1/.88 sharp_beamheight#;
-       draw_meta_sharp (w, 0);
-
-       pickup pencircle scaled stemwidth;
-
-       lft x5 = lft x6 = outer_space;
-       lft x7 = lft x8 = outer_space + stemx;
-       bot y5 = -d;
-       top y6 = vround (1.5 staff_space - stem * beamslope);
-       bot y7 = -top y6 + feta_space_shift;
-       top y8 = h;
-
-       labels (5, 6, 7, 8);
-
-       draw_gridline (z5, z6, stemwidth);
-       draw_gridline (z7, z8, stemwidth);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("1/2 Sharp (3 beams)", "sharp.slashslashslash.stem");
-       save stem, stemx, stemwidth;
-       save outer_space, interbeam;
-       save sharp_beamheight;
-
-       sharp_beamheight# := 0.22 staff_space# + stafflinethickness#;
-
-       stemwidth# := stafflinethickness# + .05 staff_space#;
-       define_whole_blacker_pixels (stemwidth);
-
-       interbeam := 1.2 staff_space_rounded;
-
-       set_char_box (0, 0.95 staff_space#,
-                     1.3 staff_space#, 1.3 staff_space#);
-
-       stem := 7 / 16 * w;
-       outer_space := hround ((w - stemwidth) / 2);
-
-       w := 2 outer_space + stemwidth;
-       d := d - feta_space_shift;
-
-       draw_meta_sharp (.8 w, -.5 interbeam);
-       draw_meta_sharp (.8 w, -.5 interbeam + vround interbeam);
-       sharp_beamheight# := 1/.8 sharp_beamheight#;
-       draw_meta_sharp (w, 0);
-
-       pickup pencircle scaled stemwidth;
-
-       lft x5 = lft x6 = outer_space;
-       top y6 = vround (1.5 staff_space - .5 stem);
-       bot y5 = -top y6 + feta_space_shift;
-       labels (5, 6);
-
-       draw_gridline (z5, z6, stemwidth);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("3/4 Sharp", "sharp.slashslash.stemstemstem");
-       save stem, stemx, stemwidth;
-       save outer_space, interbeam;
-
-       stemwidth# := stafflinethickness# + .05 staff_space#;
-       define_whole_blacker_pixels (stemwidth);
-
-       interbeam := 1.05 staff_space_rounded;
-
-       set_char_box (0, 1.6 staff_space#,
-                     1.5 staff_space#, 1.5 staff_space#);
-
-       stem := 9 / 32 * w;
-       stemx := hround stem;
-       outer_space := hround ((w - 2 stemx - stemwidth) / 2);
-
-       w := 2 outer_space + 2 stemx + stemwidth;
-       d := d - feta_space_shift;
-
-       draw_meta_sharp (w, -.5 interbeam);
-       draw_meta_sharp (w, -.5 interbeam + vround interbeam);
-
-       pickup pencircle scaled stemwidth;
-
-       lft x5 = lft x6 = outer_space;
-       lft x7 = lft x8 = outer_space + stemx;
-       lft x9 = lft x10 = outer_space + 2 stemx;
-       bot y5 = -d;
-       top y6 = vround (1.5 staff_space - 2 stem * beamslope);
-       bot y9 = -top y6 + feta_space_shift;
-       top y10 = h;
-       y7 = .5 [y5, y9];
-       y8 = .5 [y6, y10];
-
-       labels (5, 6, 7, 8, 9, 10);
-
-       draw_gridline (z5, z6, stemwidth);
-       draw_gridline (z7, z8, stemwidth);
-       draw_gridline (z9, z10, stemwidth);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-%
-% The stems of the natural are brushed (at least, in Barenreiter SCS)
-%
-
-def draw_natural (expr arrowup, arrowdown) =
-       save stemwidth, top_stem_thick;
-       save ne, pat_top, pat_bottom;
-       save depth, height, extendleft, extendright, stemlength;
-       save brush_scale_up, brush_scale_down;
-       pair ne;
-       path pat_top, pat_bottom;
-
-       top_stem_thick# = stafflinethickness# + .10 staff_space#;
-       stemwidth# = 0.09 staff_space# + .5 stafflinethickness#;
-       define_whole_blacker_pixels (top_stem_thick, stemwidth);
-
-       stemlength# = 1.5 staff_space#;
-       define_pixels (stemlength);
-
-       height# = stemlength#;
-       depth# = stemlength#;
-       extendleft# = 0;
-       extendright# = 0;
-       if arrowup:
-               extendleft# := 3 stafflinethickness#;
-               height# := height# + 1.2 staff_space#;
-       fi;
-       if arrowdown:
-               extendright# := 3.15 stafflinethickness#;
-               depth# := depth# + 1.2 staff_space#;
-       fi;
-       define_pixels (extendright);
-
-       set_char_box (extendleft#, 2/3 staff_space#, depth#, height#);
-
-       d := d - feta_space_shift;
-
-       pickup pencircle scaled stemwidth;
-
-       brush_scale_up := 1.0;
-       brush_scale_down := 1.0;
-       % to look nice, arrowed stems must be less brushed
-       if arrowup:
-               brush_scale_up := 0.85;
-       fi;
-       if arrowdown:
-               brush_scale_down := 0.85;
-       fi;
-
-       penpos1 (top_stem_thick, 0);
-       penpos3 (top_stem_thick, 0);
-       penpos2 (stemwidth, 0);
-       penpos4 (stemwidth, 0);
-       % z1' and z3' are needed for the arrowed accidentals
-       penpos1' (top_stem_thick * brush_scale_up, 0);
-       penpos3' (top_stem_thick * brush_scale_down, 0);
-
-       x2r = w;
-       x4l = 0;
-       x3 = x3' = x2;
-       x1 = x1' = x4;
-
-       y1 = y1' = stemlength;
-       y3 = y3' = -stemlength;
-       top y2 = vround (staff_space - 3/2 stafflinethickness);
-       y4 = -y2 + feta_space_shift;
-
-       pat_bottom := z4r{z4r - z1r}
-                     .. bot z4
-                     .. z4l{z1l - z4l};
-       fill simple_serif (z1'l, z1'r, -30)
-            -- pat_bottom
-            -- cycle;
-
-       pat_top := z2r{z2r - z3r}
-                  .. top z2
-                  .. z2l{z3l - z2l};
-       fill simple_serif (z3'l, z3'r, 30)
-            -- pat_top
-            -- cycle;
-
-       ne = (x2 - x4, stafflinethickness);
-
-       z11' = z3l + whatever * (z2l - z3l);
-       y11' = vround (.5 (staff_space - stafflinethickness));
-       z11 = z11' + whatever * ne;
-       x11 = x12;
-       z12 = directionpoint -ne of pat_top;
-       z13 = z12 + whatever * ne;
-       x13 = x1;
-       z14 = z11 + whatever * ne;
-       x14 = x1;
-
-       z21' = z4r + whatever * (z1r - z4r);
-       y21' = -y11' + feta_space_shift;
-       z21 = z21' + whatever * ne;
-       x21 = x22;
-       z22 = directionpoint -ne of pat_bottom;
-       z23 = z22 + whatever * ne;
-       x23 = x3;
-       z24 = z21 + whatever * ne;
-       x24 = x3;
-
-       fill z11
-            -- z12
-            -- z13
-            -- z14
-            -- cycle;
-       fill z21
-            -- z22
-            -- z23
-            -- z24
-            -- cycle;
-
-       penlabels (1, 1', 2, 3, 3', 4);
-       labels (11, 11', 12, 13, 14, 21, 21', 22, 23, 24);
-
-       if arrowup:
-               draw_arrow (z1, top_stem_thick * brush_scale_up,
-                           z1'l - z4l, stafflinethickness / 2, false);
-       fi;
-       if arrowdown:
-               draw_arrow (z3, top_stem_thick * brush_scale_down,
-                           z2r - z3'r, stafflinethickness / 2, true);
-               w := w + extendright;
-       fi;
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-enddef;
-
-
-fet_beginchar ("Natural", "natural");
-       draw_natural (false, false);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Natural (arrow up)", "natural.arrowup");
-       draw_natural (true, false);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Natural (arrow down)", "natural.arrowdown");
-       draw_natural (false, true);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Natural (arrows up and down)", "natural.arrowboth");
-       draw_natural (true, true);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-%
-% Dedicated to my mom.    (3/10/97)
-%
-% Mamma, ik hou van je; kom je alsjeblieft terug?
-%    -- HW
-%
-%
-% TODO: remove crook_fatness
-% TODO: document, simplify!
-%
-
-def draw_meta_flat (expr xcenter, w, crook_fatness, arrowup, arrowdown) =
-       save crook_thinness;
-       save bottom_overshoot, bot_crook_dir;
-       save top_stem_thick, top_stem_thick_orig;
-       save bottom_stem_thick, hair, smaller_hole;
-       save top_crook_thinness;
-       save zwiep;
-       save center;
-       pair center, bot_crook_dir;
-       save clearing, clearing_orig;
-
-       clearxy;
-
-       % the stem shouldn't reach the top staff line.
-       %% TODO: should take from height.
-       %
-       % TODO: parameterize this
-       %
-       if w >= 0.75 staff_space:
-               smaller_hole = 0.35 stafflinethickness;
-       else:
-               smaller_hole = 0;
-       fi;
-       crook_thinness = .7 stafflinethickness + .06 staff_space;
-       top_crook_thinness = 1 stafflinethickness + .065 staff_space;
-       clearing = 1.7 stafflinethickness;
-       clearing_orig = clearing;
-       if arrowup:
-               clearing := 0.5 staff_space;
-       fi;
-       bottom_overshoot = stafflinethickness;
-
-       bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
-       top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
-       top_stem_thick_orig# = top_stem_thick#;
-       if arrowup:
-               % to look nice, arrowed stems should be less brushed
-               top_stem_thick# := top_stem_thick# * 0.8;
-       fi;
-       define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick,
-                                    top_stem_thick_orig);
-
-       if odd (top_stem_thick - bottom_stem_thick):
-               top_stem_thick := top_stem_thick - 1;
-       fi;
-       if odd (top_stem_thick_orig - bottom_stem_thick):
-               top_stem_thick_orig := top_stem_thick_orig - 1;
-       fi;
-
-       center = (xcenter, 0);
-
-       x1l = hround (xcenter - .5 top_stem_thick);
-       y1 = vround (2 staff_space - clearing);
-       x2l = hround (xcenter - .5 bottom_stem_thick);
-       y2 = -.5 staff_space - .5 stafflinethickness;
-       % z16 and the `*_orig' variables are needed for arrowed accidentals
-       % because their inner part should be unchanged from plain ones but
-       % the points z3l, z3r, and z10 depend on values that are different
-       % for arrowed accidentals
-       x16l = hround (xcenter -.5 top_stem_thick_orig);
-       y16 = vround (2 staff_space - clearing_orig);
-
-       penpos1 (top_stem_thick, 0);
-       penpos16 (top_stem_thick_orig, 0);
-       penpos2 (bottom_stem_thick, 0);
-
-       y3l = vfloor ((staff_space - stafflinethickness) / 2);
-       z3l = whatever [z2r, z1r];
-       z3r = .3 [z2r,
-                 (z16r shifted (0, clearing_orig - 1.7 stafflinethickness))]
-             + (smaller_hole, 0);
-       x3r := hceiling x3r;
-
-       % we insert z3l to get better conversion with mf2pt1
-       fill simple_serif (z1r, z1l, 30)
-            -- z2l
-            -- z2r
-            -- z3l
-            -- cycle;
-
-       z10 = whatever [z2r, z16r] + (smaller_hole, 0);
-       y10 = -1/10 staff_space;
-       x10 := hceiling x10;
-
-       x11 = xcenter + bottom_overshoot / 3;
-       y11 = -vround (.5 (staff_space + stafflinethickness)
-                      + bottom_overshoot);
-
-       x2a = 0.2[x2r, x7];
-       y2a = 1.5[y2, y11];
-
-       penpos4 (whatever, 53);
-
-       y4l - y4r = top_crook_thinness;
-       y5r = .15 staff_space;
-       x5l = hround (w + xcenter);
-       y4 = staff_space / 2;
-       x4r = .45 [x5r, x3r];
-       y4l := vround y4l;
-
-       penpos5 (crook_fatness, -175);
-
-       bot_crook_dir = unitvector ((x5l, 0) - z11);
-       z8 = z11 + whatever * bot_crook_dir;
-       y8 = -staff_space / 2;
-
-       z7 = z8
-            + whatever * bot_crook_dir
-            + crook_thinness * (bot_crook_dir rotated 90);
-       x7 = .1 [x3r, x8];
-
-       unfill z3r{z3r - z10}
-              .. z4r{right}
-              .. z5r{down}
-              .. z7{-bot_crook_dir}
-              & z7
-              .. z10{z3r - z10}
-              -- cycle;
-
-       if arrowdown:
-               fill z2l{down}
-                    .. z2a{up}
-                    .. z8{bot_crook_dir}
-                    .. z5l{up}
-                    .. z4l{left}
-                    .. z3l
-                    -- cycle;
-       else:
-               fill z2l{down}
-                    .. z11{right}
-                    .. z8{bot_crook_dir}
-                    .. z5l{up}
-                    .. z4l{left}
-                    .. z3l
-                    -- cycle;
-       fi;
-
-       if arrowup:
-               draw_arrow (z1, top_stem_thick, z1l - z2l,
-                           0.5 stafflinethickness, false);
-       fi;
-       if arrowdown:
-               draw_arrow ((0.5 [x2l, x2a], y2), x2a - x2l, up,
-                           staff_space / 2, true);
-       fi;
-enddef;
-
-
-def draw_arrowed_meta_flat (expr xcenter, width, crook_fatness,
-                                arrowup, arrowdown) =
-       save depth, height, extendleft;
-
-       depth# = 0.6 staff_space#;
-       height# = 1.9 staff_space#;
-       extendleft# := 1.2 stafflinethickness#;
-       if arrowup:
-               extendleft# := 3.45 stafflinethickness#;
-               height# := height# + 0.8 staff_space#;
-       fi;
-       if arrowdown:
-               extendleft# := 3.45 stafflinethickness#;
-               depth# := depth# + 1.6 staff_space#;
-       fi;
-
-       set_char_box (extendleft#, width, depth#, height#);
-       draw_meta_flat(xcenter, w, crook_fatness, arrowup, arrowdown);
-enddef;
-
-%
-% unfortunately, 600dpi is not enough to show the brush of the stem.
-%
-
-fet_beginchar ("Flat", "flat");
-       draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
-                               false, false);
-       penlabels (range 0 thru 11);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Flat (arrow up)", "flat.arrowup");
-       draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
-                               true, false);
-       penlabels (range 0 thru 23);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Flat (arrow down)", "flat.arrowdown");
-       draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
-                               false, true);
-       penlabels (range 0 thru 23);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Arrowed Flat (arrow up and down)", "flat.arrowboth");
-       draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
-                               true, true);
-       penlabels (range 0 thru 23);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Flat (slashed)", "flat.slash");
-       set_char_box (.4 staff_space#, .8 staff_space#,
-                     0.6 staff_space#, 1.9 staff_space#);
-
-       draw_meta_flat (0, w, 0.31 staff_space, false, false);
-
-       clearxy;
-
-       save slope, slash_width;
-       slope = 0.5;
-       slash_width = w;
-
-       z11 = (0, h / 2);
-       z12 = z11 - (slash_width, slash_width * slope) / 2;
-       z13 = z11 + (slash_width, slash_width * slope) / 2;
-       penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
-       penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
-
-       z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
-       z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
-
-       fill z13r
-            .. z15
-            .. z13l
-            -- z12l
-            .. z14
-            .. z12r
-            -- z13r
-            .. cycle;
-
-       penlabels (12, 13);
-       labels (14, 15);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-fet_beginchar ("Flat (slashed twice)", "flat.slashslash");
-       set_char_box (.4 staff_space#, .8 staff_space#,
-                     0.6 staff_space#, 1.9 staff_space#);
-
-       draw_meta_flat (0, w, 0.31 staff_space, false, false);
-
-       clearxy;
-
-       save slope, slash_width;
-       slope = 0.5;
-       slash_width = w;
-
-       z11 = (0, 5/12 h);
-       z12 = z11 - (slash_width, slash_width * slope) / 2;
-       z13 = z11 + (slash_width, slash_width * slope) / 2;
-       penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
-       penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
-
-       z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
-       z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
-
-       fill z13r
-            .. z15
-            .. z13l
-            -- z12l
-            .. z14
-            .. z12r
-            -- z13r
-            .. cycle;
-
-       penlabels (12, 13);
-       labels (14, 15);
-
-       z21 = (0, 2/3 h);
-       z22 = z21 - (slash_width, slash_width * slope) / 2;
-       z23 = z21 + (slash_width, slash_width * slope) / 2;
-       penpos22 (1.5 stafflinethickness, angle (z23 - z22) - 90);
-       penpos23 (1.5 stafflinethickness, angle (z23 - z22) - 90);
-
-       z24 = z22 - .75 stafflinethickness * unitvector (z23 - z22);
-       z25 = z23 + .75 stafflinethickness * unitvector (z23 - z22);
-
-       fill z23r
-            .. z25
-            .. z23l
-            -- z22l
-            .. z24
-            .. z22r
-            -- z23r
-            .. cycle;
-
-       penlabels (22, 23);
-       labels (24, 25);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-fet_beginchar ("Flatflat (mirrored)", "mirroredflat.flat");
-       set_char_box (0, 1.6 staff_space#,
-                     0.6 staff_space#, 1.9 staff_space#);
-
-       % This is a modified version of `draw_meta_flat'.
-
-       save crook_thinness, crook_fatness;
-       save bottom_overshoot, bot_crook_dir;
-       save top_stem_thick, bottom_stem_thick, hair, smaller_hole;
-       save top_crook_thinness;
-       save zwiep;
-       save center;
-       pair center, bot_crook_dir;
-       save clearing, wid;
-       save pat;
-       path pat;
-
-       clearxy;
-
-       wid = w / 2;
-
-       % the stem shouldn't reach the top staff line.
-       %% TODO: should take from height.
-       %
-       % TODO: parameterize this
-       %
-       if wid >= 0.75 staff_space:
-               smaller_hole = 0.35 stafflinethickness;
-       else:
-               smaller_hole = 0;
-       fi;
-       clearing = 1.7 stafflinethickness;
-       crook_thinness = .7 stafflinethickness + .06 staff_space;
-       crook_fatness = 0.31 staff_space;
-       top_crook_thinness = 1 stafflinethickness + .065 staff_space;
-       bottom_overshoot = stafflinethickness;
-
-       bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
-       top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
-       define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick);
-
-       if odd (top_stem_thick - bottom_stem_thick):
-               top_stem_thick := top_stem_thick - 1;
-       fi;
-
-       center = (0, 0);
-
-       x1l = hround (-.5 top_stem_thick);
-       y1 = vround (2 staff_space - clearing);
-       x2l = hround (-.5 bottom_stem_thick);
-       y2 = -.5 staff_space - .5 stafflinethickness;
-
-       penpos1 (top_stem_thick, 0);
-       penpos2 (bottom_stem_thick, 0);
-
-       y3l = vfloor ((staff_space - stafflinethickness) / 2);
-       z3l = whatever [z2r, z1r];
-       z3r = .3 [z2r, z1r] + (smaller_hole, 0);
-       x3r := hceiling x3r;
-
-       z10 = whatever [z2r, z1r] + (smaller_hole, 0);
-       y10 = -1/10 staff_space;
-       x10 := hceiling x10;
-
-       x11 = bottom_overshoot / 3;
-       y11 = -vround (.5 (staff_space + stafflinethickness)
-                      + bottom_overshoot);
-
-       penpos4 (whatever, 53);
-
-       y4l - y4r = top_crook_thinness;
-       y5r = .15 staff_space;
-       x5l = hround (wid);
-       y4 = staff_space / 2;
-       x4r = .45 [x5r, x3r];
-       y4l := vround y4l;
-
-       penpos5 (crook_fatness, -175);
-
-       bot_crook_dir = unitvector ((x5l, 0) - z11);
-       z8 = z11 + whatever * bot_crook_dir;
-       y8 = -staff_space / 2;
-
-       z7 = z8
-            + whatever * bot_crook_dir
-            + crook_thinness * (bot_crook_dir rotated 90);
-       x7 = .1 [x3r, x8];
-
-       pat := z3r{z3r - z10}
-              .. z4r{right}
-              .. z5r{down}
-              .. z7{-bot_crook_dir}
-              & z7
-              .. z10{z3r - z10}
-              -- cycle;
-       unfill pat;
-       unfill pat xscaled -1;
-
-       pat := z11{right}
-              .. z8{bot_crook_dir}
-              .. z5l{up}
-              .. z4l{left}
-              .. z3l;
-       fill pat
-            -- simple_serif (z1r, z1l, 30)
-            -- reverse pat xscaled -1 shifted (-feta_eps, 0)
-            -- cycle;
-
-       currentpicture := currentpicture shifted (w/2, 0);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Semi flat", "mirroredflat");
-       set_char_box (1.2 stafflinethickness#, .8 staff_space#,
-                     0.6 staff_space#, 1.9 staff_space#);
-
-       draw_meta_flat (0, w, 0.31 staff_space, false, false);
-       currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
-fet_endchar;
-
-
-fet_beginchar ("Semi flat", "mirroredflat.backslash");
-       set_char_box (.4 staff_space#, .8 staff_space#,
-                     0.6 staff_space#, 1.9 staff_space#);
-
-       draw_meta_flat (0, w, 0.31 staff_space, false, false);
-
-       clearxy;
-
-       save slope, slash_width;
-       slope = 0.5;
-       slash_width = w;
-
-       z11 = (0, h / 2);
-       z12 = z11 - (slash_width, slash_width * slope) / 2;
-       z13 = z11 + (slash_width, slash_width * slope) / 2;
-       penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
-       penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
-
-       z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
-       z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
-
-       fill z13r
-            .. z15
-            .. z13l
-            -- z12l
-            .. z14
-            .. z12r
-            -- z13r
-            .. cycle;
-
-       currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
-
-       labels (1, 2, 3);
-fet_endchar;
-
-
-fet_beginchar ("Double Flat", "flatflat");
-       save left_wid, overlap, right_wid;
-
-       left_wid = .7;
-       right_wid = .8;
-       overlap = .05;
-
-       set_char_box (1.2 stafflinethickness#,
-                     (left_wid + right_wid - overlap) * staff_space#,
-                     .6 staff_space#, 1.9 staff_space#);
-       draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space,
-                       false, false);
-       draw_meta_flat (hround ((left_wid - overlap) * staff_space),
-                       right_wid * staff_space, 1/3 staff_space,
-                       false, false);
-fet_endchar;
-
-
-fet_beginchar ("3/4 Flat", "flatflat.slash");
-       save left_wid, overlap, right_wid;
-
-       left_wid = .7;
-       right_wid = .8;
-       overlap = .05;
-
-       set_char_box (1.2 stafflinethickness#,
-                     (left_wid + right_wid - overlap) * staff_space#,
-                     .6 staff_space#, 1.9 staff_space#);
-       draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space,
-                       false, false);
-       draw_meta_flat (hround ((left_wid - overlap) * staff_space),
-                       right_wid * staff_space, 1/3 staff_space,
-                       false, false);
-
-       %% maybe we should clip part of the stems?
-       %% or make the 1st flat smaller?
-       %% or reverse it?
-       pickup pencircle scaled 2 stafflinethickness;
-
-       z12 = round (-.25 w - b, .55 staff_space) + feta_offset;
-       z13 = round (.75 w, 1.45 staff_space) + feta_offset;
-       penpos12 (2 stafflinethickness, angle (z13 - z12) - 90);
-       penpos13 (2 stafflinethickness, angle (z13 - z12) - 90);
-
-       z14 = z12 - stafflinethickness * unitvector (z13 - z12);
-       z15 = z13 + stafflinethickness * unitvector (z13 - z12);
-
-       fill z13r
-            .. z15
-            .. z13l
-            -- z12l
-            .. z14
-            .. z12r
-            -- z13r
-            .. cycle;
-
-       penlabels (12, 13);
-       labels (14, 15);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Double Sharp", "doublesharp");
-       save klaverblad, klaversteel;
-       save pat;
-       path pat;
-
-       klaversteel = 1/15 staff_space;
-       klaverblad = .4 staff_space - .5 stafflinethickness;
-
-       set_char_box (0, staff_space#, .5 staff_space#, .5 staff_space#);
-
-       z1 = (klaversteel, 0);
-       z2 = (w / 2 - klaverblad / 10, h - klaverblad);
-       z3 = (w / 2, h);
-       z4 = z2 reflectedabout ((0, 0), (1, 1));
-       z5 = z1 reflectedabout ((0, 0), (1, 1));
-
-       labels (1, 2, 3, 4, 5);
-
-       pickup pencircle scaled blot_diameter;
-
-       x2 := hfloor (rt x2) - blot_diameter / 2;
-       x3 := hfloor (rt x3) - blot_diameter / 2;
-       y3 := vfloor (top y3) - blot_diameter / 2;
-       y4 := vfloor (top y4) - blot_diameter / 2;
-
-       pat = (rt z1){dir45}
-             .. {right}(bot z2)
-             .. rt z2
-             -- rt z3{z3 - z2}
-             .. top z3{z4 - z3}
-             -- top z4{z4 - z3}
-             .. (lft z4){down}
-             .. {dir 225}(top z5);
-       pat := pat
-              -- reverse pat xscaled -1 shifted (-feta_eps, 0);
-
-       % assure symmetry -- it's more important to center the glyph on the
-       % staff line than centering it between staff lines, so we use
-       % feta_shift, not feta_space_shift.
-       h := h + feta_shift;
-
-       fill pat shifted (0, feta_shift)
-            -- reverse pat yscaled -1 shifted (0, -feta_eps)
-            -- cycle;
-
-       % ugh
-       currentpicture := currentpicture shifted (hround (w / 2), 0);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-def draw_paren =
-       save leftindent;
-
-       leftindent := .2 staff_space;
-
-       set_char_box (0, .5 staff_space# + stafflinethickness#,
-                     staff_space#, staff_space#);
-
-       d := d - feta_shift;
-
-       z1 = (leftindent, h);
-       z2 = (w - stafflinethickness, .5 (h - d));
-       z3 = (leftindent, -d);
-
-       penpos1 (stafflinethickness, 35);
-       penpos2 (.1 staff_space + stafflinethickness, 0);
-       penpos3 (stafflinethickness, -35);
-
-       fill z2l{down}
-            .. simple_serif (z3l, z3r, 90)
-            .. z2r{up}
-            .. simple_serif (z1r, z1l, 90)
-            .. z2l{down}
-            -- cycle;
-enddef;
-
-
-fet_beginchar ("Right Parenthesis", "rightparen");
-       draw_paren;
-       penlabels (1, 2, 3);
-
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
-fet_endchar;
-
-
-draw_shifted_too;
-
-
-fet_beginchar ("Left Parenthesis", "leftparen");
-       draw_paren;
-
-       currentpicture := currentpicture xscaled -1;
-
-       set_char_box (charwd, charbp, chardp, charht);
-fet_endchar;
-
+       input feta-arrow;
+       input feta-sharps;
+       input feta-naturals;
+       input feta-flats;
+       input feta-parenthesis;
 fet_endgroup ("accidentals");
diff --git a/mf/feta-alphabet-generic.mf b/mf/feta-alphabet-generic.mf
new file mode 100644 (file)
index 0000000..047f08b
--- /dev/null
@@ -0,0 +1,19 @@
+% This file is part of LilyPond, the GNU music typesetter.
+%
+% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+%
+% The LilyPond font is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version, or under the SIL Open Font License.
+
+
+input common-modules-and-initialization;
+
+fet_beginfont ("feta-alphabet", design_size, "fetaNumber");
+       number_design_size := design_size / 2;
+       dynamic_design_size := 14 design_size / 20;
+
+       input feta-numbers;
+       input feta-dynamics;
+fet_endfont ("feta-numbers");
diff --git a/mf/feta-alphabet.mf b/mf/feta-alphabet.mf
deleted file mode 100644 (file)
index 5663a79..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-test := 0;
-
-staffsize# := design_size * pt#;
-
-input feta-autometric;
-input feta-macros;
-input feta-params;
-
-fet_beginfont ("feta-alphabet", design_size, "fetaNumber");
-
-mode_setup;
-
-number_design_size := design_size / 2;
-dynamic_design_size := 14 design_size / 20;
-
-input feta-numbers;
-input feta-dynamics;
-
-fet_endfont ("feta-numbers");
index 04ba4e3867da755fd2ca04b8f1bf035e3506834b..c9e10df325746b626e298a1f086502a0842c540b 100644 (file)
@@ -1,6 +1,6 @@
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 11.22;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
index d314f40d4dc4934fa65c8ce94a1d83991e0b10ee..56924fb199f2b7039507bc5f1dd841a0e7bf0e64 100644 (file)
@@ -1,6 +1,6 @@
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 12.60;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
index 9a1bd2ee71b02de69e72408d2f6c3eb33d351f17..8db8b63da798ec4cb237facd179c8e5cb733933d 100644 (file)
@@ -1,6 +1,6 @@
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 14.14;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
index 86eb9c8c89e2bf7617fa7ec3cdacaac8a63dc27b..e93d0e61c0e87bf6bb6bf53fe4779689defb0aef 100644 (file)
@@ -1,6 +1,6 @@
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 15.87;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
index db216c154bc0cdb5bb88eee8b47c4dce522a8de9..30441bbd9b4ed1f98b71ebb9fd148cc0ebbea564 100644 (file)
@@ -1,6 +1,6 @@
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 17.82;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
index 0affe39057ae124685dc0c45554e31c7ac63d973..3d86449713fad9c43e9af067ee21748b820bf69f 100644 (file)
@@ -1,7 +1,6 @@
-% feta-alphabet20.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 20;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
index c8a725e59e30726b0f2c611e09ff4c09ed7bd118..ffd3381ce4ff4601613dc83b280dd19b095086f7 100644 (file)
@@ -1,7 +1,6 @@
-% feta-alphabet23.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 22.45;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
index 71af0403f986d7f76614192f48f5e56e09017b52..02170ec89d508128afc0184d77dcbf04b4112374 100644 (file)
@@ -1,6 +1,6 @@
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 25.20;
-input feta-alphabet;
+input feta-alphabet-generic;
 end.
 
diff --git a/mf/feta-arrow.mf b/mf/feta-arrow.mf
new file mode 100644 (file)
index 0000000..fab1bf1
--- /dev/null
@@ -0,0 +1,82 @@
+
+%
+% Draw an arrow
+%
+% * `stemslant' gives the direction of the stem's left boundary
+%   (needed for brushed stems, equals "up" for straight stems)
+% * `extend' is used to make the stem longer or shorter (if negative);
+%   different kinds of accidentals need different values here
+%
+def draw_arrow (expr attach, stemwidth, stemslant, extend, pointingdown) =
+begingroup;
+       save htip;  % tip height
+       save wwing; % wing `radius'
+       save angle_wing_bot, angle_wing_top, angle_tip;
+       save upshift;
+       clearxy;
+
+       wwing := 0.26 stemwidth;
+       htip := staff_space * 0.85 + stafflinethickness - wwing;
+
+       % `flip' is used to reflect the arrow vertically
+       % if arrow points downward
+       transform flip;
+       if pointingdown:
+               flip = identity reflectedabout (origin, right);
+       else:
+               flip = identity;
+       fi;
+
+       z1 = attach shifted (-stemwidth / 2, 0);
+       upshift := max (0, wwing + 0.1 staff_space + extend);
+       z2 = z1 shifted (((unitvector stemslant)
+                         scaled upshift) transformed flip);
+
+       z7 = attach shifted ((stemwidth/2),0);
+       z6 = z7 shifted (((unitvector (-xpart stemslant, ypart stemslant))
+                         scaled upshift) transformed flip);
+       z2 - z3 = ( 0.38 staff_space, 0.05 htip) transformed flip;
+       z6 - z5 = (-0.38 staff_space, 0.05 htip) transformed flip;
+
+       z4 = attach shifted ((-0.2 stemwidth, upshift + htip)
+                            transformed flip);
+       z4'= attach shifted (( 0.2 stemwidth, upshift + htip)
+                            transformed flip);
+
+       % `angle_wing_bot' is the angle at which the arc
+       % from z2 to z3a enters z3a
+       % `angle_wing_top' is the angle at which the arc
+       % from z3b to z4 leaves z3b
+       % `angle_tip' is the angle at which the arc
+       % from z4 to z4' leaves z4
+       angle_wing_bot = 30;
+       angle_wing_top = 55;
+       angle_tip = 68;
+
+       z3a = z3 shifted ((((dir angle_wing_bot) rotated -90)
+                          scaled wwing) transformed flip);
+       z3b = z3 shifted ((((dir angle_wing_top) rotated 90)
+                          scaled wwing) transformed flip);
+
+       z5a = z5 shifted ((((dir (180 - angle_wing_bot)) rotated 90)
+                          scaled wwing) transformed flip);
+       z5b = z5 shifted ((((dir (180 - angle_wing_top)) rotated -90)
+                          scaled wwing) transformed flip);
+
+       % Draw the arrow
+       pickup pencircle scaled 1;
+       fill z1
+            -- z2{stemslant transformed flip}
+            .. {(-dir angle_wing_bot) transformed flip}z3a
+            .. z3b{(dir angle_wing_top) transformed flip}
+            .. z4{(dir angle_tip) transformed flip}
+            .. z4'{(dir (-angle_tip)) transformed flip}
+            .. {(dir (-angle_wing_top)) transformed flip}z5b
+            .. z5a{(-dir (-angle_wing_bot)) transformed flip}
+            .. z6{((-stemslant) reflectedabout (origin, up)) transformed flip}
+            -- z7
+            -- cycle;
+
+       labels (range 0 thru 7, 4', 3a, 3b, 5a, 5b);
+endgroup;
+enddef;
index 1210262421a478024ef6ba167df54407d850cce9..8cf00c4efeab992ccf2abcffd0c74569c65e4737 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  256 smallest braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 0;
-input feta-braces;
+input feta-braces-generic;
 end.
index df91510af7355a3cbe1fa724bf372a4f56bf7bfd..c6a02a08e482e4ce9d1df3f4369551a8ef286232 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 1;
-input feta-braces;
+input feta-braces-generic;
 end.
index 87fc66047dfccba037f8b27548b7ed3147b39386..591065d303bb9754f7da7216017a97707b139e6c 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 2;
-input feta-braces;
+input feta-braces-generic;
 end.
index ffad571c0c3c943635a1d70286c4335a829d68d7..a2ef2510a3aab66521e67d0f151766cbb3d78d43 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 3;
-input feta-braces;
+input feta-braces-generic;
 end.
index a0b130bdada639107e7bd2cd250aa5dbfb0a8448..dfdb94fd7e2db7fa914010fca87ce9d6a89dd220 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 4;
-input feta-braces;
+input feta-braces-generic;
 end.
index ad31d2bcc8a2d392772f0d550271c72c4c4bccc3..866c5435398c7f1f63367fed943639beec53531e 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 5;
-input feta-braces;
+input feta-braces-generic;
 end.
index 545ca5a855b5ce4e97f5b1bb29249ea0347b0e3d..4347abe68829733518509621335434f0b5f3a51e 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 6;
-input feta-braces;
+input feta-braces-generic;
 end.
diff --git a/mf/feta-braces-generic.mf b/mf/feta-braces-generic.mf
new file mode 100644 (file)
index 0000000..fea872a
--- /dev/null
@@ -0,0 +1,47 @@
+% This file is part of LilyPond, the GNU music typesetter.
+%
+% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+%                Jan Nieuwenhuizen <janneke@gnu.org>
+%
+% The LilyPond font is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version, or under the SIL Open Font License.
+
+
+% We have to reduce the pixel-per-point value to
+% support large brace glyphs in case we are using MetaPost
+% (which by default sets `hppp' to 49.80244, regardless of
+% the used `mag' value)
+
+if known miterlimit:
+       bpppix_ := 0.2;         % ten times larger than original
+
+       numeric mm, pt, dd, bp, cm, pc, cc, in;
+
+       mm * bpppix_ = 2.83464;
+       pt * bpppix_ = 0.99626;
+       dd * bpppix_ = 1.06601;
+       bp * bpppix_ = 1;
+       cm * bpppix_ = 28.34645;
+       pc * bpppix_ = 11.95517;
+       cc * bpppix_ = 12.79213;
+       in * bpppix_ = 72;
+
+       hppp := pt;
+       vppp := pt;
+fi;
+
+design_size := 20;   %% arbitrary
+
+input common-modules-and-initialization;
+
+%
+% We must let the design increase for each font to make sure that mftrace
+% doesn't jack up the resolution too highly for the longer braces.
+%
+
+fet_beginfont ("feta-braces-" & char (97 + font_count),
+              (font_count + 1) * 20, "fetaBraces");
+       input feta-braces;
+fet_endfont ("feta-braces");
index 646e153106f1a8044f312a375b469237bee27c6f..dda3ce206983ee5777f8f3458f7206bb84cdc30e 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 7;
-input feta-braces;
+input feta-braces-generic;
 end.
index 0f3fcd35673df1281a2ddc7b0f5159d28a30bc26..29d519112b3f62d13fc6254809a4c1a0f678db00 100644 (file)
@@ -1,22 +1,5 @@
 % Feta (not the Font-En-Tja) music font --  next 256 braces
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
 font_count := 8;
-input feta-braces;
+input feta-braces-generic;
 end.
index c948f345fd6e525fa0d221606b96a55f86dc99e9..cf592e72b09ad2b1be3e0052b574d47a09245941 100644 (file)
 % You should have received a copy of the GNU General Public License
 % along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
-
-% We have to reduce the pixel-per-point value to
-% support large brace glyphs in case we are using MetaPost
-% (which by default sets `hppp' to 49.80244, regardless of
-% the used `mag' value)
-
-if known miterlimit:
-       bpppix_ := 0.2;         % ten times larger than original
-
-       numeric mm, pt, dd, bp, cm, pc, cc, in;
-
-       mm * bpppix_ = 2.83464;
-       pt * bpppix_ = 0.99626;
-       dd * bpppix_ = 1.06601;
-       bp * bpppix_ = 1;
-       cm * bpppix_ = 28.34645;
-       pc * bpppix_ = 11.95517;
-       cc * bpppix_ = 12.79213;
-       in * bpppix_ = 72;
-
-       hppp := pt;
-       vppp := pt;
-fi;
-
-
-input feta-autometric;
-input feta-macros;
-
-staffsize# := 20 pt#;   %% arbitrary
-
-input feta-params;
-
 %
 % We must let the design increase for each font to make sure that mftrace
 % doesn't jack up the resolution too highly for the longer braces.
 %
 
-fet_beginfont ("feta-braces-" & char (97 + font_count),
-              (font_count + 1) * 20, "fetaBraces");
-
-mode_setup;
-
-
 save code, braces_per_font;
 code := 64;
 braces_per_font := 64;
@@ -160,5 +122,3 @@ for i := 0 step 1 until font_count:
                number := number + 1;
        endfor;
 endfor;
-
-fet_endfont ("feta-braces");
index d76b3414535e4403fc01f071dfb88fdbc81385cb..2b79030ae551ad8244b2628e44891f54365f12ca 100644 (file)
@@ -105,7 +105,7 @@ def draw_c_clef (expr reduction) =
 
        % ugh, should be bulb, not flare?
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 enddef;
 
 
@@ -270,7 +270,7 @@ def draw_bass_clef (expr exact_center, reduction) =
 
        penlabels (1, 2, 3, 4, 5, 6);
 
-       draw_staff (-3, 1, 0);
+       draw_staff_if_debugging (-3, 1);
 enddef;
 
 
@@ -482,7 +482,7 @@ def draw_gclef (expr reduction) =
        penlabels (range 101 thru 121);
        penlabels (110', 111');
 
-       draw_staff (-1, 3, 0);
+       draw_staff_if_debugging (-1, 3);
 enddef;
 
 
@@ -522,7 +522,7 @@ def draw_percussion_clef (expr reduction) =
        draw_block ((-b, -d), (-b + razt, h));
        draw_block ((w - razt, -d), (w, h));
 
-       draw_staff (-3, 1, 1);
+       draw_staff_if_debugging (-3, 1);
 enddef;
 
 
@@ -729,7 +729,7 @@ def draw_tab_clef (expr reduction) =
        draw_tab_B ((-b + .025 reduced_ss, -d),
                    (2.1 reduced_ss, letterheight), 0.25);
 
-       draw_staff (-3, 2, 0.5);
+       draw_staff_if_debugging (-3, 2);
 enddef;
 
 
index 947cc8a35a487c91bfac13000e000812a9229d8c..8fc5aab9ee710e25b394cff9361505efcae504a1 100644 (file)
@@ -1,4 +1,3 @@
-% Feta (not the Font-En-Tja) music font --  generic stuff: include lots of files, but don't
 % This file is part of LilyPond, the GNU music typesetter.
 %
 % Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
@@ -7,40 +6,14 @@
 % it under the terms of the GNU General Public License as published by
 % the Free Software Foundation, either version 3 of the License, or
 % (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-
-
-if test = -1:
-       mode := smoke;
-fi
 
-staffsize# := design_size * pt#;
 
-mode_setup;
-
-input feta-macros;
-
-input feta-params;
+input common-modules-and-initialization;
 
 font_x_height staff_space#;
 
 fet_beginfont ("feta", design_size, "fetaMusic");
+       input feta-flags;
 
-input feta-flags;
-
-autometric_parameter ("staffsize", staffsize#);
-autometric_parameter ("stafflinethickness", stafflinethickness#);
-autometric_parameter ("staff_space", staff_space#);
-autometric_parameter ("linethickness", linethickness#);
-autometric_parameter ("black_notehead_width", black_notehead_width#);
-autometric_parameter ("ledgerlinethickness", ledgerlinethickness#);
-autometric_parameter ("blot_diameter", blot_diameter#);
-
+       input declare-autometric-parameters;
 fet_endfont;
index 30cd7f0976c0887ab2bc1c11163be435e039189e..8026bf499d46b7c2bbdf0473c4fff96efb1e089c 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags11.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 11.22;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
index 3210b1abc121c99af94856a26d694c86d0404367..51e508fee34f3e59d270acae5536c9319a592889 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags13.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 12.60;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
index 9a5449cc5d081bc580efed9ee831f78059f499bd..22055a8cc2e4f6a206d8f8f0dd555fabab073fcc 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags14.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 14.14;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
index d02993736a8bcdc25bd0bb2779bcb8fab1bea032..3e706e7d2360f8be6823e93af2eec525b2268222 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags16.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 15.87;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
index dcaefd440d5ffa02953b43ef8d880e82857c3aa6..a15fea7560984e8429d1dd7b8837fc1c28e9682b 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags18.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 17.82;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
index b7b834ecc4e2fbc616d6c24ef13e24e7468ec389..9eedbeb78d17f5113c29d0de27cd65ee89dd1cb9 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags20.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 20;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
index dcd640c8a95c6903886e4f2d50b299869ab1a576..1500a151106620ff8669a484c6ab92c48689bbcf 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags23.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 22.45;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
index b2a1fe616f69acec50d9f928d6a988b78ece1b61..322213b562e084cfdc76fc2ca886d8d7066850e4 100644 (file)
@@ -1,13 +1,5 @@
-% feta-flags26.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 25.20;
-test := 0;
-
-
 input feta-flags-generic;
-
 end.
-
diff --git a/mf/feta-flats.mf b/mf/feta-flats.mf
new file mode 100644 (file)
index 0000000..b7470e2
--- /dev/null
@@ -0,0 +1,535 @@
+
+%
+% Dedicated to my mom.    (3/10/97)
+%
+% Mamma, ik hou van je; kom je alsjeblieft terug?
+%    -- HW
+%
+%
+% TODO: remove crook_fatness
+% TODO: document, simplify!
+%
+
+def draw_meta_flat (expr xcenter, w, crook_fatness, arrowup, arrowdown) =
+       save crook_thinness;
+       save bottom_overshoot, bot_crook_dir;
+       save top_stem_thick, top_stem_thick_orig;
+       save bottom_stem_thick, hair, smaller_hole;
+       save top_crook_thinness;
+       save zwiep;
+       save center;
+       pair center, bot_crook_dir;
+       save clearing, clearing_orig;
+
+       clearxy;
+
+       % the stem shouldn't reach the top staff line.
+       %% TODO: should take from height.
+       %
+       % TODO: parameterize this
+       %
+       if w >= 0.75 staff_space:
+               smaller_hole = 0.35 stafflinethickness;
+       else:
+               smaller_hole = 0;
+       fi;
+       crook_thinness = .7 stafflinethickness + .06 staff_space;
+       top_crook_thinness = 1 stafflinethickness + .065 staff_space;
+       clearing = 1.7 stafflinethickness;
+       clearing_orig = clearing;
+       if arrowup:
+               clearing := 0.5 staff_space;
+       fi;
+       bottom_overshoot = stafflinethickness;
+
+       bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
+       top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
+       top_stem_thick_orig# = top_stem_thick#;
+       if arrowup:
+               % to look nice, arrowed stems should be less brushed
+               top_stem_thick# := top_stem_thick# * 0.8;
+       fi;
+       define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick,
+                                    top_stem_thick_orig);
+
+       if odd (top_stem_thick - bottom_stem_thick):
+               top_stem_thick := top_stem_thick - 1;
+       fi;
+       if odd (top_stem_thick_orig - bottom_stem_thick):
+               top_stem_thick_orig := top_stem_thick_orig - 1;
+       fi;
+
+       center = (xcenter, 0);
+
+       x1l = hround (xcenter - .5 top_stem_thick);
+       y1 = vround (2 staff_space - clearing);
+       x2l = hround (xcenter - .5 bottom_stem_thick);
+       y2 = -.5 staff_space - .5 stafflinethickness;
+       % z16 and the `*_orig' variables are needed for arrowed accidentals
+       % because their inner part should be unchanged from plain ones but
+       % the points z3l, z3r, and z10 depend on values that are different
+       % for arrowed accidentals
+       x16l = hround (xcenter -.5 top_stem_thick_orig);
+       y16 = vround (2 staff_space - clearing_orig);
+
+       penpos1 (top_stem_thick, 0);
+       penpos16 (top_stem_thick_orig, 0);
+       penpos2 (bottom_stem_thick, 0);
+
+       y3l = vfloor ((staff_space - stafflinethickness) / 2);
+       z3l = whatever [z2r, z1r];
+       z3r = .3 [z2r,
+                 (z16r shifted (0, clearing_orig - 1.7 stafflinethickness))]
+             + (smaller_hole, 0);
+       x3r := hceiling x3r;
+
+       % we insert z3l to get better conversion with mf2pt1
+       fill simple_serif (z1r, z1l, 30)
+            -- z2l
+            -- z2r
+            -- z3l
+            -- cycle;
+
+       z10 = whatever [z2r, z16r] + (smaller_hole, 0);
+       y10 = -1/10 staff_space;
+       x10 := hceiling x10;
+
+       x11 = xcenter + bottom_overshoot / 3;
+       y11 = -vround (.5 (staff_space + stafflinethickness)
+                      + bottom_overshoot);
+
+       x2a = 0.2[x2r, x7];
+       y2a = 1.5[y2, y11];
+
+       penpos4 (whatever, 53);
+
+       y4l - y4r = top_crook_thinness;
+       y5r = .15 staff_space;
+       x5l = hround (w + xcenter);
+       y4 = staff_space / 2;
+       x4r = .45 [x5r, x3r];
+       y4l := vround y4l;
+
+       penpos5 (crook_fatness, -175);
+
+       bot_crook_dir = unitvector ((x5l, 0) - z11);
+       z8 = z11 + whatever * bot_crook_dir;
+       y8 = -staff_space / 2;
+
+       z7 = z8
+            + whatever * bot_crook_dir
+            + crook_thinness * (bot_crook_dir rotated 90);
+       x7 = .1 [x3r, x8];
+
+       unfill z3r{z3r - z10}
+              .. z4r{right}
+              .. z5r{down}
+              .. z7{-bot_crook_dir}
+              & z7
+              .. z10{z3r - z10}
+              -- cycle;
+
+       if arrowdown:
+               fill z2l{down}
+                    .. z2a{up}
+                    .. z8{bot_crook_dir}
+                    .. z5l{up}
+                    .. z4l{left}
+                    .. z3l
+                    -- cycle;
+       else:
+               fill z2l{down}
+                    .. z11{right}
+                    .. z8{bot_crook_dir}
+                    .. z5l{up}
+                    .. z4l{left}
+                    .. z3l
+                    -- cycle;
+       fi;
+
+       if arrowup:
+               draw_arrow (z1, top_stem_thick, z1l - z2l,
+                           0.5 stafflinethickness, false);
+       fi;
+       if arrowdown:
+               draw_arrow ((0.5 [x2l, x2a], y2), x2a - x2l, up,
+                           staff_space / 2, true);
+       fi;
+enddef;
+
+
+def draw_arrowed_meta_flat (expr xcenter, width, crook_fatness,
+                                arrowup, arrowdown) =
+       save depth, height, extendleft;
+
+       depth# = 0.6 staff_space#;
+       height# = 1.9 staff_space#;
+       extendleft# := 1.2 stafflinethickness#;
+       if arrowup:
+               extendleft# := 3.45 stafflinethickness#;
+               height# := height# + 0.8 staff_space#;
+       fi;
+       if arrowdown:
+               extendleft# := 3.45 stafflinethickness#;
+               depth# := depth# + 1.6 staff_space#;
+       fi;
+
+       set_char_box (extendleft#, width, depth#, height#);
+       draw_meta_flat(xcenter, w, crook_fatness, arrowup, arrowdown);
+enddef;
+
+%
+% unfortunately, 600dpi is not enough to show the brush of the stem.
+%
+
+fet_beginchar ("Flat", "flat");
+       draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
+                               false, false);
+       penlabels (range 0 thru 11);
+
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Flat (arrow up)", "flat.arrowup");
+        draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
+                                true, false);
+        penlabels (range 0 thru 23);
+
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Flat (arrow down)", "flat.arrowdown");
+        draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
+                                false, true);
+        penlabels (range 0 thru 23);
+
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Flat (arrow up and down)", "flat.arrowboth");
+       draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
+                               true, true);
+       penlabels (range 0 thru 23);
+
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Flat (slashed)", "flat.slash");
+       set_char_box (.4 staff_space#, .8 staff_space#,
+                     0.6 staff_space#, 1.9 staff_space#);
+
+       draw_meta_flat (0, w, 0.31 staff_space, false, false);
+
+       clearxy;
+
+       save slope, slash_width;
+       slope = 0.5;
+       slash_width = w;
+
+       z11 = (0, h / 2);
+       z12 = z11 - (slash_width, slash_width * slope) / 2;
+       z13 = z11 + (slash_width, slash_width * slope) / 2;
+       penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
+       penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
+
+       z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
+       z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
+
+       fill z13r
+            .. z15
+            .. z13l
+            -- z12l
+            .. z14
+            .. z12r
+            -- z13r
+            .. cycle;
+
+       penlabels (12, 13);
+       labels (14, 15);
+
+       draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Flat (slashed twice)", "flat.slashslash");
+       set_char_box (.4 staff_space#, .8 staff_space#,
+                     0.6 staff_space#, 1.9 staff_space#);
+
+       draw_meta_flat (0, w, 0.31 staff_space, false, false);
+
+       clearxy;
+
+       save slope, slash_width;
+       slope = 0.5;
+       slash_width = w;
+
+       z11 = (0, 5/12 h);
+       z12 = z11 - (slash_width, slash_width * slope) / 2;
+       z13 = z11 + (slash_width, slash_width * slope) / 2;
+       penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
+       penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
+
+       z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
+       z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
+
+       fill z13r
+            .. z15
+            .. z13l
+            -- z12l
+            .. z14
+            .. z12r
+            -- z13r
+            .. cycle;
+
+       penlabels (12, 13);
+       labels (14, 15);
+
+       z21 = (0, 2/3 h);
+       z22 = z21 - (slash_width, slash_width * slope) / 2;
+       z23 = z21 + (slash_width, slash_width * slope) / 2;
+       penpos22 (1.5 stafflinethickness, angle (z23 - z22) - 90);
+       penpos23 (1.5 stafflinethickness, angle (z23 - z22) - 90);
+
+       z24 = z22 - .75 stafflinethickness * unitvector (z23 - z22);
+       z25 = z23 + .75 stafflinethickness * unitvector (z23 - z22);
+
+       fill z23r
+            .. z25
+            .. z23l
+            -- z22l
+            .. z24
+            .. z22r
+            -- z23r
+            .. cycle;
+
+       penlabels (22, 23);
+       labels (24, 25);
+
+       draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Flatflat (mirrored)", "mirroredflat.flat");
+       set_char_box (0, 1.6 staff_space#,
+                     0.6 staff_space#, 1.9 staff_space#);
+
+       % This is a modified version of `draw_meta_flat'.
+
+       save crook_thinness, crook_fatness;
+       save bottom_overshoot, bot_crook_dir;
+       save top_stem_thick, bottom_stem_thick, hair, smaller_hole;
+       save top_crook_thinness;
+       save zwiep;
+       save center;
+       pair center, bot_crook_dir;
+       save clearing, wid;
+       save pat;
+       path pat;
+
+       clearxy;
+
+       wid = w / 2;
+
+       % the stem shouldn't reach the top staff line.
+       %% TODO: should take from height.
+       %
+       % TODO: parameterize this
+       %
+       if wid >= 0.75 staff_space:
+               smaller_hole = 0.35 stafflinethickness;
+       else:
+               smaller_hole = 0;
+       fi;
+       clearing = 1.7 stafflinethickness;
+       crook_thinness = .7 stafflinethickness + .06 staff_space;
+       crook_fatness = 0.31 staff_space;
+       top_crook_thinness = 1 stafflinethickness + .065 staff_space;
+       bottom_overshoot = stafflinethickness;
+
+       bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
+       top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
+       define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick);
+
+       if odd (top_stem_thick - bottom_stem_thick):
+               top_stem_thick := top_stem_thick - 1;
+       fi;
+
+       center = (0, 0);
+
+       x1l = hround (-.5 top_stem_thick);
+       y1 = vround (2 staff_space - clearing);
+       x2l = hround (-.5 bottom_stem_thick);
+       y2 = -.5 staff_space - .5 stafflinethickness;
+
+       penpos1 (top_stem_thick, 0);
+       penpos2 (bottom_stem_thick, 0);
+
+       y3l = vfloor ((staff_space - stafflinethickness) / 2);
+       z3l = whatever [z2r, z1r];
+       z3r = .3 [z2r, z1r] + (smaller_hole, 0);
+       x3r := hceiling x3r;
+
+       z10 = whatever [z2r, z1r] + (smaller_hole, 0);
+       y10 = -1/10 staff_space;
+       x10 := hceiling x10;
+
+       x11 = bottom_overshoot / 3;
+       y11 = -vround (.5 (staff_space + stafflinethickness)
+                      + bottom_overshoot);
+
+       penpos4 (whatever, 53);
+
+       y4l - y4r = top_crook_thinness;
+       y5r = .15 staff_space;
+       x5l = hround (wid);
+       y4 = staff_space / 2;
+       x4r = .45 [x5r, x3r];
+       y4l := vround y4l;
+
+       penpos5 (crook_fatness, -175);
+
+       bot_crook_dir = unitvector ((x5l, 0) - z11);
+       z8 = z11 + whatever * bot_crook_dir;
+       y8 = -staff_space / 2;
+
+       z7 = z8
+            + whatever * bot_crook_dir
+            + crook_thinness * (bot_crook_dir rotated 90);
+       x7 = .1 [x3r, x8];
+
+       pat := z3r{z3r - z10}
+              .. z4r{right}
+              .. z5r{down}
+              .. z7{-bot_crook_dir}
+              & z7
+              .. z10{z3r - z10}
+              -- cycle;
+       unfill pat;
+       unfill pat xscaled -1;
+
+       pat := z11{right}
+              .. z8{bot_crook_dir}
+              .. z5l{up}
+              .. z4l{left}
+              .. z3l;
+       fill pat
+            -- simple_serif (z1r, z1l, 30)
+            -- reverse pat xscaled -1 shifted (-feta_eps, 0)
+            -- cycle;
+
+       currentpicture := currentpicture shifted (w/2, 0);
+
+       draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Semi flat", "mirroredflat");
+       set_char_box (1.2 stafflinethickness#, .8 staff_space#,
+                     0.6 staff_space#, 1.9 staff_space#);
+
+       draw_meta_flat (0, w, 0.31 staff_space, false, false);
+       currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
+fet_endchar;
+
+
+fet_beginchar ("Semi flat", "mirroredflat.backslash");
+       set_char_box (.4 staff_space#, .8 staff_space#,
+                     0.6 staff_space#, 1.9 staff_space#);
+
+       draw_meta_flat (0, w, 0.31 staff_space, false, false);
+
+       clearxy;
+
+       save slope, slash_width;
+       slope = 0.5;
+       slash_width = w;
+
+       z11 = (0, h / 2);
+       z12 = z11 - (slash_width, slash_width * slope) / 2;
+       z13 = z11 + (slash_width, slash_width * slope) / 2;
+       penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
+       penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
+
+       z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
+       z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
+
+       fill z13r
+            .. z15
+            .. z13l
+            -- z12l
+            .. z14
+            .. z12r
+            -- z13r
+            .. cycle;
+
+       currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
+
+       labels (1, 2, 3);
+fet_endchar;
+
+
+fet_beginchar ("Double Flat", "flatflat");
+       save left_wid, overlap, right_wid;
+
+       left_wid = .7;
+       right_wid = .8;
+       overlap = .05;
+
+       set_char_box (1.2 stafflinethickness#,
+                     (left_wid + right_wid - overlap) * staff_space#,
+                     .6 staff_space#, 1.9 staff_space#);
+       draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space,
+                       false, false);
+       draw_meta_flat (hround ((left_wid - overlap) * staff_space),
+                       right_wid * staff_space, 1/3 staff_space,
+                       false, false);
+fet_endchar;
+
+
+fet_beginchar ("3/4 Flat", "flatflat.slash");
+       save left_wid, overlap, right_wid;
+
+       left_wid = .7;
+       right_wid = .8;
+       overlap = .05;
+
+       set_char_box (1.2 stafflinethickness#,
+                     (left_wid + right_wid - overlap) * staff_space#,
+                     .6 staff_space#, 1.9 staff_space#);
+       draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space,
+                       false, false);
+       draw_meta_flat (hround ((left_wid - overlap) * staff_space),
+                       right_wid * staff_space, 1/3 staff_space,
+                       false, false);
+
+       %% maybe we should clip part of the stems?
+       %% or make the 1st flat smaller?
+       %% or reverse it?
+       pickup pencircle scaled 2 stafflinethickness;
+
+       z12 = round (-.25 w - b, .55 staff_space) + feta_offset;
+       z13 = round (.75 w, 1.45 staff_space) + feta_offset;
+       penpos12 (2 stafflinethickness, angle (z13 - z12) - 90);
+       penpos13 (2 stafflinethickness, angle (z13 - z12) - 90);
+
+       z14 = z12 - stafflinethickness * unitvector (z13 - z12);
+       z15 = z13 + stafflinethickness * unitvector (z13 - z12);
+
+       fill z13r
+            .. z15
+            .. z13l
+            -- z12l
+            .. z14
+            .. z12r
+            -- z13r
+            .. cycle;
+
+       penlabels (12, 13);
+       labels (14, 15);
+
+       draw_staff_if_debugging (-2, 2);
+fet_endchar;
diff --git a/mf/feta-generic.mf b/mf/feta-generic.mf
deleted file mode 100644 (file)
index 0d253ce..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-% Feta (not the Font-En-Tja) music font --  generic stuff: include lots of files, but don't
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
-
-
-if test = -1:
-       mode := smoke;
-fi
-
-staffsize# := design_size * pt#;
-
-mode_setup;
-
-input feta-macros;
-
-input feta-params;
-
-font_x_height staff_space#;
-
-fet_beginfont ("feta", design_size, "fetaMusic");
-
-if test = 0:
-       input feta-rests;
-       input feta-accidentals;
-       input feta-arrowheads;
-       input feta-dots;
-       input feta-scripts;
-       input feta-clefs;
-       input feta-timesignatures;
-       input feta-pedals;
-       input feta-brackettips;
-       input feta-accordion;
-       input feta-ties;
-else:
-       input feta-test-generic.mf;
-fi
-
-autometric_parameter ("staffsize", staffsize#);
-autometric_parameter ("stafflinethickness", stafflinethickness#);
-autometric_parameter ("staff_space", staff_space#);
-autometric_parameter ("linethickness", linethickness#);
-autometric_parameter ("black_notehead_width", black_notehead_width#);
-autometric_parameter ("ledgerlinethickness", ledgerlinethickness#);
-autometric_parameter ("blot_diameter", blot_diameter#);
-
-fet_endfont;
index c464c3f7f8342488834f5a37608216c65f90d64f..37544a7b64dac0351f074b855b722551c623bb41 100644 (file)
@@ -21,6 +21,7 @@
 % debugging
 %
 
+
 def print_penpos (suffix $) =
        message
          "z" & str$ & "l = (" & decimal x.$.l & ", " &decimal y.$.l & ");"
@@ -50,15 +51,15 @@ def treq =
 enddef;
 
 
-def draw_staff (expr first, last, offset) =
+def draw_staff_if_debugging (expr first, last) =
        if test <> 0:
                pickup pencircle scaled stafflinethickness;
 
                for i := first step 1 until last:
                        draw (-staff_space,
-                             (i + offset) * staff_space_rounded)
+                             (i + stafflines_y_offset) * staff_space_rounded)
                             -- (4 staff_space,
-                                (i + offset) * staff_space_rounded);
+                                (i + stafflines_y_offset) * staff_space_rounded);
                endfor;
        fi;
 enddef;
diff --git a/mf/feta-naturals.mf b/mf/feta-naturals.mf
new file mode 100644 (file)
index 0000000..3c824c7
--- /dev/null
@@ -0,0 +1,163 @@
+
+%
+% The stems of the natural are brushed (at least, in Barenreiter SCS)
+%
+
+% general parameters:
+save full_width, full_height;
+save stem_thickness, stem_end_thickness_multiplier;
+save beam_thickness, beam_slant, hole_highest_point;
+
+full_height# := 3 staff_space#;
+full_width# := 2/3 staff_space#;
+stem_thickness# := 0.09 staff_space# + 0.5 stafflinethickness#;
+stem_end_thickness_multiplier := 10/7;
+beam_slant := 1.266 stafflinethickness;
+beam_thickness := 0.485 staff_space -  stafflinethickness;
+hole_highest_point := 0.5 (staff_space - stafflinethickness);
+
+
+def draw_natural (expr arrowup, arrowdown) =
+        save upstem_factor, downstem_factor;
+        save upstem_end_thickness, downstem_end_thickness;
+        save half_height, half_box_height;
+        save beam_direction, r_stem_top_path, l_stem_bottom_path;
+        pair beam_direction;
+        path r_stem_top_path, l_stem_bottom_path;
+
+        upstem_factor = downstem_factor = stem_end_thickness_multiplier;
+
+        half_height# := 0.5 full_height#;
+        define_pixels (half_height);
+        define_pixels (full_width);
+
+        set_char_box (0, full_width#, half_height#, half_height#);
+        d := d - feta_space_shift;
+
+        if arrowup:
+                b := b + 3 stafflinethickness;
+                h := h + 1.2 staff_space;
+                % to look nice, arrowed stems must be less brushed
+                upstem_factor := 0.5 (1 + upstem_factor);
+        fi;
+        if arrowdown:
+                w := w + 3 stafflinethickness;
+                d := d + 1.2 staff_space;
+                % to look nice, arrowed stems must be less brushed
+                downstem_factor := 0.5 (1 + downstem_factor);
+        fi;
+
+        upstem_end_thickness# = upstem_factor * stem_thickness#;
+        downstem_end_thickness# = downstem_factor * stem_thickness#;
+        define_whole_blacker_pixels (upstem_end_thickness, downstem_end_thickness);
+        define_whole_blacker_pixels (stem_thickness);
+
+        half_box_height := hole_highest_point + beam_thickness
+                           %% correction for the fact that x11 != x12.
+                           %% ideally y2 should be calculated from y11
+                           %% and beam_thickness, but the brushed stems
+                           %% would cause a cyclic dependency:
+                           %% y2 -> x11 -> y14 -> y13 -> y12 -> y2
+                           + 0.5 stem_thickness * beam_slant / full_width;
+
+        %% stems:
+
+        pickup pencircle scaled stem_thickness;
+
+        penpos1 (upstem_end_thickness, 0);
+        penpos3 (downstem_end_thickness, 0);
+        penpos2 (stem_thickness, 0);
+        penpos4 (stem_thickness, 0);
+
+        x2r = full_width;
+        x4l = 0;
+        x3 = x2;
+        x1 = x4;
+
+        y1 = half_height;
+        y3 = -half_height;
+        top y2 = vround (half_box_height);
+        y4 = -y2 + feta_space_shift;
+
+        l_stem_bottom_path := z4r{z4r - z1r}
+                              .. bot z4
+                              .. z4l{z1l - z4l};
+
+        r_stem_top_path := z2r{z2r - z3r}
+                           .. top z2
+                           .. z2l{z3l - z2l};
+
+        fill simple_serif (z1l, z1r, -30)
+             -- l_stem_bottom_path
+             -- cycle;
+
+        fill simple_serif (z3l, z3r, 30)
+             -- r_stem_top_path
+             -- cycle;
+
+        %% beams:
+
+        beam_direction = (full_width, beam_slant);
+
+        z11 = z3l + whatever * (z2l - z3l);
+        y11 = vround (hole_highest_point);
+        z12 = directionpoint -beam_direction of r_stem_top_path;
+        z13 = z12 + whatever * beam_direction;
+        x13 = x1;
+        z14 = z11 + whatever * beam_direction;
+        x14 = x1;
+
+        z21 = z4r + whatever * (z1r - z4r);
+        y21 = -y11 + feta_space_shift;
+        z22 = directionpoint -beam_direction of l_stem_bottom_path;
+        z23 = z22 + whatever * beam_direction;
+        x23 = x3;
+        z24 = z21 + whatever * beam_direction;
+        x24 = x3;
+
+        fill z11
+             -- z12
+             -- z13
+             -- z14
+             -- cycle;
+
+        fill z21
+             -- z22
+             -- z23
+             -- z24
+             -- cycle;
+
+        if arrowup:
+                draw_arrow (z1, upstem_end_thickness,
+                            z1l - z4l, stafflinethickness / 2, false);
+        fi;
+        if arrowdown:
+                draw_arrow (z3, downstem_end_thickness,
+                            z2r - z3r, stafflinethickness / 2, true);
+        fi;
+
+        %% debugging:
+        penlabels (1, 2, 3, 4);
+        labels (11, 12, 13, 14, 21, 22, 23, 24);
+        draw_staff_if_debugging (-2, 2);
+enddef;
+
+
+fet_beginchar ("Natural", "natural");
+       draw_natural (false, false);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Natural (arrow up)", "natural.arrowup");
+       draw_natural (true, false);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Natural (arrow down)", "natural.arrowdown");
+       draw_natural (false, true);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Natural (arrows up and down)", "natural.arrowboth");
+       draw_natural (true, true);
+fet_endchar;
index 3c255073c8339bb64a559b2119e340c356423466..290deaf0844aaedc706f4de78e994d6455e06570 100644 (file)
@@ -1,4 +1,3 @@
-% Feta (not the Font-En-Tja) music font --  generic stuff: include lots of files, but don't
 % This file is part of LilyPond, the GNU music typesetter.
 %
 % Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
@@ -7,40 +6,14 @@
 % it under the terms of the GNU General Public License as published by
 % the Free Software Foundation, either version 3 of the License, or
 % (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-
-
-if test = -1:
-       mode := smoke;
-fi
 
-staffsize# := design_size * pt#;
 
-mode_setup;
-
-input feta-macros;
-
-input feta-params;
+input common-modules-and-initialization;
 
 font_x_height staff_space#;
 
 fet_beginfont ("feta", design_size, "fetaMusic");
+       input feta-noteheads;
 
-input feta-noteheads;
-
-autometric_parameter ("staffsize", staffsize#);
-autometric_parameter ("stafflinethickness", stafflinethickness#);
-autometric_parameter ("staff_space", staff_space#);
-autometric_parameter ("linethickness", linethickness#);
-autometric_parameter ("black_notehead_width", black_notehead_width#);
-autometric_parameter ("ledgerlinethickness", ledgerlinethickness#);
-autometric_parameter ("blot_diameter", blot_diameter#);
-
+       input declare-autometric-parameters;
 fet_endfont;
index 82abf14e54bf3fb3ede1de6caab4cb6609a0f1cc..2ebf537b59db941ed09c4e6fbc26a7a8717568a0 100644 (file)
 test_outlines := 0;
 
 
-save remember_pic;
-picture remember_pic;
-
-
 % Most beautiful noteheads are pronounced, not circular,
 % and not even symmetric.
 % These examples are inspired by [Wanske]; see literature list.
 
 
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % NOTE HEAD VARIABLES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -159,33 +154,17 @@ enddef;
 fet_beginchar ("Longa notehead", "uM2");
        draw_longa (true);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
 fet_beginchar ("Longa notehead", "dM2");
        draw_longa (false);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Longa notehead", "uM2");
-               draw_longa (true);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-
-
-       fet_beginchar ("Longa notehead", "dM2");
-               draw_longa (false);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 def draw_brevis (expr linecount, line_thickness_multiplier) =
        save stemthick, fudge, gap;
 
@@ -253,35 +232,17 @@ enddef;
 fet_beginchar ("Brevis notehead", "sM1");
        draw_brevis (1, 1);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Brevis notehead", "sM1");
-               draw_brevis(1, 1);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Double-lined brevis notehead", "sM1double");
        draw_brevis (2, 0.8);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Double-lined brevis notehead", "sM1double");
-               draw_brevis (2, 0.8);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Whole notehead", "s0");
        draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, 0.707, 0);
        undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10,
@@ -289,60 +250,26 @@ fet_beginchar ("Whole notehead", "s0");
 
        whole_notehead_width# := charwd;
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Whole notehead", "s0");
-               draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0,
-                                     0.707, 0);
-               undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10,
-                                      0.68, 2 stafflinethickness#);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Half notehead", "s1");
        draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17);
        undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#);
 
        half_notehead_width# := charwd;
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Half notehead", "s1");
-               draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34,
-                                     0.66, 0.17);
-               undraw_inside_ellipse (3.25, 33, 0.81,
-                                      2.5 stafflinethickness#);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Quarter notehead", "s2");
        draw_quarter_path;
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Quarter notehead", "s2");
-               draw_outside_ellipse (1.49 - puff_up_factor / 3.0, 31,
-                                     0.707, 0);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
@@ -351,58 +278,26 @@ fet_beginchar ("Whole diamondhead", "s0diamond");
        undraw_inside_ellipse (1.30, 125, 0.6,
                               .4 staff_space# + stafflinethickness#);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Whole diamondhead", "s0diamond");
-               draw_outside_ellipse (1.80, 0, 0.495, 0);
-               undraw_inside_ellipse (1.30, 125, 0.6,
-                                      .4 staff_space# + stafflinethickness#);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Half diamondhead", "s1diamond");
        draw_outside_ellipse (1.50, 34, 0.49, 0.17);
        undraw_inside_ellipse (3.5, 33, 0.80,
                               .3 staff_space# + 1.5 stafflinethickness#);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Half diamondhead", "s1diamond");
-               draw_outside_ellipse (1.50, 34, 0.49, 0.17);
-               undraw_inside_ellipse (3.5, 33, 0.80,
-                                      .3 staff_space#
-                                      + 1.5 stafflinethickness#);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Quarter diamondhead", "s2diamond");
        draw_outside_ellipse (1.80, 35, 0.495, -0.25);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Quarter diamondhead", "s2diamond");
-               draw_outside_ellipse (1.80, 35, 0.495, -0.25);
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
@@ -561,19 +456,10 @@ enddef;
 fet_beginchar ("Whole trianglehead", "s0triangle");
        draw_whole_triangle_head;
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Whole trianglehead", "s0triangle");
-               draw_whole_triangle_head;
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 def draw_small_triangle_head (expr dir) =
        save hei, xs;
        save llap;
@@ -595,14 +481,14 @@ enddef;
 fet_beginchar ("Half trianglehead (downstem)", "d1triangle");
        draw_small_triangle_head (-1);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
 fet_beginchar ("Half trianglehead (upstem)", "u1triangle");
        draw_small_triangle_head (1);
 
-       draw_staff (-2, 2, 0.5);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -623,14 +509,14 @@ enddef;
 fet_beginchar ("Quarter trianglehead (upstem)", "u2triangle");
        draw_closed_triangle_head (1);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
 fet_beginchar ("Quarter trianglehead (downstem)", "d2triangle");
        draw_closed_triangle_head (-1);
 
-       draw_staff (-2, 2, 0.5);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -707,21 +593,21 @@ enddef;
 fet_beginchar ("Whole slashhead", "s0slash");
        draw_slash (4 slash_thick# + 0.5 staff_space#);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
 fet_beginchar ("Half slashhead", "s1slash");
        draw_slash (3.0 slash_thick# + 0.15 staff_space#);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
 fet_beginchar ("Quarter slashhead", "s2slash");
        draw_slash (1.5 slash_thick#);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -835,28 +721,10 @@ fet_beginchar ("Whole Crossed notehead", "s0cross");
 
        draw_cross (3.75);
 
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Whole Crossed notehead", "s0cross");
-               save wid, hei;
-
-               wid# := black_notehead_width# + 4 stafflinethickness#;
-               hei# := noteheight# + stafflinethickness#;
-
-               set_char_box (0, wid#, hei# / 2, hei# / 2);
-
-               currentpicture := remember_pic;
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Half Crossed notehead", "s1cross");
        save wid, hei;
 
@@ -867,28 +735,10 @@ fet_beginchar ("Half Crossed notehead", "s1cross");
 
        draw_cross (3.0);
 
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Half Crossed notehead", "s1cross");
-               save wid, hei;
-
-               wid# := black_notehead_width# + 2 stafflinethickness#;
-               hei# := noteheight# + stafflinethickness# / 2;
-
-               set_char_box (0, wid#, hei# / 2, hei# / 2);
-
-               currentpicture := remember_pic;
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("Crossed notehead", "s2cross");
        wid# := black_notehead_width#;
        hei# := noteheight#;
@@ -896,25 +746,10 @@ fet_beginchar ("Crossed notehead", "s2cross");
 
        draw_cross (1.0);
 
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("Crossed notehead", "s2cross");
-               wid# := black_notehead_width#;
-               hei# := noteheight#;
-               set_char_box (0, wid#, hei# / 2, hei# / 2);
-
-               currentpicture := remember_pic;
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 fet_beginchar ("X-Circled notehead", "s2xcircle");
        save wid, hei;
        save cthick, cxd, cyd, dy;
@@ -960,29 +795,10 @@ fet_beginchar ("X-Circled notehead", "s2xcircle");
        z12 = (charwx * hppp, charwy * vppp);
        labels (12);
 
-       remember_pic := currentpicture;
-
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
-if test > 0:
-       fet_beginchar ("X-Circled notehead", "s2xcircle");
-               save wid, hei;
-               save cthick, cxr, cyr;
-
-               wid# := black_notehead_width# * sqrt (sqrt2);
-               hei# := noteheight# * sqrt (sqrt2);
-
-               set_char_box (0, wid#, hei# / 2, hei# / 2);
-
-               currentpicture := remember_pic;
-
-               draw_staff (-2, 2, 0.5);
-       fet_endchar;
-fi;
-
-
 %%%%%%%%
 %
 % SOLFA SHAPED NOTES
@@ -1634,7 +1450,7 @@ def draw_sol_head (expr filled) =
        if not filled:
          undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#);
        fi
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 enddef;
 
 fet_beginchar ("Whole solhead", "s0sol");
@@ -2253,7 +2069,7 @@ begingroup
        if not filled:
          undraw_inside_ellipse (1.9, 33, 0.74, 5.5 stafflinethickness#);
        fi
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 endgroup
 enddef;
 
index b02844a196b9c693c85b97425e51c003afc5d77d..cba81dee23421118c5303dd209433bd27523faa4 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads11.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 11.22;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
index e010769f4b20fcca22ef64e2afaa16e0884ec108..0516809917211e567793cdf54852cfc195d618c4 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads13.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 12.60;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
index 7d25cb2a60b665ca2d58287f564fb50a0dd73ef9..14d3b78b01fd0aea253d568081c72c27d624ab75 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads14.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 14.14;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
index 755f9ffdd518572b192b552709bd791a9b13562f..8c8370dc5931eb14bb0c662c5e6c9ce25b4425de 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads16.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 15.87;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
index bdc6918bf36698f35e7229ccc041bc1f31835fcd..a1e705c48c5454427dd40dfe998ed9bd58200dbf 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads18.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 17.82;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
index 072f99207c29d907fd46b310ebea366424315073..9ac9379de258adf8dabab88d4c1ee02d03dca0eb 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads20.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 20;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
index ab0154832eda9bd55404c9e84143040d78659507..f6ddb0db4483e773300472b01205f14d4688006b 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads23.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 22.45;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
index b25d21495c0a8416db183db6324ea37822c6091f..e72c7012d57c0f88ed4e1d679604a0e604cd3615 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads26.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 25.20;
-test := 0;
-
-
 input feta-noteheads-generic;
-
 end.
-
diff --git a/mf/feta-other-generic.mf b/mf/feta-other-generic.mf
new file mode 100644 (file)
index 0000000..0ec50a8
--- /dev/null
@@ -0,0 +1,29 @@
+% This file is part of LilyPond, the GNU music typesetter.
+%
+% Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+%
+% The LilyPond font is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version, or under the SIL Open Font License.
+
+
+input common-modules-and-initialization;
+
+font_x_height staff_space#;
+
+fet_beginfont ("feta", design_size, "fetaMusic");
+       input feta-rests;
+       input feta-accidentals;
+       input feta-arrowheads;
+       input feta-dots;
+       input feta-scripts;
+       input feta-clefs;
+       input feta-timesignatures;
+       input feta-pedals;
+       input feta-brackettips;
+       input feta-accordion;
+       input feta-ties;
+
+       input declare-autometric-parameters;
+fet_endfont;
diff --git a/mf/feta-parenthesis.mf b/mf/feta-parenthesis.mf
new file mode 100644 (file)
index 0000000..ad2561a
--- /dev/null
@@ -0,0 +1,44 @@
+
+
+def draw_paren =
+       save leftindent;
+
+       leftindent := .2 staff_space;
+
+       set_char_box (0, .5 staff_space# + stafflinethickness#,
+                     staff_space#, staff_space#);
+
+       d := d - feta_shift;
+
+       z1 = (leftindent, h);
+       z2 = (w - stafflinethickness, .5 (h - d));
+       z3 = (leftindent, -d);
+
+       penpos1 (stafflinethickness, 35);
+       penpos2 (.1 staff_space + stafflinethickness, 0);
+       penpos3 (stafflinethickness, -35);
+
+       fill z2l{down}
+            .. simple_serif (z3l, z3r, 90)
+            .. z2r{up}
+            .. simple_serif (z1r, z1l, 90)
+            .. z2l{down}
+            -- cycle;
+enddef;
+
+
+fet_beginchar ("Right Parenthesis", "rightparen");
+       draw_paren;
+       penlabels (1, 2, 3);
+
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Left Parenthesis", "leftparen");
+       draw_paren;
+
+       currentpicture := currentpicture xscaled -1;
+
+       set_char_box (charwd, charbp, chardp, charht);
+fet_endchar;
index 09439853a0b35a0b830e80db8bf5ec04d57985c2..9147b7fa955d6106fc18be9fa518c711f1738bdf 100644 (file)
@@ -43,7 +43,7 @@ fet_beginchar ("whole rest", "0");
        currentpicture := currentpicture
                            shifted (0, -block_rest_y + feta_space_shift);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -52,7 +52,7 @@ fet_beginchar ("half rest", "1");
 
        block_rest;
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -72,8 +72,6 @@ fet_beginchar ("whole rest (outside staff)", "0o");
        lft x5 = -b - block_rest_y;
        rt x6 = w + block_rest_y;
        draw_gridline (z5, z6, ledgerlinethickness_rounded);
-
-       draw_staff (-2, 2, -3);
 fet_endchar;
 
 
@@ -90,8 +88,6 @@ fet_beginchar ("half rest (outside staff)", "1o");
        rt x6 = w + block_rest_y;
 
        draw_gridline (z5, z6, ledgerlinethickness_rounded);
-
-       draw_staff (-2, 2, 3);
 fet_endchar;
 
 
@@ -103,7 +99,7 @@ fet_beginchar ("maxima rest", "M3");
 
        addto currentpicture also currentpicture shifted (2 breve_rest_x, 0);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -113,7 +109,7 @@ fet_beginchar ("longa rest", "M2");
        draw_block ((0, -breve_rest_y + feta_shift),
                    (breve_rest_x, breve_rest_y));
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -122,7 +118,7 @@ fet_beginchar ("breve rest", "M1");
 
        draw_block ((0, 0), (breve_rest_x, breve_rest_y));
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 fet_beginchar ("breve rest (outside staff)", "M1o");
@@ -139,8 +135,6 @@ fet_beginchar ("breve rest (outside staff)", "M1o");
 
        draw_gridline (z5, z6, ledgerlinethickness_rounded);
        draw_gridline ((x5, 0), (x6, 0), ledgerlinethickness_rounded);
-
-       draw_staff (-2, 2, 3);
 fet_endchar;
 
 
@@ -226,7 +220,7 @@ fet_beginchar ("Quarter rest", "2");
        penlabels (1, 2, 3, 4, 5, 6, 7);
        penlabels (10, 11, 12, 13);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -374,7 +368,7 @@ def draw_eighth_rest (expr show_labels) =
             -- z1l
             .. cycle;
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 enddef;
 
 
@@ -440,7 +434,7 @@ fet_beginchar ("16th rest", "4");
        penlabels (1, 2);
        labels (9);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -494,7 +488,7 @@ fet_beginchar ("32th rest", "5");
        penlabels (1, 2);
        labels (9);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -552,7 +546,7 @@ fet_beginchar ("64th rest", "6");
        penlabels (1, 2);
        labels (9);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
@@ -614,7 +608,7 @@ fet_beginchar ("128th rest", "7");
        penlabels (1, 2);
        labels (9);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 fet_endchar;
 
 
index 91c3ae1fe49867c126308b3571d266194eb30479..0baef99bb455bfb3d3389d9318ae895ee533cb13 100644 (file)
@@ -1277,7 +1277,6 @@ fet_beginchar ("Varied Segno", "varsegno");
        addto currentpicture also currentpicture scaled -1;
 
        penlabels (1, 1', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
-       % draw_staff (-2, 2, 0);
 fet_endchar;
 
 
@@ -1495,7 +1494,7 @@ fet_beginchar ("Arpeggio", "arpeggio");
        draw_arpeggio;
        penlabels (range 1 thru 9);
 
-       draw_staff (-2, 2, 0.0);
+       draw_staff_if_debugging (-2, 2);
        endgroup;
 fet_endchar;
 
diff --git a/mf/feta-sharps.mf b/mf/feta-sharps.mf
new file mode 100644 (file)
index 0000000..eeade7d
--- /dev/null
@@ -0,0 +1,339 @@
+
+%
+% The beams of most sharps have horizontal endings (as if drawn with
+% a square pen).  [Wanske] does not mention this, so we'll just ignore
+% this fact.
+%
+
+save default_width, default_height, onestemmed_height;
+save default_interbeam_dist, triples_interbeam_dist;
+save default_beam_thickness, stem_thickness;
+
+default_width# := 1.1 staff_space#;
+default_height# := 3 staff_space#;
+onestemmed_height# := 2.66 staff_space#;
+define_pixels (default_width);
+
+default_interbeam_dist := 1.05 staff_space_rounded;
+triples_interbeam_dist := 1.2 staff_space_rounded;
+
+default_beam_thickness# := 0.3 staff_space# + stafflinethickness#;
+stem_thickness# := stafflinethickness# + .05 staff_space#;
+define_whole_blacker_pixels (stem_thickness);
+
+
+def draw_sharp_beam (expr length, y_offset) =
+        save beam_length;
+        save ne_beam_dir, nw_dist;
+        pair ne_beam_dir, nw_dist;
+
+        beam_length := length;
+
+        define_whole_vertical_blacker_pixels (default_beam_thickness);
+
+        clearxy;
+
+        pickup pencircle scaled 2 blot_diameter;
+
+        rt x2 - lft x1 = beam_length;
+        z2 = z1 + whatever * (beam_length, default_beam_thickness);
+        .5 [z1, z3] = (.5 w, y_offset);
+        x3 = x2;
+        top y2 - bot y3 = default_beam_thickness;
+        x4 = x1;
+        top y1 - bot y4 = default_beam_thickness;
+
+        ne_beam_dir = unitvector (z2 - z1);
+        nw_dist = (ne_beam_dir rotated 90) * blot_diameter;
+
+        fill lft z1{up}
+             ... (z1 + nw_dist){ne_beam_dir}
+             -- (z2 + nw_dist){ne_beam_dir}
+             ... rt z2{down}
+             -- rt z3{down}
+             ... (z3 - nw_dist){-ne_beam_dir}
+             -- (z4 - nw_dist){-ne_beam_dir}
+             ... lft z4{up}
+             -- cycle;
+
+       labels (1, 2, 3, 4);
+enddef;
+
+
+def draw_sharp (expr arrowup, arrowdown) =
+        save dist_between_stems;
+        save outer_space;
+        save half_height, interbeam_dist;
+
+        half_height# := 0.5 default_height#;
+        define_pixels (half_height);
+        interbeam_dist := default_interbeam_dist;
+
+        set_char_box (0, default_width#, half_height#, half_height#);
+        d := d - feta_space_shift;
+
+        dist_between_stems := hround (7 / 16 * default_width);
+        outer_space := hround ((w - dist_between_stems - stem_thickness) / 2);
+
+        w := 2 outer_space + dist_between_stems + stem_thickness;
+
+        draw_sharp_beam (w, -.5 interbeam_dist);
+        draw_sharp_beam (w, -.5 interbeam_dist + vround interbeam_dist);
+
+        % expand the charbox so that it encloses the whole arrow;
+        % this must not happen earlier because some commands above
+        % still rely on the old width
+        if arrowup:
+                w := w + 1.5 stafflinethickness;
+                h := h + 1.2 staff_space;
+        fi;
+        if arrowdown:
+                b := b + 1.5 stafflinethickness;
+                d := d + 1.2 staff_space;
+        fi;
+
+        pickup pencircle scaled stem_thickness;
+
+        lft x5 = lft x6 = outer_space;
+        lft x7 = lft x8 = outer_space + dist_between_stems;
+        bot y5 = -half_height;
+        top y8 = half_height;
+        z6 = z8 + whatever * ne_beam_dir;
+        bot y7 = -top y6 + feta_space_shift;
+
+        draw_gridline (z5, z6, stem_thickness);
+        draw_gridline (z7, z8, stem_thickness);
+
+        if arrowup:
+                draw_arrow (z8, stem_thickness, up,
+                            stafflinethickness / 2 + stem_thickness / 2, false);
+        fi;
+        if arrowdown:
+                draw_arrow (z5, stem_thickness, up,
+                            stafflinethickness / 2 + stem_thickness / 2, true);
+        fi;
+
+        labels (5, 6, 7, 8);
+        draw_staff_if_debugging (-2, 2);
+enddef;
+
+
+fet_beginchar ("Sharp", "sharp");
+       draw_sharp (false, false);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Sharp (arrow up)", "sharp.arrowup");
+       draw_sharp (true, false);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Sharp (arrow down)", "sharp.arrowdown");
+       draw_sharp (false, true);
+fet_endchar;
+
+
+fet_beginchar ("Arrowed Sharp (arrows up and down)", "sharp.arrowboth");
+       draw_sharp (true, true);
+fet_endchar;
+
+
+fet_beginchar ("1/2 Sharp", "sharp.slashslash.stem");
+        save outer_space;
+        save half_height, interbeam_dist;
+
+        half_height# := 0.5 onestemmed_height#;
+        define_pixels (half_height);
+        interbeam_dist := default_interbeam_dist;
+
+        set_char_box (0, 0.7 staff_space#, half_height#, half_height#);
+        d := d - feta_space_shift;
+
+        outer_space := hround ((w - stem_thickness) / 2);
+
+        w := 2 outer_space + stem_thickness;
+
+        draw_sharp_beam (w, -.5 interbeam_dist);
+        draw_sharp_beam (w, -.5 interbeam_dist + vround interbeam_dist);
+
+        pickup pencircle scaled stem_thickness;
+
+        lft x5 = lft x6 = outer_space;
+        top y6 = half_height;
+        bot y5 = -top y6 + feta_space_shift;
+
+        draw_gridline (z5, z6, stem_thickness);
+
+        labels (5, 6);
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Sharp (3 beams)", "sharp.slashslashslash.stemstem");
+        save dist_between_stems;
+        save outer_space;
+        save half_height, interbeam_dist;
+        save default_beam_thickness;
+
+        half_height# := 0.5 default_height#;
+        define_pixels (half_height);
+        interbeam_dist := triples_interbeam_dist;
+
+        default_beam_thickness# := 0.22 staff_space# + stafflinethickness#;
+
+        set_char_box (0, default_width#, half_height#, half_height#);
+
+        dist_between_stems := hround (7 / 16 * default_width);
+        outer_space := hround ((w - dist_between_stems - stem_thickness) / 2);
+
+        w := 2 outer_space + dist_between_stems + stem_thickness;
+        d := d - feta_space_shift;
+
+        draw_sharp_beam (.88 w, -.5 interbeam_dist);
+        draw_sharp_beam (.88 w, -.5 interbeam_dist + vround interbeam_dist);
+        default_beam_thickness# := 1/.88 default_beam_thickness#;
+        draw_sharp_beam (w, 0);
+
+        pickup pencircle scaled stem_thickness;
+
+        lft x5 = lft x6 = outer_space;
+        lft x7 = lft x8 = outer_space + dist_between_stems;
+        bot y5 = -half_height;
+        top y8 = half_height;
+        z6 = z8 + whatever * ne_beam_dir;
+        bot y7 = -top y6 + feta_space_shift;
+
+        draw_gridline (z5, z6, stem_thickness);
+        draw_gridline (z7, z8, stem_thickness);
+
+        labels (5, 6, 7, 8);
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("1/2 Sharp (3 beams)", "sharp.slashslashslash.stem");
+        save outer_space;
+        save half_height, interbeam_dist;
+        save default_beam_thickness;
+
+        half_height# := 0.5 onestemmed_height#;
+        define_pixels (half_height);
+        interbeam_dist := triples_interbeam_dist;
+
+        default_beam_thickness# := 0.22 staff_space# + stafflinethickness#;
+
+        set_char_box (0, 0.95 staff_space#, half_height#, half_height#);
+
+        outer_space := hround ((w - stem_thickness) / 2);
+
+        w := 2 outer_space + stem_thickness;
+        d := d - feta_space_shift;
+
+        draw_sharp_beam (.8 w, -.5 interbeam_dist);
+        draw_sharp_beam (.8 w, -.5 interbeam_dist + vround interbeam_dist);
+        default_beam_thickness# := 1/.8 default_beam_thickness#;
+        draw_sharp_beam (w, 0);
+
+        pickup pencircle scaled stem_thickness;
+
+        lft x5 = lft x6 = outer_space;
+        top y6 = half_height;
+        bot y5 = -top y6 + feta_space_shift;
+
+        draw_gridline (z5, z6, stem_thickness);
+
+        labels (5, 6);
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("3/4 Sharp", "sharp.slashslash.stemstemstem");
+        save dist_between_stems;
+        save outer_space;
+        save half_height, interbeam_dist;
+
+        half_height# := 0.5 default_height#;
+        define_pixels (half_height);
+        interbeam_dist := default_interbeam_dist;
+
+        set_char_box (0, 1.6 staff_space#, half_height#, half_height#);
+        d := d - feta_space_shift;
+
+        dist_between_stems := hround (9 / 32 * w);
+        outer_space := hround ((w - 2 dist_between_stems - stem_thickness) / 2);
+
+        w := 2 outer_space + 2 dist_between_stems + stem_thickness;
+
+        draw_sharp_beam (w, -.5 interbeam_dist);
+        draw_sharp_beam (w, -.5 interbeam_dist + vround interbeam_dist);
+
+        pickup pencircle scaled stem_thickness;
+
+        lft x5 = lft x6 = outer_space;
+        lft x9 = lft x10 = outer_space + dist_between_stems;
+        lft x7 = lft x8 = outer_space + 2 dist_between_stems;
+        bot y5 = -half_height;
+        top y8 = half_height;
+        z6 = z8 + whatever * ne_beam_dir;
+        bot y7 = -top y6 + feta_space_shift;
+        y9 = .5 [y5, y7];
+        y10 = .5 [y6, y8];
+
+        draw_gridline (z5, z6, stem_thickness);
+        draw_gridline (z7, z8, stem_thickness);
+        draw_gridline (z9, z10, stem_thickness);
+
+        labels (5, 6, 7, 8, 9, 10);
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
+
+
+fet_beginchar ("Double Sharp", "doublesharp");
+        save klaverblad, klaversteel;
+        save pat;
+        path pat;
+
+        klaversteel = 1/15 staff_space;
+        klaverblad = .4 staff_space - .5 stafflinethickness;
+
+        set_char_box (0, staff_space#, .5 staff_space#, .5 staff_space#);
+
+        z1 = (klaversteel, 0);
+        z2 = (w / 2 - klaverblad / 10, h - klaverblad);
+        z3 = (w / 2, h);
+        z4 = z2 reflectedabout ((0, 0), (1, 1));
+        z5 = z1 reflectedabout ((0, 0), (1, 1));
+
+        pickup pencircle scaled blot_diameter;
+
+        x2 := hfloor (rt x2) - blot_diameter / 2;
+        x3 := hfloor (rt x3) - blot_diameter / 2;
+        y3 := vfloor (top y3) - blot_diameter / 2;
+        y4 := vfloor (top y4) - blot_diameter / 2;
+
+        pat = (rt z1){dir45}
+              .. {right}(bot z2)
+              .. rt z2
+              -- rt z3{z3 - z2}
+              .. top z3{z4 - z3}
+              -- top z4{z4 - z3}
+              .. (lft z4){down}
+              .. {dir 225}(top z5);
+        pat := pat
+               -- reverse pat xscaled -1 shifted (-feta_eps, 0);
+
+        % assure symmetry -- it's more important to center the glyph on the
+        % staff line than centering it between staff lines, so we use
+        % feta_shift, not feta_space_shift.
+        h := h + feta_shift;
+
+        fill pat shifted (0, feta_shift)
+             -- reverse pat yscaled -1 shifted (0, -feta_eps)
+             -- cycle;
+
+       % ugh
+       currentpicture := currentpicture shifted (hround (w / 2), 0);
+
+        labels (1, 2, 3, 4, 5);
+        draw_staff_if_debugging (-2, 2);
+fet_endchar;
diff --git a/mf/feta-test-generic.mf b/mf/feta-test-generic.mf
deleted file mode 100644 (file)
index a910b52..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-%
-% test stuff.
-% in a separate file to avoid tainting non-test font files for testing.
-%
-
-%input feta-rests;
-input feta-accidentals;
-%input feta-dots;
-%input feta-arrowheads;
-%input feta-scripts;
-%input feta-trills;
-%input feta-clefs;
-%input feta-brackettips;
-%input feta-timesignatures;
-%input feta-pedals;
-%input feta-accordion;
-%input feta-ties;
diff --git a/mf/feta-test11.mf b/mf/feta-test11.mf
deleted file mode 100644 (file)
index ad21720..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-% feta-test11.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
-
-design_size := 11;
-test := 1;
-
-% smoked cheese
-% test := -1;
-
-input feta-generic;
-
-end.
-
diff --git a/mf/feta-test13.mf b/mf/feta-test13.mf
deleted file mode 100644 (file)
index 28abf42..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-% feta-test13.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
-
-design_size := 13;
-test := 1;
-
-% smoked cheese
-% test := -1;
-
-input feta-generic;
-
-
-end.
-
diff --git a/mf/feta-test16.mf b/mf/feta-test16.mf
deleted file mode 100644 (file)
index eaa280a..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-% feta-test16.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
-
-design_size := 16;
-test := 1;
-
-% smoked cheese
-% test := -1;
-
-input feta-generic;
-
-
-end.
-
diff --git a/mf/feta-test20.mf b/mf/feta-test20.mf
deleted file mode 100644 (file)
index 5a58be3..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-% feta-test20.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
-
-design_size := 20;
-test := 1;
-
-% smoked cheese
-% test := -1;
-
-input feta-generic;
-
-
-end.
-
diff --git a/mf/feta-test23.mf b/mf/feta-test23.mf
deleted file mode 100644 (file)
index 5a25b46..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-% feta-test23.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
-
-design_size := 23;
-test := 1;
-
-% smoked cheese
-% test := -1;
-
-input feta-generic;
-
-
-end.
-
diff --git a/mf/feta-test26.mf b/mf/feta-test26.mf
deleted file mode 100644 (file)
index e9e1521..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-% feta-test26.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
-
-design_size := 26;
-test := 1;
-
-% smoked cheese
-% test := -1;
-
-input feta-generic;
-
-
-end.
index 0098f0ad424e4ca0cb8bab6cbccc8d140325042e..8a50fc512a21fd57070882e68af943bc5098e99b 100644 (file)
@@ -90,7 +90,7 @@ def draw_C =
 
        penlabels (1, 2, 3, 4, 5);
 
-       draw_staff (-2, 2, 0);
+       draw_staff_if_debugging (-2, 2);
 enddef;
 
 
index be6a6a7e10d7cdcb30f48c40d88a3ad6eb7a5708..ddc0f0d29251681c83db0e0a8f54fe934f7c7c0e 100644 (file)
@@ -1,13 +1,6 @@
-% feta11.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 11.22;
-test := 0;
-
-
-input feta-generic;
 
+input feta-other-generic;
 end.
-
index 5014c123424530ba2e40111e17db5eaf870cce83..37871789cef95a3a24d782dd722c3354dda2c8eb 100644 (file)
@@ -1,13 +1,6 @@
-% feta13.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 12.60;
-test := 0;
-
-
-input feta-generic;
 
+input feta-other-generic;
 end.
-
index 23ac8e4d153928e19273183b40c796f924e95c19..a70db3e136320df2d78a9e00834c9f8b4631ee14 100644 (file)
@@ -1,14 +1,6 @@
-% feta14.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 14.14;
-test := 0;
-
-
-input feta-generic;
-
 
+input feta-other-generic;
 end.
-
index 174460b715fe32026216309c0203b00dbd6acfda..d38c756bf728600fd154aa854c1f7957fbfcc1e1 100644 (file)
@@ -1,13 +1,6 @@
-% feta16.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 15.87;
-test := 0;
-
-
-input feta-generic;
 
+input feta-other-generic;
 end.
-
index b52f6a3e35ca72d75e2b1efc983c7071978b9f22..d69ff7ccceede542e038d48bcb8c3cb7d8732b5a 100644 (file)
@@ -1,14 +1,6 @@
-% feta18.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
-input feta-autometric;
-
-% todo change file name
 design_size := 17.82;
-test := 0;
-
-
-input feta-generic;
-
 
+input feta-other-generic;
 end.
index 2b561b200d9fee70370387096dffc32193e4585f..eafc6fa1638a6cb904216c11f05fd9c7999b2fd8 100644 (file)
@@ -1,14 +1,7 @@
-% feta20.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 20;
 
-input feta-autometric;
-
-
 % use feta-test for debugging.
-test := 0;
-input feta-generic;
-
-
+input feta-other-generic;
 end.
index d2cf0025e94e18a8c541e8a6dbbaa03b3383954a..0a0be5cae0bff525c4d8ef05147cf7681b7730ee 100644 (file)
@@ -1,15 +1,6 @@
-% feta23.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
-input feta-autometric;
-
-% todo change file name
 design_size := 22.45;
-test := 0;
-
-
-input feta-generic;
-
 
+input feta-other-generic;
 end.
-
index 2bfa536618942eccc90fbf818b9f541c7821270c..62ed9540e4a2924860f382da20bfe13b3ee63696 100644 (file)
@@ -1,15 +1,6 @@
-% feta26.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 25.20;
-test := 0;
-
-
-input feta-generic;
-
 
+input feta-other-generic;
 end.
-
-
index ec6561dc8e50a0cc001e6135c63a6b4caae99f23..4221f02a38539d607b4097eed45e4ac8ab3475be 100644 (file)
@@ -125,9 +125,7 @@ enddef;
 
 
 fet_beginchar ("Ed. Vat. do clef", "vaticana.do");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_vaticana_do_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -194,9 +192,7 @@ enddef;
 
 
 fet_beginchar ("Ed. Vat. fa clef", "vaticana.fa");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_vaticana_fa_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -282,9 +278,7 @@ enddef;
 
 
 fet_beginchar ("Ed. Med. do clef", "medicaea.do");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_medicaea_do_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -352,9 +346,7 @@ enddef;
 
 
 fet_beginchar ("Ed. Med. fa clef", "medicaea.fa");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_medicaea_fa_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -589,9 +581,7 @@ enddef;
 
 
 fet_beginchar ("neo-mensural c clef", "neomensural.c");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_neomensural_c_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -696,9 +686,7 @@ enddef;
 
 
 fet_beginchar ("petrucci c1 clef", "petrucci.c1");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_c_clef ((0, 0), +2, 1.0);
 fet_endchar;
 
@@ -709,9 +697,7 @@ fet_endchar;
 
 
 fet_beginchar ("petrucci c2 clef", "petrucci.c2");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_c_clef ((0, 0), +1, 1.0);
 fet_endchar;
 
@@ -722,9 +708,7 @@ fet_endchar;
 
 
 fet_beginchar ("petrucci c3 clef", "petrucci.c3");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_c_clef ((0, 0), 0, 1.0);
 fet_endchar;
 
@@ -735,9 +719,7 @@ fet_endchar;
 
 
 fet_beginchar ("petrucci c4 clef", "petrucci.c4");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_c_clef ((0, 0), -1, 1.0);
 fet_endchar;
 
@@ -748,9 +730,7 @@ fet_endchar;
 
 
 fet_beginchar ("petrucci c5 clef", "petrucci.c5");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_c_clef ((0, 0), -2, 1.0);
 fet_endchar;
 
@@ -840,9 +820,7 @@ enddef;
 
 
 fet_beginchar ("mensural c clef", "mensural.c");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_mensural_c_clef ((0, 0), 1.0, true);
 fet_endchar;
 
@@ -853,9 +831,7 @@ fet_endchar;
 
 
 fet_beginchar ("black mensural c clef", "blackmensural.c");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_mensural_c_clef ((0, 0), 1.0, false);
 fet_endchar;
 
@@ -1034,9 +1010,7 @@ enddef;
 
 
 fet_beginchar ("petrucci f clef", "petrucci.f");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_f_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -1142,9 +1116,7 @@ enddef;
 
 
 fet_beginchar ("mensural f clef", "mensural.f");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_mensural_f_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -1374,9 +1346,7 @@ enddef;
 
 
 fet_beginchar ("petrucci g clef", "petrucci.g");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_g_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -1408,9 +1378,7 @@ enddef;
 % until the code for the mensural g clef will be rewritten.
 %
 fet_beginchar ("mensural g clef", "mensural.g");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_petrucci_g_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -1499,9 +1467,7 @@ enddef;
 
 
 fet_beginchar ("Hufnagel do clef", "hufnagel.do");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_hufnagel_do_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -1595,9 +1561,7 @@ enddef;
 
 
 fet_beginchar ("Hufnagel fa clef", "hufnagel.fa");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_hufnagel_fa_clef ((0, 0), 1.0);
 fet_endchar;
 
@@ -1619,9 +1583,7 @@ enddef;
 
 
 fet_beginchar ("Hufnagel do/fa clef", "hufnagel.do.fa");
-       if test = 1:
-               draw_staff (-1, 3, 0.0);
-       fi;
+       draw_staff_if_debugging (-1, 3);
        draw_hufnagel_do_fa_clef ((0, 0), 1.0);
 fet_endchar;
 
diff --git a/mf/parmesan-generic.mf b/mf/parmesan-generic.mf
deleted file mode 100644 (file)
index 31b35ff..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-% Feta (not the Font-En-Tja) music font --  generic stuff: include lots of files,
-% This file is part of LilyPond, the GNU music typesetter.
-%
-% Copyright (C) 2002--2012 Juergen Reuter <reuter@ipd.uka.de>
-%
-% The LilyPond font is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
-
-
-if test = -1:
-       mode := smoke;
-fi;
-
-mode_setup;
-
-staffsize# := design_size * pt#;
-
-input feta-macros;
-input feta-params;
-
-input parmesan-macros;
-
-
-font_x_height staff_space#;
-
-
-fet_beginfont ("parmesan", design_size, "parmesanMusic");
-       if test = 0:
-               input parmesan-rests;
-               input parmesan-clefs;
-               input parmesan-custodes
-               input parmesan-accidentals;
-               input parmesan-flags;
-               input parmesan-timesignatures;
-               input parmesan-scripts;
-               input parmesan-dots;
-       else:
-
-       fi;
-fet_endfont;
index a4103791ff8302c808f4c2529def1013b2fd3f09..746839bc768756a30e225ebe84042db3cddc104b 100644 (file)
@@ -1,4 +1,3 @@
-% Feta (not the Font-En-Tja) music font --  generic stuff: include lots of files
 % This file is part of LilyPond, the GNU music typesetter.
 %
 % Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
@@ -7,28 +6,9 @@
 % it under the terms of the GNU General Public License as published by
 % the Free Software Foundation, either version 3 of the License, or
 % (at your option) any later version, or under the SIL Open Font License.
-%
-% LilyPond is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-
-
-if test = -1:
-       mode := smoke;
-fi
-
-staffsize# := design_size * pt#;
-
-mode_setup;
-
-input feta-macros;
 
-input feta-params;
 
+input common-modules-and-initialization;
 input parmesan-macros;
 
 font_x_height staff_space#;
index 288695a45e13781c40dd05d82eb12e3e0c3f13cc..4f35548ff1ebf453af6fc1fb9bb388491fd5a3e8 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads11.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 11.22;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
index ad126423aabadee00e23debfa76c3e6db3b8588a..13cedf0b14e8d00ba772d3dcb0841b4869248e67 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads13.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 12.60;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
index f5d3a41df72ae54bbbac00b4f1a4e6e46dad2956..4c41de51495953ad3b85c75b7f8d778409e8504a 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads14.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 14.14;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
index 3db517fa0455dd1a4ec585b1a932f06aa74eeaee..53f67ceb686d22f681ccd42ae8b1c8c58890bb4d 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads16.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 15.87;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
index ed0f99ec0e6f5f6990c0aba8519920aab434047a..4fcc73d5c4b0ece2daf1ab09ad3ae6cf876c949c 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads18.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 17.82;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
index 8891652bb81d14fdb76057a0423445f1d290c980..3d2d91ff28ce17ba49983b8fa52c62ab0488a7b4 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads20.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 20;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
index fe64e6f496eda98b5dcc67b49145e824096efbde..7a0d3bfd939c639100d2f5c96867e461e6d60696 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads23.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 22.45;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
index 082ffc208d219a5bb3186660889c89552f552be4..f7cb63aa909f6ecf419e39e46dc05f1add32553e 100644 (file)
@@ -1,13 +1,5 @@
-% feta-noteheads26.mf
-% part of LilyPond's pretty-but-neat music font
-
-input feta-autometric;
+% Produce font files at specified size.
 
 design_size := 25.20;
-test := 0;
-
-
 input parmesan-noteheads-generic;
-
 end.
-
diff --git a/mf/parmesan-other-generic.mf b/mf/parmesan-other-generic.mf
new file mode 100644 (file)
index 0000000..a0e9f38
--- /dev/null
@@ -0,0 +1,26 @@
+% This file is part of LilyPond, the GNU music typesetter.
+%
+% Copyright (C) 2002--2012 Juergen Reuter <reuter@ipd.uka.de>
+%
+% The LilyPond font is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version, or under the SIL Open Font License.
+
+
+
+input common-modules-and-initialization;
+input parmesan-macros;
+
+font_x_height staff_space#;
+
+fet_beginfont ("parmesan", design_size, "parmesanMusic");
+       input parmesan-rests;
+       input parmesan-clefs;
+       input parmesan-custodes
+       input parmesan-accidentals;
+       input parmesan-flags;
+       input parmesan-timesignatures;
+       input parmesan-scripts;
+       input parmesan-dots;
+fet_endfont;
index 27ba341437d1952a24bf2aea32069ec0f87d6d04..050559744ff10456052c7f49171b9f0aefc92339 100644 (file)
@@ -1,13 +1,6 @@
-% parmesan11.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 11.22;
 
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
+input parmesan-other-generic;
 end.
-
index 905da48d5d8d73021461d78a0ed9771ef082779f..8e139d450db0ad3794d2c3366d4d28dc2c7d5807 100644 (file)
@@ -1,14 +1,6 @@
-% parmesan13.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 12.60;
 
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
-
+input parmesan-other-generic;
 end.
-
index 6357337be224aaeafdad1922ea373b3f45394b8b..2eb056525f6bcce13f04b015055508032dd5f0d3 100644 (file)
@@ -1,14 +1,5 @@
-% parmesan14.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 14.14;
-
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
-
+input parmesan-other-generic;
 end.
-
index 19b0516779b768ddf31468905f616d469fefbc84..d8dd45d2ff1ffbbf94143efc697df25aef3de371 100644 (file)
@@ -1,14 +1,6 @@
-% parmesan16.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 15.87;
 
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
-
+input parmesan-other-generic;
 end.
-
index 8c28507046feacaf34f3f5ea6270a81113275590..cd1052b3aee55a38475d20665fa2a802165a347d 100644 (file)
@@ -1,14 +1,6 @@
-% parmesan18.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 17.82;
 
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
-
+input parmesan-other-generic;
 end.
-
index d14251edcedf0a0bfdc039b8ffb3bde45c0ffe90..a7e8452c6fe0482caca9f0caa1a5a4ee819e7a26 100644 (file)
@@ -1,14 +1,6 @@
-% parmesan20.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 20;
 
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
-
+input parmesan-other-generic;
 end.
-
index 39b643732ba8de336441350d1c1331486db98988..e47b714b5cb56efe680178c160be0f808b293e4b 100644 (file)
@@ -1,14 +1,6 @@
-% parmesan23.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 22.45;
 
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
-
+input parmesan-other-generic;
 end.
-
index 1be6fb51914144b15f02dc793f3874cb395329d5..925ceaa8abc9073a2f93b6f0c8e2e6beb274798b 100644 (file)
@@ -1,14 +1,6 @@
-% parmesan26.mf
-% part of LilyPond's pretty-but-neat music font
+% Produce font files at specified size.
 
 design_size := 25.20;
 
-input feta-autometric;
-
-test := 0;
-
-input parmesan-generic;
-
-
+input parmesan-other-generic;
 end.
-
index 3e62f0366e68e5281b8cb3ae6e19f3aa23b22a25..03df7c03cb7735e5f8f4746983e19384cb85ea19 100644 (file)
@@ -1,4 +1,4 @@
-%!PS-Adobe-1.0: music-drawing-routines.ps
+%!PS-Adobe-2.0
 %
 % Functions for direct and embedded PostScript
 
@@ -63,12 +63,7 @@ bind def
     0 setgray 0 setlinecap % Prepare graphics state
     1 setlinewidth 0 setlinejoin
     10 setmiterlimit [ ] 0 setdash newpath
-    /languagelevel where % If level not equal to 1 then
-    {pop languagelevel % set strokeadjust and
-    1 ne % overprint to their defaults.
-      {false setstrokeadjust false setoverprint
-      } if
-    } if
+    false setoverprint
 } bind def
 
 /EndEPSF { %def
@@ -77,11 +72,18 @@ bind def
   b4_Inc_state restore
 } bind def
 
-/stroke_and_fill {
+/stroke_and_fill? {
+    {
        gsave
-               stroke
+           false setstrokeadjust
+           stroke
        grestore
        fill
+    }
+    {
+       stroke
+    }
+    ifelse
 } bind def
 
 /vector_add { % x1 y1 x2 y2 vector_add x1+x2 y1+y2
@@ -95,30 +97,104 @@ bind def
 
 /draw_round_box % width height x y blot
 {
-        dup
-       0.0 gt {
-               setlinewidth % w h x y
-               rmoveto % w h
-               2 copy 0 ne exch 0 ne and
+    0 max setlinewidth
+    matrix currentmatrix 5 1 roll
+    currentpoint translate newpath translate
+    2 copy 0 min exch 0 min exch translate
+    abs exch abs exch
+    currentlinewidth 0 eq
+    { % straight corners
+       2 copy 2 mul gt
+       { % horizontal
+           0 1 index 2 div moveto
+           setlinewidth
+           0 rlineto
+           0 setlinecap
+           stroke
+       }
+       {
+           2 copy exch 2 mul gt
+           { % vertical
+               1 index 2 div 0 moveto
+               exch setlinewidth
+               0 exch rlineto
+               0 setlinecap
+               stroke
+           }
+           {
+               0 0 4 2 roll rectfill
+           }
+           ifelse
+       }
+       ifelse
+    }
+    { % rounded corners
+       2 copy 0 eq exch 0 eq or
+       { % line shape
+           0 0 moveto
+           rlineto
+           1 setlinecap
+           stroke
+           0 setlinecap
+       }
+       { % full shape
+           currentstrokeadjust {
+               currentlinewidth 2 div
+               0 0 2 index 180 270 arc
+               2 index 0 2 index 270 360 arc
+               3 copy 0 90 arc
+               0 2 index 3 -1 roll 90 180 arc
+               closepath
+               2 copy 2 mul gt
+               { % horizontal
+                   2 copy add currentlinewidth add 10 add % large enough
+                   0 1 index neg moveto
+                   2 index 1 index neg lineto
+                   2 index 1 index lineto
+                   0 exch lineto closepath
+                   gsave clip newpath
+                   0 1 index 2 div moveto
+                   currentlinewidth add setlinewidth
+                   0 rlineto
+                   2 setlinecap
+                   stroke
+                   grestore
+               }
                {
-                   0 setlinecap
-                   1 setlinejoin
-                   currentpoint % w h x1 y1
-                   4 2 roll % x1 y1 w h
-                   4 copy
-                   rectfill
-                   rectstroke
-               } {
-                   1 setlinecap
-                   rlineto stroke
-               } ifelse
-       } {
-               pop % w h x y
-               rmoveto % w h
-               currentpoint % w h x1 y1
-               4 2 roll % x1 y1 w h
-               rectfill
-       } ifelse
+                   2 copy exch 2 mul gt
+                   { % vertical
+                       2 copy add currentlinewidth add 10 add % large enough
+                       dup neg 0 moveto
+                       dup 0 lineto
+                       dup 2 index lineto
+                       neg 1 index lineto closepath
+                       gsave clip newpath
+                       1 index 2 div 0 moveto
+                       exch currentlinewidth add setlinewidth
+                       0 exch rlineto
+                       2 setlinecap
+                       stroke
+                       grestore
+                   }
+                   {
+                       pop pop
+                       fill
+                   }
+                   ifelse
+               }
+               ifelse
+               newpath
+           }
+           {
+               1 setlinejoin
+               0 0 4 2 roll 4 copy rectstroke rectfill
+           }
+           ifelse
+       }
+       ifelse
+    }
+    ifelse
+    setmatrix
 } bind def
 
 /draw_polygon % fill? x(n) y(n) x(n-1) y(n-1) ... x(0) y(0) n blot
@@ -136,11 +212,7 @@ bind def
        rmoveto % x(0) y(0)
        { polygon_x polygon_y vector_add lineto } repeat % n times
        closepath
-       { %fill?
-               stroke_and_fill
-       }{
-               stroke
-       } ifelse
+       stroke_and_fill?
 } bind def
 
 /draw_circle % filled? radius thickness draw_circle
@@ -150,9 +222,7 @@ bind def
        3 2 roll        % f? x0 y0 r
        dup 0 rmoveto
        0 360 arc closepath
-               { stroke_and_fill }
-               { stroke }
-       ifelse
+       stroke_and_fill?
 } bind def
 
 /draw_ellipse % filled? x-radius y-radius thickness draw_ellipse
@@ -164,9 +234,7 @@ bind def
   1 0 rmoveto
   1 0 360  arc closepath
   savematrix setmatrix
-             { stroke_and_fill}
-             { stroke }
-  ifelse
+  stroke_and_fill?
 } bind def
 
 /draw_partial_ellipse % filled connect x-radius y-radius startangle endangle thickness draw_partial_ellipse
@@ -205,7 +273,7 @@ bind def
   connect {
     startangle cos startangle sin moveto endangle cos endangle sin lineto }
     if
-  savematrix setmatrix filled { stroke_and_fill } { stroke } ifelse
+  savematrix setmatrix filled stroke_and_fill?
   grestore
 } bind def
 
@@ -213,7 +281,6 @@ bind def
 {
        setlinewidth % dx dy x1 y1
        1 setlinecap
-       1 setlinejoin
        rmoveto % dx dy
        rlineto
        stroke
@@ -222,7 +289,6 @@ bind def
 /draw_dashed_line % dx dy thickness dashpattern offset draw_dashed_line
 {
        1 setlinecap
-       1 setlinejoin
        setdash % dx dy thickness
        setlinewidth %dx dy
        rlineto
index e2eb3baa4ac5735055ece16dd52d2b90e50a0276..8c472a63e03d487775fc8f6673b9e60a5e43c64f 100644 (file)
@@ -3683,6 +3683,17 @@ def conv(str):
     str = re.sub ("New_dynamic_engraver", "Dynamic_engraver", str)
     return str
 
+@rule ((2, 19, 0), r'''(make-relative (a b) b ...) -> make-relative (a b) #{ a b #}...''')
+def conv (str):
+    str = re.sub (r"(\(make-relative\s+\(\s*(([A-Za-z][-_A-Za-z0-9]*)" +
+                  r"(?:\s+[A-Za-z][-_A-Za-z0-9]*)*)\s*\)\s*)\3(?=\s)",
+                  r"\1(make-event-chord (list \2))", str)
+    str = re.sub (r"(\(make-relative\s+\(\s*([A-Za-z][-_A-Za-z0-9]*" +
+                  r"(?:\s+([A-Za-z][-_A-Za-z0-9]*))+)\s*\)\s*)\3(?=\s)",
+                  r"\1(make-sequential-music (list \2))", str)
+    return str
+
+
 # Guidelines to write rules (please keep this at the end of this file)
 #
 # - keep at most one rule per version; if several conversions should be done,
index 14e0209675d02c1b220745d39c14c46271625b2b..176f9a496baffbce18c58f0327a24643554883d0 100644 (file)
     (let ((value (ly:context-property context name)))
       (if (not (null? value)) value default)))
 
-  (define (beaming<? a b)
-    (ly:moment<? (fraction->moment (car a))
-                 (fraction->moment (car b))))
-
-  (define (ending-moments group-list start-beat base-moment)
+  (define (ending-moments group-list start-beat base-length)
     (if (null? group-list)
         '()
         (let ((new-start (+ start-beat (car group-list))))
-          (cons (ly:moment-mul (ly:make-moment new-start 1) base-moment)
-                (ending-moments (cdr group-list) new-start base-moment)))))
+          (cons (* new-start base-length)
+                (ending-moments (cdr group-list) new-start base-length)))))
 
-  (define (larger-setting test-beam sorted-alist)
-    (if (null? sorted-alist)
-        '()
-        (let* ((first-key (caar sorted-alist))
-               (first-moment (fraction->moment first-key)))
-          (if (moment<=? test-beam first-moment)
-              (car sorted-alist)
-              (larger-setting test-beam (cdr sorted-alist))))))
+  (define (larger-setting type sorted-alist)
+    (assoc type sorted-alist <=))
 
-  (define (beat-end? moment beat-structure)
-    (pair? (member moment beat-structure)))  ;; member returns a list if found, not #t
+  (define (beat-end? moment beat-endings)
+    (pair? (memv moment beat-endings)))  ;; member returns a list if found, not #t
 
   ;; Start of actual auto-beam test routine
   ;;
   ;;
   ;; Don't start auto beams on grace notes
-  (if (and (!= (ly:moment-grace-numerator (ly:context-now context)) 0)
-           (= dir START))
-      #f
-      (let* ((base-moment (get 'baseMoment (ly:make-moment 1 4)))
-             (measure-length (get 'measureLength (ly:make-moment 1 1)))
+  (and (or (zero? (ly:moment-grace (ly:context-now context)))
+           (!= dir START))
+      (let* ((base-length (cond ((get 'baseMoment #f) => ly:moment-main)
+                                (else 1/4)))
+             (measure-length (cond ((get 'measureLength #f) => ly:moment-main)
+                                   (else 1)))
              (time-signature-fraction
               (get 'timeSignatureFraction '(4 . 4)))
              (beat-structure (get 'beatStructure '(1 1 1 1)))
-             (beat-endings (ending-moments beat-structure 0 base-moment))
-             (exceptions (sort (assoc-get 'end
-                                          (get 'beamExceptions '())
-                                          '())
-                               beaming<?))
+             (beat-endings (ending-moments beat-structure 0 base-length))
+             (exceptions (sort (map
+                                (lambda (a)
+                                  (if (pair? (car a))
+                                      (cons (/ (caar a) (cdar a))
+                                            (cdr a))
+                                      a))
+                                (assoc-get 'end
+                                           (get 'beamExceptions '())
+                                           '()))
+                               car<))
              (function (if (= dir START) 'begin 'end))
              (beam-half-measure (get 'beamHalfMeasure #t))
-             (type (moment->fraction test-beam))
-             (non-grace (ly:make-moment
-                         (ly:moment-main-numerator measure-pos)
-                         (ly:moment-main-denominator measure-pos)))
-             (pos (if (ly:moment<? non-grace ZERO-MOMENT)
-                      (ly:moment-add measure-length non-grace)
+             (type (ly:moment-main test-beam))
+             (non-grace (ly:moment-main measure-pos))
+             (pos (if (negative? non-grace)
+                      (+ measure-length non-grace)
                       non-grace))
              (type-grouping (assoc-get type exceptions '()))
-             (default-rule (if (null? type-grouping)
-                               (larger-setting test-beam exceptions)
-                               '()))
-             (default-grouping (if (pair? default-rule)
-                                   (cdr default-rule)
-                                   '()))
-             (default-beat-length (if (pair? default-rule)
-                                      (car default-rule)
-                                      '()))
+             (default-rule (and (null? type-grouping)
+                                (larger-setting type exceptions)))
+             (default-grouping (and default-rule (cdr default-rule)))
+             (default-beat-length (and default-rule (car default-rule)))
              (exception-grouping (if (null? type-grouping)
                                      default-grouping
                                      type-grouping))
              (grouping-moment (if (null? type-grouping)
-                                  (fraction->moment default-beat-length)
-                                  test-beam))
-             (exception-moments (ending-moments
-                                 exception-grouping 0 grouping-moment)))
+                                  default-beat-length
+                                  type))
+             (exception-moments (and exception-grouping
+                                     (ending-moments
+                                      exception-grouping 0 grouping-moment))))
 
         (if (= dir START)
             ;; Start rules -- #t if beam is allowed to start
             (or beam-half-measure ;; Start anywhere, but option for mid-measure
-                (not (equal? (ly:moment-add pos pos) measure-length))
+                (not (= (+ pos pos) measure-length))
                 (not (= 3 (car time-signature-fraction))) ;; in triple meter
-                (not (= (cdr type) ;; when the beamed note is 1/6 of a measure
+                (not (= (denominator type) ;; when the beamed note is 1/6 of a measure
                         (* 2 (cdr time-signature-fraction)))))
             ;; End rules -- #t if beam is required to end
-            (or (= (ly:moment-main-numerator pos) 0) ;; end at measure beginning
-                (if (null? exception-grouping)
-                    (beat-end? pos beat-endings) ;; no exception, so check beat ending
-                    (member pos exception-moments))))))) ;; check exception rule
+            (or (zero? pos) ;; end at measure beginning
+                (if exception-grouping
+                    (beat-end? pos exception-moments) ;; check exception rule
+                    (beat-end? pos beat-endings))))))) ;; no exception, so check beat ending
+
+
+(define-public (extract-beam-exceptions music)
+  "Creates a value useful for setting @code{beamExceptions} from @var{music}."
+  (define (car> a b) (> (car a) (car b)))
+  (define (beatify! lst)
+    ;; takes a collection of end points, sorts them, and returns the
+    ;; non-zero differences as beaming pattern
+    (let ((s (sort-list! lst <)))
+      (remove! zero?
+               (map - s (cons 0 s)))))
+  (let ((res '()))
+    (let analyze ((m (unfold-repeats-fully (event-chord-reduce music)))
+                  (pos 0))
+      ;; enter beam ends from m starting at pos into res, return new pos
+      (cond ((music-is-of-type? m 'bar-check) 0)
+            ((music-is-of-type? m 'simultaneous-music)
+             (fold (lambda (m prev) (max (analyze m pos) prev))
+                   pos
+                   (ly:music-property m 'elements)))
+            ((not (music-is-of-type? m 'rhythmic-event))
+             (let ((elt (ly:music-property m 'element)))
+               (fold analyze
+                     (if (ly:music? elt) (analyze elt pos) pos)
+                     (ly:music-property m 'elements))))
+            ;; Have rhythmic event.
+            ((any
+              (lambda (art)
+                (and (music-is-of-type? art 'beam-event)
+                     (= (ly:music-property art 'span-direction START) STOP)))
+              (ly:music-property m 'articulations))
+             (let* ((len (duration-length (ly:music-property m 'duration)))
+                    (pos (+ pos len))
+                    (ass (assv len res)))
+               (cond ((or (zero? len) (not (integer? (/ pos len))))
+                      (ly:warning m (_ "Beam end fits no pattern")))
+                     (ass
+                      (set-cdr! ass (cons (/ pos len) (cdr ass))))
+                     (else
+                      (set! res (cons (list len (/ pos len)) res))))
+               pos))
+            (else
+             (+ pos (duration-length (ly:music-property m 'duration))))))
+
+    ;; takes the output from the loop, generates actual beam exceptions
+    (list
+     (cons 'end
+           (map!
+            (lambda (l)
+              (cons (car l)
+                    (beatify! (cdr l))))
+            (sort-list! res car>))))))
index 03c6f808156f88816b7fa6da999670b4b2891316..302936e49cf1ae8b55d285ae57de20f865e22270 100644 (file)
@@ -910,50 +910,51 @@ of the volta brackets relative to the bar lines."
                                        line-thickness
                                        1/2))
          (bar-array (ly:grob-object grob 'bars))
-         (bar-array-length (ly:grob-array-length bar-array))
          ;; the bar-array starts with the uppermost bar line grob that is
          ;; covered by the left edge of the volta bracket; more (span)
          ;; bar line grobs from other staves may follow
-         (left-bar-line (if (> bar-array-length 0)
-                            (ly:grob-array-ref bar-array 0)
-                            '()))
+         (left-bar-line (and (ly:grob-array? bar-array)
+                             (positive? (ly:grob-array-length bar-array))
+                             (ly:grob-array-ref bar-array 0)))
          ;; we need the vertical-axis-group-index of the left-bar-line
          ;; to find the corresponding right-bar-line
-         (vag-index (if (null? left-bar-line)
-                        -1
-                        (ly:grob-get-vertical-axis-group-index left-bar-line)))
+         (vag-index (and left-bar-line
+                         (ly:grob-get-vertical-axis-group-index left-bar-line)))
          ;; the bar line corresponding to the right edge of the volta bracket
          ;; is the last entry with the same vag-index, so we transform the array to a list,
-         ;; reverse it and search for suitable entries:
-         (filtered-grobs (filter (lambda (e)
-                                   (eq? (ly:grob-get-vertical-axis-group-index e)
-                                        vag-index))
-                                 (reverse (ly:grob-array->list bar-array))))
-         ;; we need the first one (if any)
-         (right-bar-line (if (pair? filtered-grobs)
-                             (car filtered-grobs)
-                             '()))
+         ;; reverse it and search for the first suitable entry from
+         ;; the back
+         (right-bar-line (and left-bar-line
+                              (find (lambda (e)
+                                      (eqv? (ly:grob-get-vertical-axis-group-index e)
+                                            vag-index))
+                                    (reverse (ly:grob-array->list bar-array)))))
          ;; the left-bar-line may be a #'<Grob Item >,
          ;; so we add "" as a fallback return value
-         (left-bar-glyph-name (if (null? left-bar-line)
-                                  (string annotation-char)
-                                  (ly:grob-property left-bar-line 'glyph-name "")))
-         (right-bar-glyph-name (if (null? right-bar-line)
-                                   (string annotation-char)
-                                   (ly:grob-property right-bar-line 'glyph-name "")))
-         (left-bar-broken (or (null? left-bar-line)
-                              (not (zero? (ly:item-break-dir left-bar-line)))))
-         (right-bar-broken (or (null? right-bar-line)
-                               (not (zero? (ly:item-break-dir right-bar-line)))))
+         (left-bar-glyph-name (if left-bar-line
+                                  (ly:grob-property left-bar-line 'glyph-name "")
+                                  (string annotation-char)))
+         (right-bar-glyph-name (if right-bar-line
+                                   (ly:grob-property right-bar-line 'glyph-name "")
+                                   (string annotation-char)))
+         ;; This is the original logic.  It flags left-bar-broken if
+         ;; there is no left-bar-line.  That seems strange.
+         (left-bar-broken (not (and left-bar-line
+                                    (zero? (ly:item-break-dir left-bar-line)))))
+         (right-bar-broken (not (and right-bar-line
+                                     (zero? (ly:item-break-dir
+                                             right-bar-line)))))
+         ;; Revert to current grob for getting layout info if no
+         ;; left-bar-line available
          (left-span-stencil-extent (ly:stencil-extent
                                     (span-bar::compound-bar-line
-                                     left-bar-line
+                                     (or left-bar-line grob)
                                      left-bar-glyph-name
                                      dummy-extent)
                                     X))
          (right-span-stencil-extent (ly:stencil-extent
                                      (span-bar::compound-bar-line
-                                      right-bar-line
+                                      (or right-bar-line grob)
                                       right-bar-glyph-name
                                       dummy-extent)
                                      X))
@@ -968,7 +969,7 @@ of the volta brackets relative to the bar lines."
               (- (max 0 (interval-end left-span-stencil-extent))
                  (max 0 (interval-end (ly:stencil-extent
                                        (bar-line::compound-bar-line
-                                        left-bar-line
+                                        (or left-bar-line grob)
                                         left-bar-glyph-name
                                         dummy-extent)
                                        X)))
index a131e7f3428d95870bcc3ec05b1643fe7d899552..ec54ed28c9ebb9c57542154356958d14acd30fce 100644 (file)
   (and (pair? x)
        (index? (car x)) (index? (cdr x))))
 
+(define-public (rational-or-procedure? x)
+  (or
+   (and (rational? x) (exact? x))
+   (procedure? x)))
+
 (define-public (number-or-grob? x)
   (or (ly:grob? x) (number? x)))
 
index 20d77ea72f5d100dbc5705f64b27a5023e74e057..69262b061dbb165b8307ec089f9d5ee203899005 100644 (file)
@@ -60,6 +60,9 @@ vertical alignment.")
 numbers.  Can be @code{numbers} for going back to the same number or
 @code{numbers-with-letters} for going back to the same number with letter
 suffixes.  No setting will not go back in measure-number time.")
+     (alternativeRestores ,symbol-list? "Timing variables that are
+restored to their value at the end of the first alternative in
+subsequent alternatives.")
      (associatedVoice ,string? "Name of the @code{Voice} that has the
 melody for this @code{Lyrics} line.")
      (autoAccidentals ,list? "List of different ways to typeset an
@@ -215,6 +218,17 @@ and @samp{bracketed}.")
 symbol go, measured in half staff spaces from the center of the
 staff.")
      (completionBusy ,boolean? "Whether a completion-note head is playing.")
+     (completionFactor ,rational-or-procedure?
+"When @code{Completion_heads_engraver} and
+@code{Completion_rest_engraver} need to split a note or rest with a
+scaled duration, such as @code{c2*3}, this specifies the scale factor
+to use for the newly-split notes and rests created by the engraver.
+
+If @code{#f}, the completion engraver uses the scale-factor of
+each duration being split.
+
+If set to a callback procedure, that procedure is called with the
+context of the completion engraver, and the duration to be split.")
      (completionUnit ,ly:moment? "Sub-bar unit of completion.")
      (connectArpeggios ,boolean? "If set, connect arpeggios across
 piano staff.")
@@ -444,12 +458,12 @@ associated with the current context.  Ranges from@tie{}@w{-1} to@tie{}1,
 where the values@tie{}@w{-1} (@code{#LEFT}),@tie{}0 (@code{#CENTER})
 and@tie{}1 (@code{#RIGHT}) correspond to hard left, center, and hard
 right, respectively.")
-     (midiReverbLevel ,number? "Reverb effect level for the MIDI channel
-associated with the current context.  Ranges from 0 to@tie{}1
-(0=off,@tie{}1=full effect).")
-     (midiChorusLevel ,number? "Chorus effect level for the MIDI channel
-associated with the current context.  Ranges from 0 to@tie{}1
-(0=off,@tie{}1=full effect).")
+     (midiReverbLevel ,number? "Reverb effect level for the MIDI
+channel associated with the current context.  Ranges from 0
+to@tie{}1 (0=off,@tie{}1=full effect).")
+     (midiChorusLevel ,number? "Chorus effect level for the MIDI
+channel associated with the current context.  Ranges from 0
+to@tie{}1 (0=off,@tie{}1=full effect).")
      (minimumFret ,number? "The tablature auto string-selecting
 mechanism selects the highest string with a fret at least
 @code{minimumFret}.")
index a5b0895c9bbfea3ccc2e23d9bfa26204d6c82e54..cfa2cfb4c1ef6752e84a6be785a689ddd317111d 100644 (file)
@@ -170,6 +170,9 @@ when a spanner is broken at a line break.")
 ;;;
 ;;; c
 ;;;
+     (chord-dots-limit ,integer? "Limits the column of dots
+on each chord to the height of the chord plus
+@code{chord-dots-limit} staff-positions.")
      (circled-tip ,boolean? "Put a circle at start/@/end of
 hairpins (al/@/del niente).")
      (clip-edges ,boolean? "Allow outward pointing beamlets at the
@@ -1015,7 +1018,8 @@ texts.")
 ;;;
 ;;; x
 ;;;
-     (X-extent ,number-pair? "Hard coded extent in X@tie{}direction.")
+     (X-extent ,number-pair? "Extent (size) in the X@tie{}direction,
+measured in staff-space units, relative to object's reference point.")
      (X-offset ,number? "The horizontal amount that this object is
 moved relative to its X-parent.")
      (X-positions ,number-pair? "Pair of X staff coordinates of a spanner
@@ -1026,7 +1030,8 @@ in the form @code{(@var{left} . @var{right})}, where both @var{left} and
 ;;;
 ;;; y
 ;;;
-     (Y-extent ,number-pair? "Hard coded extent in Y@tie{}direction.")
+     (Y-extent ,number-pair? "Extent (size) in the Y@tie{}direction,
+measured in staff-space units, relative to object's reference point.")
      (Y-offset ,number? "The vertical amount that this object is moved
 relative to its Y-parent.")
 
index a4e0d52a760b45a237b12438cae84932586fbd1f..64be8844ceba21b71830a38d4123e667a3b6adf3 100644 (file)
     (DotColumn
      . (
         (axes . (,X))
+        (chord-dots-limit . 3)
         (direction . ,RIGHT)
         (positioning-done . ,ly:dot-column::calc-positioning-done)
         (X-extent . ,ly:axis-group-interface::width)
         (cross-staff . ,ly:script-interface::calc-cross-staff)
         (direction . ,ly:script-interface::calc-direction)
         (font-encoding . fetaMusic)
+        (horizon-padding . 0.1) ; to avoid interleaving with accidentals
         (positioning-done . ,ly:script-interface::calc-positioning-done)
         (side-axis . ,Y)
 
         (axes . (,X))
         (direction . ,RIGHT)
         (font-size . -4)
+        ;; minimum shift to the right, in case the parent note has no stem
+        (minimum-space . 2.5)
+        (horizon-padding . 0.1) ; to avoid interleaving with augmentation dots
         (padding . 0.3)
         (side-axis . ,X)
         (stencil . ,parenthesize-elements)
         (stencils . ,parentheses-item::calc-parenthesis-stencils)
-        ;; offset a bit to the right, further if needed to clear the main note
-        (X-offset . ,(lambda (grob)
-                       (ly:side-position-interface::x-aligned-side grob 2.5)))
+        (X-offset . ,ly:side-position-interface::x-aligned-side)
         (Y-extent . ,grob::always-Y-extent-from-stencil)
         (meta . ((class . Item)
                  (interfaces . (axis-group-interface
 
     (VoltaBracket
      . (
+        (baseline-skip . 1.7)
         (direction . ,UP)
         (edge-height . (2.0 . 2.0)) ;; staff-space;
         (font-encoding . fetaText)
index 9e5528f5bb2a7eafa0d7eb1d6de990463245f650..fa98be0872a465a5a16cb96527ec03945abf1a52 100644 (file)
@@ -1014,13 +1014,9 @@ samplePath =
 
 (define-markup-list-command (score-lines layout props score)
   (ly:score?)
-  "
-This is the same as the @code{\\score} markup but delivers its
-systems as a list of lines.  This is not usually called directly by
-the user.  Instead, it is called when the parser encounters
-@code{\\score} in a context where only markup lists are allowed.  When
-used as the argument of a toplevel @code{\\markuplist}, the result can
-be split across pages."
+  "This is the same as the @code{\\score} markup but delivers its
+systems as a list of lines.  Its @var{score} argument is entered in
+braces like it would be for @code{\\score}."
   (let ((output (ly:score-embedded-format score layout)))
 
     (if (ly:music-output? output)
@@ -3958,7 +3954,7 @@ Make a fraction of two markups.
 (define-markup-command (normal-size-super layout props arg)
   (markup?)
   #:category font
-  #:properties ((baseline-skip))
+  #:properties ((font-size 0))
   "
 @cindex setting superscript in standard font size
 
@@ -3974,13 +3970,12 @@ Set @var{arg} in superscript with a normal font size.
 @end lilypond"
   (ly:stencil-translate-axis
    (interpret-markup layout props arg)
-   (* 0.5 baseline-skip) Y))
+   (* 1.0 (magstep font-size)) Y))
 
 (define-markup-command (super layout props arg)
   (markup?)
   #:category font
-  #:properties ((font-size 0)
-                (baseline-skip))
+  #:properties ((font-size 0))
   "
 @cindex superscript text
 
@@ -4001,7 +3996,7 @@ Set @var{arg} in superscript.
     layout
     (cons `((font-size . ,(- font-size 3))) props)
     arg)
-   (* 0.5 baseline-skip)
+   (* 1.0 (magstep font-size)) ; original font-size
    Y))
 
 (define-markup-command (translate layout props offset arg)
@@ -4026,8 +4021,7 @@ is a pair of numbers representing the displacement in the X and Y axis.
 (define-markup-command (sub layout props arg)
   (markup?)
   #:category font
-  #:properties ((font-size 0)
-                (baseline-skip))
+  #:properties ((font-size 0))
   "
 @cindex subscript text
 
@@ -4049,13 +4043,13 @@ Set @var{arg} in subscript.
     layout
     (cons `((font-size . ,(- font-size 3))) props)
     arg)
-   (* -0.5 baseline-skip)
+   (* -0.75 (magstep font-size)) ; original font-size
    Y))
 
 (define-markup-command (normal-size-sub layout props arg)
   (markup?)
   #:category font
-  #:properties ((baseline-skip))
+  #:properties ((font-size 0))
   "
 @cindex setting subscript in standard font size
 
@@ -4071,7 +4065,7 @@ Set @var{arg} in subscript with a normal font size.
 @end lilypond"
   (ly:stencil-translate-axis
    (interpret-markup layout props arg)
-   (* -0.5 baseline-skip)
+   (* -0.75 (magstep font-size))
    Y))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
index fd759d52d154cae4c76e326fe09f7ea3303bcc77..32a747aba8504db978364bac70075ece2abe0179 100644 (file)
@@ -526,8 +526,17 @@ Otherwise, return #f."
                  (map-in-order (lambda (event)
                                  (music->lily-string event parser))
                                (ly:music-property note 'articulations))))
-        (else ;; unknown?
-         "")))
+        (else
+         ;; pure duration
+         ;; FIXME: { c4 c4 4 4 } must not be output as { c4 c 4 4 }
+         ;; quite tricky to do.  Do it when outputting sequences?
+         (format #f "~a~{~a~}"
+                 (duration->lily-string (ly:music-property note 'duration)
+                                        #:force-duration #t
+                                        #:remember #t)
+                 (map-in-order (lambda (event)
+                                 (music->lily-string event parser))
+                               (ly:music-property note 'articulations))))))
 
 (define-display-method ClusterNoteEvent (note parser)
   (simple-note->lily-string note parser))
index 5c9c12538e03b761798e17122d5ac807ac84ce4b..4469f88ff0ad8646f2083962e69133bcd2e6bc15 100644 (file)
@@ -119,6 +119,12 @@ This property can only be defined as initializer in
 whether to allow, forbid or force a line break.")
 
      (metronome-count ,number-or-pair? "How many beats in a minute?")
+     (midi-extra-velocity ,integer? "How much louder or softer should
+this note be in MIDI output? The default is 0.")
+     (midi-length ,procedure? "Function to determine how long to play
+a note in MIDI. It should take a moment (the written length of the
+note) and a context, and return a moment (the length to play the
+note).")
      (moment ,ly:moment? "The moment at which an event happens.")
      (music-cause ,ly:music? "The music object that is the cause of
 an event.")
index d92affb11ccad4c45953c36a81ab8128af576335..bb7dc555049e566cfe047bf1911a0a3164636bed 100644 (file)
@@ -84,7 +84,9 @@
    "/output-scale "
    (number->string (ly:output-def-lookup layout 'output-scale)) " def\n"
    (output-entry "page-height" 'paper-height)
-   (output-entry "page-width" 'paper-width)))
+   (output-entry "page-width" 'paper-width)
+   (if (ly:get-option 'strokeadjust) "true setstrokeadjust\n" "")
+   ))
 
 (define (dump-page outputter page page-number page-count landscape?)
   (ly:outputter-dump-string
@@ -97,7 +99,6 @@
         "")
     "%%EndPageSetup\n"
     "\n"
-    "true setstrokeadjust\n"
     "gsave 0 paper-height translate set-ps-scale-to-lily-scale\n"))
   (ly:outputter-dump-stencil outputter page)
   (ly:outputter-dump-string outputter "stroke grestore\nshowpage\n"))
index 7e5ab5858cb4750fba15b5f22d8b092c678fe810..7ad02ec09e3c921b4108ddb014757eb5017823dd 100644 (file)
@@ -28,6 +28,8 @@
     (max-slope-factor . 10)
     (free-head-distance . 0.3)
     (free-slur-distance . 0.8)
+    (gap-to-staffline-inside . 0.2)
+    (gap-to-staffline-outside . 0.1)
     (extra-object-collision-penalty . 50)
     (accidental-collision . 3)
     (extra-encompass-free-distance . 0.3)
index 43b05e57c20d8fa6b5b9e784d434cb5c564d1c58..570c7407750e75d16d693628950d127b2f465158 100644 (file)
   (cons (ly:moment-main-numerator moment)
         (ly:moment-main-denominator moment)))
 
+(define-public (seconds->moment s context)
+  "Return a moment equivalent to s seconds at the current tempo."
+  (ly:moment-mul (ly:context-property context 'tempoWholesPerMinute)
+                 (ly:make-moment (/ s 60))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; durations
 
@@ -116,6 +121,16 @@ non-visual scale factor 1."
 duration (base note length and dot count), as a number of whole notes."
   (duration-length (duration-visual dur)))
 
+(define-public (unity-if-multimeasure context dur)
+  "Given a context and a duration, return @code{1} if the duration is
+longer than the @code{measureLength} in that context, and @code{#f} otherwise.
+This supports historic use of @code{Completion_heads_engraver} to split
+@code{c1*3} into three whole notes."
+  (if (ly:moment<? (ly:context-property context 'measureLength)
+                   (ly:duration-length dur))
+    1
+    #f))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; arithmetic
 (define-public (average x . lst)
index 9e47fc0df7548dcdc55d049f7afbfa7997a882c0..86054217b85d9ef6f6f0133f5de5ee428bf37ffd 100644 (file)
@@ -330,6 +330,12 @@ floating point exceptions.")
      #t
      "Don't use directories from input files while
 constructing output file names.")
+    (strokeadjust
+     #f
+     "Set the PostScript strokeadjust operator explicitly.
+This employs different drawing primitives, resulting in
+large PDF file size increases but often markedly better
+PDF previews.")
     (svg-woff
      #f
      "Use woff font files in SVG backend.")
@@ -663,6 +669,7 @@ messages into errors.")
     (,number-or-string? . "number or string")
     (,number-pair? . "pair of numbers")
     (,number-pair-list? . "list of number pairs")
+    (,rational-or-procedure? . "an exact rational or procedure")
     (,rhythmic-location? . "rhythmic location")
     (,scheme? . "any type")
     (,string-or-pair? . "string or pair")
index b3d7f3f0f01cf942ef71f7db0caa19fd47db742f..5fe0bfbbefef410acd76fdf536c2b343695eaff9 100644 (file)
@@ -73,7 +73,7 @@
    parser
    (format #f
            (_ "wrong type for argument ~a.  Expecting ~a, found ~s")
-           n (type-name pred) arg)
+           n (type-name pred) (music->make-music arg))
    location))
 
 (define-ly-syntax-simple (void-music)
index 383b7f3f6defb7e85373397b08b7b1000aaec08c..592cff33c320ab0173e4ca319fa068f75ba0c829 100644 (file)
@@ -20,6 +20,7 @@
 (use-modules (scm safe-utility-defs))
 
 (use-modules (ice-9 optargs))
+(use-modules (srfi srfi-11))
 
 ;;; ly:music-property with setter
 ;;; (ly:music-property my-music 'elements)
@@ -382,6 +383,28 @@ beats to be distinguished."
               (unfold-repeats e)))
     music))
 
+(define-public (unfold-repeats-fully music)
+  "Unfolds repeats and expands the resulting @code{unfolded-repeated-music}."
+  (map-some-music
+   (lambda (m)
+     (and (music-is-of-type? m 'unfolded-repeated-music)
+          (make-sequential-music
+           (ly:music-deep-copy
+            (let loop ((n (ly:music-property m 'repeat-count))
+                       (alts (ly:music-property m 'elements))
+                       (body (ly:music-property m 'element)))
+              (cond ((<= n 0) '())
+                    ((null? alts)
+                     (cons body (loop (1- n) alts body)))
+                    (else
+                     (cons* body (car alts)
+                            (loop (1- n)
+                                  (if (pair? (cdr alts))
+                                      (cdr alts)
+                                      alts)
+                                  body)))))))))
+   (unfold-repeats music)))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; property setting music objs.
 
@@ -614,9 +637,10 @@ in @var{grob}."
   (make-music 'PropertyUnset
               'symbol sym))
 
-(define-safe-public (make-articulation name)
-  (make-music 'ArticulationEvent
-              'articulation-type name))
+(define-safe-public (make-articulation name . properties)
+  (apply make-music 'ArticulationEvent
+         'articulation-type name
+         properties))
 
 (define-public (make-lyric-event string duration)
   (make-music 'LyricEvent
@@ -728,7 +752,8 @@ duration is replaced with the specified @var{duration}."
         (set! (ly:music-property repeat-chord 'articulations)
               (append!
                (set-origin! (ly:music-deep-copy arts))
-               (ly:music-property repeat-chord 'articulations))))))
+               (ly:music-property repeat-chord 'articulations)))))
+  repeat-chord)
 
 
 (define-public (expand-repeat-chords! event-types music)
@@ -747,8 +772,7 @@ respective predecessor chord."
                 last-chord))
            (last-chord
             (set! (ly:music-property music 'duration) '())
-            (copy-repeat-chord last-chord music chord-repeat event-types)
-            music)
+            (copy-repeat-chord last-chord music chord-repeat event-types))
            (else
             (ly:music-warning music (_ "Bad chord repetition"))
             #f)))
@@ -757,6 +781,73 @@ respective predecessor chord."
                 (ly:music-property music 'elements)))))
   music)
 
+;;; This does _not_ copy any articulations.  Rationale: one main
+;;; incentive for pitch-repeating durations is after ties, such that
+;;; 4~2~8. can stand in for a 15/16 note in \partial 4 position.  In
+;;; this use case, any repeated articulations will be a nuisance.
+;;;
+;;; String assignments in TabStaff might seem like a worthwhile
+;;; exception, but they would be better tackled by the respective
+;;; engravers themselves (see issue 3662).
+;;;
+;;; Repeating chords as well seems problematic for things like
+;;; \score {
+;;;   <<
+;;;     \new Staff { c4 c c <c e> }
+;;;     \new RhythmicStaff { 4 4 4 4 }
+;;;   >>
+;;; }
+;;;
+;;; However, because of MIDI it is not advisable to use RhythmicStaff
+;;; without any initial pitch/drum-type.  For music functions taking
+;;; pure rhythms as an argument, the running of expand-repeat-notes!
+;;; at scorification time is irrelevant: at that point of time, the
+;;; music function has already run.
+
+(define-public (expand-repeat-notes! music)
+  "Walks through @var{music} and gives pitchless notes (not having a
+pitch in code{pitch} or a drum type in @code{drum-type}) the pitch(es)
+from the predecessor note/chord if available."
+  (let ((last-pitch #f))
+    (map-some-music
+     (lambda (m)
+       (define (set-and-ret last)
+         (set! last-pitch last)
+         m)
+       (cond
+        ((music-is-of-type? m 'event-chord)
+         (set-and-ret m))
+        ((music-is-of-type? m 'note-event)
+         (cond
+          ((or (ly:music-property m 'pitch #f)
+               (ly:music-property m 'drum-type #f))
+           => set-and-ret)
+          ;; ok, naked rhythm.  Go through the various cases of
+          ;; last-pitch
+          ;; nothing available: just keep as-is
+          ((not last-pitch) m)
+          ((ly:pitch? last-pitch)
+           (set! (ly:music-property m 'pitch) last-pitch)
+           m)
+          ((symbol? last-pitch)
+           (set! (ly:music-property m 'drum-type) last-pitch)
+           m)
+          ;; Ok, this is the big bad one: the reference is a chord.
+          ;; For now, we use the repeat chord logic.  That's not
+          ;; really efficient as cleaning out all articulations is
+          ;; quite simpler than what copy-repeat-chord does.
+          (else
+           (copy-repeat-chord last-pitch
+                              (make-music 'EventChord
+                                          'elements
+                                          (ly:music-property m 'articulations)
+                                          'origin
+                                          (ly:music-property m 'origin))
+                              (ly:music-property m 'duration)
+                              '(rhythmic-event)))))
+        (else #f)))
+     music)))
+
 ;;; splitting chords into voices.
 (define (voicify-list lst number)
   "Make a list of Musics.
@@ -1255,12 +1346,13 @@ then revert skipTypesetting."
      (else music))))
 
 
-(define-public toplevel-music-functions
+(define-session-public toplevel-music-functions
   (list
    (lambda (music parser) (expand-repeat-chords!
                            (cons 'rhythmic-event
                                  (ly:parser-lookup parser '$chord-repeat-events))
                            music))
+   (lambda (music parser) (expand-repeat-notes! music))
    (lambda (music parser) (voicify-music music))
    (lambda (x parser) (music-map music-check-error x))
    (lambda (x parser) (music-map precompute-music-length x))
@@ -1879,38 +1971,111 @@ yourself."
   (map (lambda (x) (ly:music-property x 'pitch))
        (event-chord-notes event-chord)))
 
-(defmacro-public make-relative (pitches last-pitch music)
-  "The list of pitch-carrying variables in @var{pitches} is used as a
-sequence for creating relativable music from @var{music}.
-The variables in @var{pitches} are, when considered inside of
-@code{\\relative}, all considered to be specifications to the preceding
-variable.  The first variable is relative to the preceding musical
-context, and @var{last-pitch} specifies the pitch passed as relative
-base onto the following musical context."
+(define-public (event-chord-reduce music)
+  "Reduces event chords in @var{music} to their first note event,
+retaining only the chord articulations.  Returns the modified music."
+  (map-some-music
+   (lambda (m)
+     (and (music-is-of-type? m 'event-chord)
+          (let*-values (((notes arts) (partition
+                                       (lambda (mus)
+                                         (music-is-of-type? mus 'rhythmic-event))
+                                       (ly:music-property m 'elements)))
+                        ((dur) (ly:music-property m 'duration))
+                        ((full-arts) (append arts
+                                             (ly:music-property m 'articulations)))
+                        ((first-note) (and (pair? notes) (car notes))))
+            (cond (first-note
+                   (set! (ly:music-property first-note 'articulations)
+                         full-arts)
+                   first-note)
+                  ((ly:duration? dur)
+                   ;; A repeat chord. Produce an unpitched note.
+                   (make-music 'NoteEvent
+                               'duration dur
+                               'articulations full-arts))
+                  (else
+                   (ly:music-error m (_ "Missing duration"))
+                   (make-music 'NoteEvent
+                               'duration (ly:make-duration 2 0 0)
+                               'articulations full-arts))))))
+   music))
+
+
+(defmacro-public make-relative (variables reference music)
+  "The list of pitch or music variables in @var{variables} is used as
+a sequence for creating relativable music from @var{music}.
+
+When the constructed music is used outside of @code{\\relative}, it
+just reflects plugging in the @var{variables} into @var{music}.
+
+The action inside of @code{\\relative}, however, is determined by
+first relativizing the surrogate @var{reference} with the variables
+plugged in and then using the variables relativized as a side effect
+of relativizing @var{reference} for evaluating @var{music}.
+
+Since pitches don't have the object identity required for tracing the
+effect of the reference call, they are replaced @emph{only} for the
+purpose of evaluating @var{reference} with simple pitched note events.
+
+The surrogate @var{reference} expression has to be written with that
+in mind.  In addition, it must @emph{not} contain @emph{copies} of
+music that is supposed to be relativized but rather the
+@emph{originals}.  This @emph{includes} the pitch expressions.  As a
+rule, inside of @code{#@{@dots{}#@}} variables must @emph{only} be
+introduced using @code{#}, never via the copying construct @code{$}.
+The reference expression will usually just be a sequential or chord
+expression naming all variables in sequence, implying that following
+music will be relativized according to the resulting pitch of the last
+or first variable, respectively.
+
+Since the usual purpose is to create more complex music from general
+arguments and since music expression parts must not occur more than
+once, one @emph{does} generally need to use copying operators in the
+@emph{replacement} expression @var{music} when using an argument more
+than once there.  Using an argument more than once in @var{reference},
+in contrast, does not make sense.
+
+There is another fine point to mind: @var{music} must @emph{only}
+contain freshly constructed elements or copied constructs.  This will
+be the case anyway for regular LilyPond code inside of
+@code{#@{@dots{}#@}}, but any other elements (apart from the
+@var{variables} themselves which are already copied) must be created
+or copied as well.
+
+The reason is that it is usually permitted to change music in-place as
+long as one does a @var{ly:music-deep-copy} on it, and such a copy of
+the whole resulting expression will @emph{not} be able to copy
+variables/values inside of closures where the information for
+relativization is being stored.
+"
 
   ;; pitch and music generator might be stored instead in music
   ;; properties, and it might make sense to create a music type of its
   ;; own for this kind of construct rather than using
   ;; RelativeOctaveMusic
-  (define ((make-relative::to-relative-callback pitches p->m p->p) music pitch)
-    (let* ((chord (make-event-chord
-                   (map
-                    (lambda (p)
-                      (make-music 'NoteEvent
-                                  'pitch p))
-                    pitches)))
-           (pitchout (begin
-                       (ly:make-music-relative! chord pitch)
-                       (event-chord-pitches chord))))
-      (set! (ly:music-property music 'element)
-            (apply p->m pitchout))
-      (apply p->p pitchout)))
+  (define ((make-relative::to-relative-callback variables music-call ref-call)
+           music pitch)
+    (let* ((ref-vars (map (lambda (v)
+                            (if (ly:pitch? v)
+                                (make-music 'NoteEvent 'pitch v)
+                                (ly:music-deep-copy v)))
+                          variables))
+           (after-pitch (ly:make-music-relative! (apply ref-call ref-vars) pitch))
+           (actual-vars (map (lambda (v r)
+                               (if (ly:pitch? v)
+                                   (ly:music-property r 'pitch)
+                                   r))
+                             variables ref-vars))
+           (rel-music (apply music-call actual-vars)))
+      (set! (ly:music-property music 'element) rel-music)
+      after-pitch))
   `(make-music 'RelativeOctaveMusic
                'to-relative-callback
                (,make-relative::to-relative-callback
-                (list ,@pitches)
-                (lambda ,pitches ,music)
-                (lambda ,pitches ,last-pitch))
+                (list ,@variables)
+                (lambda ,variables ,music)
+                (lambda ,variables ,reference))
                'element ,music))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
index 82e22fe59197e97ae601849beccbcafa7e495626..97efdce3d88578c40dc9c680cbe1cd741a748f7e 100644 (file)
@@ -26,7 +26,7 @@
 ;;; time signature.  Each default-properties set can contain the
 ;;; following entries:
 ;;;
-;;;   (baseMoment . (numerator . denominator))
+;;;   (baseMoment . (/ numerator denominator))
 ;;;   (beatStructure . structure-list)
 ;;;   (beamExceptions . (alist of beam exceptions that don't follow beats))
 ;;;
@@ -37,7 +37,7 @@
 ;;;
 ;;;   grouping-rules is an alist containing (beam-type . grouping-list) entries
 ;;;
-;;;     beam-type is (numerator . denominator)
+;;;     beam-type is the length as a rational number
 ;;;     grouping-list is a list that specifies the
 ;;;     number of stems of the given duration that are grouped in a beamed unit.
 ;;;     For an exception, the duration used is beam-type.  For measureBeats,
 ;;;
 ;;;     If an exception is specified for a given beam-type, it will apply to all
 ;;;     beams of shorter durations that don't have an individual exception, so
-;;;     ((1 . 8) . (3 3 2))
+;;;     (1/8 . (3 3 2))
 ;;;     will cause all primary beams to be broken at 3/8, 6/8, and 8/8.
 ;;;
-;;;     ((1 . 32) . (16 8 4 4))
+;;;     (1/32 . (16 8 4 4))
 ;;;     will cause all 1/32, 1/64, and 1/128 beams to be broken at 1/2, 3/4,
 ;;;     7/8, and 8/8.
 ;;;
+;;;     Tuplets are referenced using their actual (scaled) length, so
+;;;     a 3/2 tuplet of the 1/8 kind would get exceptions looked up
+;;;     under 1/12.
+;;;
 ;;; If no values are given for baseMoment and measureBeats, default values
 ;;;   will be assigned:
-;;;   baseMoment gets the value (ly:make-moment 1  time-signature-denominator)
+;;;   baseMoment gets the value (/ time-signature-denominator)
 ;;;   beatStructure gets a list of (3 3 3 ...), where the number of entries is the
 ;;;     number of beats, each containing 3 base-moments, if the time
 ;;;     signature numerator is greater than 3 and divisible by 3, and
 ;;;     a list of (1 1 1 ...), where the number of entries is the
 ;;;     number of base moments in a measure otherwise.
-;;;
-;;;       NOTE: numerator is kept in beam-type because of
-;;;             tuplets, e.g. (2 . 24) = (2 . 3) * (1 . 8)
-;;;             for eighth-note triplets.
-;;;
 
 (define-public default-time-signature-settings
   '(
     ;; in 2/2 time:
     ;;   use defaults, but end beams with 32nd notes each 1 4 beat
     ((2 . 2) .
-     ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8))))))))
+     ((beamExceptions . ((end . ((1/32 . (8 8 8 8))))))))
 
     ;; in 2/4, 2/8 and 2/16 time:
     ;;   use defaults, so no entries are necessary
@@ -80,7 +79,7 @@
     ;;   use defaults, but end beams with 32nd notes and higher each 1 4 beat
 
     ((3 . 2) .
-     ((beamExceptions . ((end .  (((1 . 32) . (8 8 8 8 8 8))))))))
+     ((beamExceptions . ((end .  ((1/32 . (8 8 8 8 8 8))))))))
 
     ;; in 3 4 time:
     ;;   use defaults, but combine all beats into a unit if possible
     ;;   in order to avoid beaming every beam type for the entire measure, we set
     ;;   triplets back to every beat.
     ((3 . 4) .
-     ((beamExceptions . ((end . (((1 . 8) . (6))            ;1/8 note whole measure
-                                 ((1 . 12) . (3 3 3)))))))) ;Anything shorter by beat
+     ((beamExceptions . ((end . ((1/8 . (6))            ;1/8 note whole measure
+                                 (1/12 . (3 3 3)))))))) ;Anything shorter by beat
 
     ;; in 3 8  time:
     ;;   beam entire measure together
-    ((3 . 8) . ((beamExceptions . ((end . (((1 . 8) . (3))))))))
+    ((3 . 8) . ((beamExceptions . ((end . ((1/8 . (3))))))))
 
     ;; in 3 16 time:
     ;;   use defaults -- no entries necessary
     ;; in 4 2 time:
     ;;   use defaults, but end beams with 16th notes or finer each 1 4 beat
     ((4 . 2) .
-     ((beamExceptions . ((end . (((1 . 16) . (4 4 4 4 4 4 4 4))))))))
+     ((beamExceptions . ((end . ((1/16 . (4 4 4 4 4 4 4 4))))))))
 
     ;; in 4 4 (common) time:
     ;;   use defaults, but combine beats 1,2 and 3,4 if only 8th notes
     ;;         ly/engraver-init.ly where the default time signature is set
     ;;         are set
     ((4 . 4) .
-     ((beamExceptions . ((end . (((1 . 8) . (4 4))  ; 1/8 notes half measure
-                                 ((1 . 12) . (3 3 3 3)))))))) ;Anything shorter by beat
+     ((beamExceptions . ((end . ((1/8 . (4 4))  ; 1/8 notes half measure
+                                 (1/12 . (3 3 3 3)))))))) ;Anything shorter by beat
 
     ;; in 4/8 time:
     ;;   combine beats 1 and 2, so beam in 2
     ;; in 6 4 time:
     ;;   use defaults, but end beams with 32nd or finer each 1/4 beat
     ((6 . 4) .
-     ((beamExceptions . ((end .  (((1 . 16) . (4 4 4 4 4 4))))))))
+     ((beamExceptions . ((end .  ((1/16 . (4 4 4 4 4 4))))))))
 
     ;; in 6 8 time:
     ;;   use defaults, so no entries necessary
     ;; in 9 4 time:
     ;;   use defaults, but end beams with 32nd or finer each 1 4 beat
     ((9 . 4) .
-     ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8 8 8 8 8))))))))
+     ((beamExceptions . ((end . ((1/32 . (8 8 8 8 8 8 8 8))))))))
 
     ;; in 9 8 time
     ;;   use defaults, so no entries necessary
     ;; in 12 4 time:
     ;;   use defaults, but end beams with 32nd or finer notes each 1 4 beat
     ((12 . 4) .
-     ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8 8 8 8 8 8 8 8 8))))))))
+     ((beamExceptions . ((end . ((1/32 . (8 8 8 8 8 8 8 8 8 8 8 8))))))))
 
     ;; in 12 8 time:
     ;;   use defaults, so no entries necessary
index dafb50c0ef4392a7fa13f1aae527ce72acd17be2..9f645b59295b8d797fc790af527d050a5f86da72 100644 (file)
@@ -85,8 +85,11 @@ Generate("%(filename)s-%(design_size)d.woff");
     open (path, 'w').write (script)
 
     subfonts = ['feta%(design_size)d',
-          'parmesan%(design_size)d',
-          'feta-alphabet%(design_size)d']
+                'feta-noteheads%(design_size)d',
+                'feta-flags%(design_size)d',
+                'parmesan%(design_size)d',
+                'parmesan-noteheads%(design_size)d',
+                'feta-alphabet%(design_size)d']
 
     ns = []
     for s in subfonts:
@@ -98,10 +101,10 @@ Generate("%(filename)s-%(design_size)d.woff");
 
     path = os.path.join (outdir, '%s-%d.dep' % (filename, design_size))
 
-    deps = r'''%(filename)s-%(design_size)d.otf: $(outdir)/feta%(design_size)d.pfa \
- $(outdir)/parmesan%(design_size)d.pfa  \
- $(outdir)/feta-alphabet%(design_size)d.pfa feta%(design_size)d.otf-table \
$(outdir)/feta-alphabet%(design_size)d.pfa feta%(design_size)d.otf-gtable
+    deps = r'''%(filename)s-%(design_size)d.otf: $(outdir)/feta%(design_size)d.pfb \
+ $(outdir)/parmesan%(design_size)d.pfb  \
+ $(outdir)/feta-alphabet%(design_size)d.pfb feta%(design_size)d.otf-table \
+ feta%(design_size)d.otf-gtable
 ''' % vars()
     open (path, 'w').write (deps)
 
index f191d0aa8fcc3a0941e01f8c4f829d5cd90a8e8f..7c193987ec51788b47fd22be28d101a57ccfe984 100644 (file)
@@ -264,6 +264,6 @@ for filenm in files:
     open (global_lisp_nm, 'w').write (global_lisp_table (g))
     if depfile_nm:
         open (depfile_nm, 'wb').write (get_deps (deps,
-                                                 [base + '.log', base + '.dvi', base + '.pfa',
+                                                 [base + '.log', base + '.dvi',
                                                   depfile_nm,
                                                   base + '.pfb']))
index 641d763713c979c06dfe0621e19959303765403d..ede9d4a98b81ea7309288364603c2a767cdca00a 100644 (file)
@@ -292,17 +292,18 @@ def do_one_file (infile_name):
             # Note that last_change can be set even if the result is
             # the same if two conversion rules cancelled out
             if result == input:
-                # check the y in x.y.z  (minor version number)
-                previous_stable = (last[0], 2*(last[1]/2), 0)
-                if ((last[0:2] != from_version[0:2]) and
-                    (previous_stable > from_version)):
-                    # previous stable version
-                    last = previous_stable
-                else:
-                    # make no (actual) change to the version number
-                    last = from_version
+                # make no (actual) change to the version number
+                last = from_version
             else:
                 last = last_change
+                # If the last update was to an unstable version
+                # number, and the final update target is no longer in
+                # the same unstable series, we update to the stable
+                # series following the unstable version.
+                if last[1]%2: # unstable
+                    next_stable = (last[0], last[1]+1, 0)
+                    if next_stable <= to_version:
+                        last = next_stable
 
         newversion = r'\version "%s"' % tup_to_str (last)
         if lilypond_version_re.search (result):