]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation
authorJean-Charles Malahieude <lilyfan@orange.fr>
Sun, 31 Aug 2014 10:24:26 +0000 (12:24 +0200)
committerJean-Charles Malahieude <lilyfan@orange.fr>
Sun, 31 Aug 2014 10:24:26 +0000 (12:24 +0200)
98 files changed:
Documentation/contributor/issues.itexi
Documentation/de/essay/engraving.itely
Documentation/de/notation/spacing.itely
Documentation/es/essay/engraving.itely
Documentation/es/extending/programming-interface.itely
Documentation/es/notation/spacing.itely
Documentation/essay/engraving.itely
Documentation/extending/programming-interface.itely
Documentation/extending/scheme-tutorial.itely
Documentation/fr/essay/engraving.itely
Documentation/fr/extending/programming-interface.itely
Documentation/fr/notation/editorial.itely
Documentation/fr/notation/spacing.itely
Documentation/ja/notation/spacing.itely
Documentation/ly-examples/cary-layout.ily
Documentation/notation/changing-defaults.itely
Documentation/notation/chords.itely
Documentation/notation/editorial.itely
Documentation/notation/notation-appendices.itely
Documentation/notation/spacing.itely
Documentation/notation/vocal.itely
Documentation/snippets/displaying-grob-ancestry.ly
Documentation/snippets/new/displaying-grob-ancestry.ly [new file with mode: 0644]
Documentation/snippets/new/vocal-ensemble-template-with-automatic-piano-reduction.ly [new file with mode: 0644]
Documentation/snippets/new/vocal-ensemble-template.ly [new file with mode: 0644]
Documentation/snippets/vocal-ensemble-template-with-automatic-piano-reduction.ly
Documentation/snippets/vocal-ensemble-template.ly
Documentation/web/news-front.itexi
Documentation/web/news.itexi
VERSION
input/regression/accidental-unbroken-tie-spacing.ly
input/regression/add-stem-support.ly
input/regression/baerenreiter-sarabande.ly
input/regression/clef-transposition-placement.ly
input/regression/divisi-staves.ly [new file with mode: 0644]
input/regression/dynamics-empty.ly
input/regression/ferneyhough-hairpins.ly
input/regression/lilypond-book/GNUmakefile
input/regression/lilypond-book/include.ly
input/regression/lilypond-book/melody.ly [new file with mode: 0644]
input/regression/lilypond-book/tex-include-file.lytex
input/regression/lilypond-book/tex-include-options.lytex
input/regression/lilypond-book/texinfo-include-file.tely
input/regression/lyric-combine-nullvoice.ly [new file with mode: 0644]
input/regression/markup-cyclic-reference.ly
input/regression/morgenlied.ly
input/regression/mozart-hrn-3.ly
input/regression/note-names-context.ly
input/regression/override-nest.ly
input/regression/page-breaking-min-distance.ly
input/regression/page-spacing.ly
input/regression/page-top-space.ly
input/regression/paper-nested-override.ly
input/regression/paper-nested-override2.ly
input/regression/scheme-text-spanner.ly
input/regression/skyline-point-extent.ly
input/regression/typography-demo.ly
lily/accidental.cc
lily/auto-beam-engraver.cc
lily/clef-modifier.cc [new file with mode: 0644]
lily/context-property.cc
lily/context-scheme.cc
lily/engraver-group.cc
lily/engraver.cc
lily/hara-kiri-group-spanner.cc
lily/include/accidental-interface.hh
lily/include/context.hh
lily/include/grob-properties.hh [new file with mode: 0644]
lily/include/lily-guile-macros.hh
lily/include/lily-proto.hh
lily/include/note-column.hh
lily/item.cc
lily/keep-alive-together-engraver.cc
lily/lexer.ll
lily/nested-property.cc
lily/note-column.cc
lily/parser.yy
lily/rest-collision-engraver.cc
lily/score-engraver.cc
lily/self-alignment-interface.cc
lily/span-bar-stub-engraver.cc
lily/text-interface.cc
lily/tie-formatting-problem.cc
ly/Welcome-to-LilyPond-MacOS.ly
ly/Welcome_to_LilyPond.ly
ly/engraver-init.ly
ly/event-listener.ly
ly/music-functions-init.ly
ly/performer-init.ly
po/lilypond.pot
python/book_snippets.py
scm/define-grob-interfaces.scm
scm/define-grob-properties.scm
scm/define-grobs.scm
scm/lily.scm
scm/output-lib.scm
scripts/auxiliar/update-with-convert-ly.sh
scripts/lilypond-book.py

index 09b049f53c4cb928cf29e2d47eafe9b5cbce1b99..091d72b82d33fa1b2300721f084f82fd1a2fd1bb 100644 (file)
@@ -1,4 +1,4 @@
-@c -*- coding: utf-8; mode: texinfo; -*-
+Elu@c -*- coding: utf-8; mode: texinfo; -*-
 @node Issues
 @chapter Issues
 
@@ -187,10 +187,10 @@ the currently-active Bug Squad member(s) can handle the message.
 
 @example
 Monday: Eluze
-Tuesday:
+Tuesday: Federico Bruni
 Wednesday: Marek Klein
 Thursday: Eluze
-Friday:
+Friday: Ralph Palmer
 Saturday: Colin Campbell
 Sunday:
 @end example
index fbc27ef8fe2c5f5e7c29c6118b919aafdfb11adf..cc8066e71777684631f0e24c2f04ac21f85aa05e 100644 (file)
@@ -481,7 +481,7 @@ friedlich nebeneinander auf der gleichen Seite erscheinen:
 @c line weights be scaled for small staves?
 
 @c Grieg's Violin Sonata Op. 45
-@lilypond[indent=1.5cm]
+@lilypond[indent=1.5\cm]
 global = {
   \time 6/8
   \key c \minor
index 1b4d0ce67366b86b42da4380c505056d1b7fcfca..35748c26f4fdcead263cd9e7b18c3543e170ccaa 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes.
 @end ignore
 
-@c \version "2.17.30"
+@c \version "2.19.12"
 
 @c Translators: Till Paala
 
@@ -478,7 +478,7 @@ vollständig neu definiert:
 
 @example
 \paper @{
-  system-system-spacing #'basic-distance = #8
+  system-system-spacing.basic-distance = #8
   score-system-spacing =
     #'((basic-distance . 12)
        (minimum-distance . 6)
@@ -1185,11 +1185,11 @@ Das obige Beispiel, das den Einsatz von  @code{\layoutVariable} zeigt,
 würde in seiner finalen Version folgende @code{\layout}-Umgebung haben:
 
 @example
-  TextScript #'padding = #1
-  TextScript #'color = #magenta
-  Glissando #'thickness = #1.5
-  NoteHead #' font-size = #4
-  NoteHead #' color = #red
+  TextScript.padding = #1
+  TextScript.color = #magenta
+  Glissando.thickness = #1.5
+  NoteHead.font-size = #4
+  NoteHead.color = #red
 @end example
 
 plus die Veränderungen an Einrückung (@code{indent}) und @code{StaffGrouper}.
@@ -1198,8 +1198,8 @@ Aber wenn die Variable vor der ersten @code{\layout}-Umgebung definiert
 wird, würde die aktuelle Konfiguration nur enthalten:
 
 @example
-  NoteHead #' font-size= #4 % (written in the variable definition)
-  NoteHead #' color = #red % (added after the use of the variable)
+  NoteHead.font-size= #4 % (written in the variable definition)
+  NoteHead.color = #red % (added after the use of the variable)
 @end example
 
 Wenn man sorgfältig plant, können @code{\layout}-Variablen ein wertvolles
index 7f78637b789147f276e917721c795583e548d44f..f3f1ca40ed568162872389f4fe5e88ad5fa8bd31 100644 (file)
@@ -491,7 +491,7 @@ used together on the same page:
 @c line weights be scaled for small staves?
 
 @c Grieg's Violin Sonata Op. 45
-@lilypond[indent=1.5cm]
+@lilypond[indent=1.5\cm]
 global = {
   \time 6/8
   \key c \minor
index 726f316dca0bb50be996b35a9d612911d8e27fef..a0a61b0cb9bec9b6471576fd45452d8323ded65a 100644 (file)
@@ -7,7 +7,7 @@
     version that you are working on.  See TRANSLATION for details.
 @end ignore
 
-@c \version "2.19.2"
+@c \version "2.19.12"
 
 @node Interfaces para programadores
 @chapter Interfaces para programadores
@@ -1376,7 +1376,7 @@ interna o en el archivo 'define-grobs.scm':
 
 @example
 \relative c'' @{
-  \override Flag #'X-offset = #(lambda (flag)
+  \override Flag.X-offset = #(lambda (flag)
     (let ((default (ly:flag::calc-x-offset flag)))
       (* default 4.0)))
   c4. d8 a4. g8
index d93a82571ff5d2a081482650a58a4b5ba61da3f5..52e79ddc8b57d804e3646956f2c7588c04e0c45e 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.30"
+@c \version "2.19.12"
 
 @ignore
 GDP TODO list
@@ -581,7 +581,7 @@ segunda redefine la variable completamente:
 
 @example
 \paper @{
-  system-system-spacing #'basic-distance = #8
+  system-system-spacing.basic-distance = #8
   score-system-spacing =
     #'((basic-distance . 12)
        (minimum-distance . 6)
index 5136a331e04fc3174a33372d598dd12979c9a39b..7797a5468a21323bba277eb467a4f3ef63aca259 100644 (file)
@@ -451,7 +451,7 @@ This also allows staves of different sizes to coexist peacefully when
 used together on the same page:
 
 @c Grieg's Violin Sonata Op. 45
-@lilypond[indent=1.5cm]
+@lilypond[indent=1.5\cm]
 global = {
   \time 6/8
   \key c \minor
index be580034424071d97736417ecff76010be2b3fdb..9da93f56153359302260b1ea2f11c4e12c551328 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.19.2"
+@c \version "2.19.12"
 
 @node Interfaces for programmers
 @chapter Interfaces for programmers
@@ -1368,7 +1368,7 @@ can by found in the Internals Reference or the file 'define-grobs.scm':
 
 @example
 \relative c'' @{
-  \override Flag #'X-offset = #(lambda (flag)
+  \override Flag.X-offset = #(lambda (flag)
     (let ((default (ly:flag::calc-x-offset flag)))
       (* default 4.0)))
   c4. d8 a4. g8
index 7503306b1fa56f3e8c16b0f6d25b5f5e8d8f28a6..fc2eba1c6debfec3345933e1d3a0b204f0ab7420 100644 (file)
@@ -275,9 +275,10 @@ Abelson, see
 @node Lists
 @unnumberedsubsubsec Lists
 
-A very common Scheme data structure is the @emph{list}.  Formally, a
-list is defined as either the empty list (represented as @code{'()},
-or a pair whose @code{cdr} is a list.
+A very common Scheme data structure is the @emph{list}.  Formally,
+a @q{proper} list is defined to be either the empty list with its
+input form @code{'()} and length@tie{}0, or a pair whose
+@code{cdr} in turn is a shorter list.
 
 There are many ways of creating lists.  Perhaps the most common is
 with the @code{list} procedure:
index 430e225240599b380e5690e69f1b87a7ea317618..1f41b047b037ece18664dc72de2735ab33429457 100644 (file)
@@ -486,7 +486,7 @@ Ceci permet par ailleurs de faire coexister harmonieusement
 plusieurs portées de taille différente sur une même page :
 
 @c Grieg's Violin Sonata Op. 45
-@lilypond[indent=1.5cm]
+@lilypond[indent=1.5\cm]
 global = {
   \time 6/8
   \key c \minor
index a1c043379403a75b53f831b45465e888be7ff62e..ca6b33a5058b5571f45f0e5b20b9ddae4995cb6b 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.19.2"
+@c \version "2.19.12"
 
 @c Translators: Valentin Villenave, Jean-Charles Malahieude
 @c Translation checkers: Gilles Thibault
@@ -1497,7 +1497,7 @@ valeur usuelle de la propriété :
 
 @example
 \relative c'' @{
-  \override Flag #'X-offset = #(lambda (flag)
+  \override Flag.X-offset = #(lambda (flag)
     (let ((default (ly:flag::calc-x-offset flag)))
       (* default 4.0)))
   c4. d8 a4. g8
index ac33088e47c501cac7d445dffca55c0d316ab69e..cfb7aeb57721e4f318ddfe00fcbadab2b360a4c2 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.11"
+@c \version "2.18.0"
 
 @c Translators: Jean-Charles Malahieude
 
index 548e70867d251dc1d132a32292e4597f5f888877..d0877e0087b36f67ad8e3f0684a123e432ada317 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.30"
+@c \version "2.19.12"
 
 @c Translators: Frédéric Chiasson, Jean-Charles Malahieude
 
@@ -555,7 +555,7 @@ deuxième redéfinit complètement la variable.
 
 @example
 \paper @{
-  system-system-spacing #'basic-distance = #8
+  system-system-spacing.basic-distance = #8
 
   score-system-spacing =
     #'((padding . 1)
index 9c16677ce7348c91bfe573bf36f1708c41ef34b5..82234a683a932b1d3c017fd3f3fdff233d47f358 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.30"
+@c \version "2.19.12"
 
 
 @c Translators: Yoshiki Sawada
@@ -507,7 +507,7 @@ largest of:
 
 @example
 \paper @{
-  system-system-spacing #'basic-distance = #8
+  system-system-spacing.basic-distance = #8
   score-system-spacing =
     #'((basic-distance . 12)
        (minimum-distance . 6)
@@ -1196,11 +1196,11 @@ layoutVariable = \layout @{
 @code{\layout} ブロックの構成は以下のようになります:
 
 @example
-  TextScript #'padding = #1
-  TextScript #'color = #magenta
-  Glissando #'thickness = #1.5
-  NoteHead #' font-size = #4
-  NoteHead #' color = #red
+  TextScript.padding = #1
+  TextScript.color = #magenta
+  Glissando.thickness = #1.5
+  NoteHead.font-size = #4
+  NoteHead.color = #red
 @end example
 
 これに @code{indent} と @code{StaffGrouper} の設定がプラスしたものです。
@@ -1209,8 +1209,8 @@ layoutVariable = \layout @{
 場合、カレントの構成は以下だけになってしまいます:
 
 @example
-  NoteHead #' font-size= #4 % (変数定義で記述されたものです)
-  NoteHead #' color = #red % (変数が使用された後に追加されたものです)
+  NoteHead.font-size= #4 % (変数定義で記述されたものです)
+  NoteHead.color = #red % (変数が使用された後に追加されたものです)
 @end example
 
 注意深く計画を立てれば、@code{\layout} 変数はソースのレイアウト設計を構築@c
index c002e111d02c1e00396098f37dcf783fc823c3ef..66c6a7fbd326ad0de0536cfe777bccbeb204246d 100644 (file)
@@ -1,5 +1,5 @@
 
-\version "2.17.30"
+\version "2.19.12"
 
 \layout {
   indent = #0
@@ -42,7 +42,7 @@
   printfirst-page-number = ##t
   print-page-number = ##t
   ragged-last-bottom = ##t
-  markup-system-spacing #'minimum-distance = #25
+  markup-system-spacing.minimum-distance = #25
 }
 
 #(set-global-staff-size 14)
index 70ffece67ecc5ee67b01ce3e6d866f78420f5457..c38727bc85b46f37f37cb798d44abd7d8b57a576 100644 (file)
@@ -2599,7 +2599,7 @@ modified by completely re-defining them as alists.}
 The way in which the notation contained within an input file is
 interpreted is determined by the current input mode.
 
-@strong{Chord mode}
+@subsubsubheading Chord mode
 
 This is activated with the @code{\chordmode} command, and causes
 input to be interpreted with the syntax of chord notation, see
@@ -2611,7 +2611,7 @@ causes the following input to be interpreted with the syntax of
 chord notation and rendered as chord names in the @code{ChordNames}
 context, see @ref{Printing chord names}.
 
-@strong{Drum mode}
+@subsubsubheading Drum mode
 
 This is activated with the @code{\drummode} command, and causes
 input to be interpreted with the syntax of drum notation, see
@@ -2620,10 +2620,10 @@ input to be interpreted with the syntax of drum notation, see
 Drum mode is also activated with the @code{\drums} command.
 This also creates a new @code{DrumStaff} context and causes the
 following input to be interpreted with the syntax of drum notation
-and rendered as drum symbols on a drum staff, see @ref{Basic
-percussion notation}.
+and rendered as drum symbols on a drum staff, see
+@ref{Basic percussion notation}.
 
-@strong{Figure mode}
+@subsubsubheading Figure mode
 
 This is activated with the @code{\figuremode} command, and causes
 input to be interpreted with the syntax of figured bass, see
@@ -2635,7 +2635,7 @@ following input to be interpreted with the figured bass syntax
 and rendered as figured bass symbols in the @code{FiguredBass}
 context, see @ref{Introduction to figured bass}.
 
-@strong{Fret and tab modes}
+@subsubsubheading Fret and tab modes
 
 There are no special input modes for entering fret and tab symbols.
 
@@ -2649,7 +2649,7 @@ You can either use the @code{FretBoards} context (see
 above the notes using the @code{\fret-diagram} command (see
 @ref{Fret diagram markups}).
 
-@strong{Lyrics mode}
+@subsubsubheading Lyrics mode
 
 This is activated with the @code{\lyricmode} command, and causes
 input to be interpreted as lyric syllables with optional durations
@@ -2660,15 +2660,13 @@ This also creates a new @code{Lyrics} context and an implicit
 @code{\lyricsto} command which associates the following lyrics
 with the preceding music.
 
-@strong{Markup mode}
+@subsubsubheading Markup mode
 
 This is activated with the @code{\markup} command, and causes
 input to be interpreted with the syntax of markup, see
 @ref{Text markup commands}.
 
-@c silly work-around for texinfo broken-ness
-@c (@strong{Note...} causes a spurious cross-reference in Info)
-@b{Note mode}
+@subsubsubheading Note mode
 
 This is the default mode or it may be activated with the
 @code{\notemode} command.  Input is interpreted as pitches,
@@ -2679,23 +2677,6 @@ it may be useful to do so in certain situations, for example if you
 are in lyric mode, chord mode or any other mode and want to insert
 something that only can be done with note mode syntax.
 
-For example, to indicate dynamic markings for the verses of a
-choral pieces it is necessary to enter note mode to interpret
-the markings:
-
-@lilypond[verbatim,relative=2,quote]
-{ c4 c4 c4 c4 }
-\addlyrics {
-  \notemode{\set stanza = \markup{ \dynamic f 1. } }
-  To be sung loudly
-}
-\addlyrics {
-  \notemode{\set stanza = \markup{ \dynamic p 2. } }
-  To be sung quietly
-}
-@end lilypond
-
-
 
 @node Direction and placement
 @subsection Direction and placement
index 8ba8009eddae37244afd5532aff7689ef1a4a60a..5ae834f3b7f4ae73139046e8b50f768e6efc6002 100644 (file)
@@ -410,7 +410,7 @@ chord mode.  The displayed chord name will be the same, regardless
 of the mode of entry, unless there are inversions or added bass notes:
 
 @lilypond[verbatim,quote]
-chordmusic = \relative c' {
+chordmusic = \relative c' {
   <c e g>2 <f bes c>
   <f c' e g>1
   \chordmode {
index fe624548cc43c24c511b663ae9815a7d8a949298..c121cf7bb3fb7278074fa928a337ffcd51a8a005 100644 (file)
@@ -7,7 +7,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.11"
+@c \version "2.18.0"
 
 @node Editorial annotations
 @section Editorial annotations
index 91d7d81998c5d91e752f46265130cbbb07fc768c..ae2e671b5bd51a51cc538832da2e41a44062ec3f 100644 (file)
@@ -1878,11 +1878,457 @@ f^\varcoda e,_\varcoda b'\varcoda
 
 @end multitable
 
+@cindex drums, various
+@cindex acoustic bass
+@cindex bass
+@cindex snare
+@cindex electric snare
+@cindex acoustic snare
+@cindex tom tom
+@cindex bongo
+@cindex conga
+@cindex timbale
+@cindex sidestick
+@cindex floor tom tom
+@cindex low tom tom
+@cindex high tom tom
+@cindex mid tom tom
+@cindex high hat
+@cindex pedal high hat
+@cindex open high hat
+@cindex half-open high hat
+@cindex cymbal, various
+@cindex crash cymbal
+@cindex ride cymbal
+@cindex chinese cymbal
+@cindex splash cymbal
+@cindex ride bell
+@cindex cowbell
+@cindex agogo
+@cindex high bongo
+@cindex low bongo
+@cindex mute bongo
+@cindex open bongo
+@cindex high conga
+@cindex low conga
+@cindex mute conga
+@cindex open conga
+@cindex high timbale
+@cindex low timbale
+@cindex mute timbale
+@cindex open timbale
+@cindex sidestick
+@cindex guiro
+@cindex cabasa
+@cindex maracas
+@cindex whistle
+@cindex handclap
+@cindex tambourine
+@cindex vibraslap
+@cindex tam tam
+@cindex claves
+@cindex woodblock
+@cindex cuica
+@cindex triangle
 
 @node Percussion notes
 @appendixsec Percussion notes
 
-@lilypondfile[quote]{percussion-chart.ly}
+@multitable @columnfractions .22 .25 .25 .25
+
+@item
+@code{bassdrum @* bd @*}
+@lilypond[notime,ragged-right]
+\drums { bd4 bd1 }
+@end lilypond
+@tab
+@code{acousticbassdrum @* bda @*}
+@lilypond[notime,ragged-right]
+\drums { bda4 bda1 }
+@end lilypond
+@tab
+@code{snare @* sn @*}
+@lilypond[notime,ragged-right]
+\drums { sn4 sn1 }
+@end lilypond
+@tab
+@code{acousticsnare @* sna @*}
+@lilypond[notime,ragged-right]
+\drums { sna4 sna1 }
+@end lilypond
+
+@item
+@code{electricsnare @* sne @*}
+@lilypond[notime,ragged-right]
+\drums { sne4 sne1 }
+@end lilypond
+@tab
+@code{lowfloortom @* tomfl @*}
+@lilypond[notime,ragged-right]
+\drums { tomfl4 tomfl1 }
+@end lilypond
+@tab
+@code{highfloortom @* tomfh @*}
+@lilypond[notime,ragged-right]
+\drums { tomfh4 tomfh1 }
+@end lilypond
+@tab
+@code{lowtom @* toml @*}
+@lilypond[notime,ragged-right]
+\drums { toml4 toml1 }
+@end lilypond
+
+@item
+@code{hightom @* tomh @*}
+@lilypond[notime,ragged-right]
+\drums { tomh4 tomh1 }
+@end lilypond
+@tab
+@code{lowmidtom @* tomml @*}
+@lilypond[notime,ragged-right]
+\drums { tomml4 tomml1 }
+@end lilypond
+@tab
+@code{highmidtom @* tommh @*}
+@lilypond[notime,ragged-right]
+\drums { tommh4 tommh1 }
+@end lilypond
+@tab
+@code{highhat @* hh @*}
+@lilypond[notime,ragged-right]
+\drums { hh4 hh1 }
+@end lilypond
+
+@item
+@code{closedhihat @* hhc @*}
+@lilypond[notime,ragged-right]
+\drums { hhc4 hhc1 }
+@end lilypond
+@tab
+@code{openhighhat @* hho @*}
+@lilypond[notime,ragged-right]
+\drums { hho4 hho1 }
+@end lilypond
+@tab
+@code{halfopenhihat @* hhho @*}
+@lilypond[notime,ragged-right]
+\drums { hhho4 hhho1 }
+@end lilypond
+@tab
+@code{pedalhihat @* hhp @*}
+@lilypond[notime,ragged-right]
+\drums { hhp4 hhp1 }
+@end lilypond
+
+
+@item
+@code{crashcymbal @* cymc @*}
+@lilypond[notime,ragged-right]
+\drums { cymc4 cymc1 }
+@end lilypond
+@tab
+@code{crashcymbala @* cymca @*}
+@lilypond[notime,ragged-right]
+\drums { cymca4 cymca1 }
+@end lilypond
+@tab
+@code{crashcymbalb @* cymcb @*}
+@lilypond[notime,ragged-right]
+\drums { cymcb4 cymcb1 }
+@end lilypond
+@tab
+@code{ridecymbal @* cymr @*}
+@lilypond[notime,ragged-right]
+\drums { cymr4 cymr1 }
+@end lilypond
+
+@item
+@code{ridecymbala @* cymra @*}
+@lilypond[notime,ragged-right]
+\drums { cymra4 cymra1 }
+@end lilypond
+@tab
+@code{ridecymbalb @* cymrb @*}
+@lilypond[notime,ragged-right]
+\drums { cymrb4 cymrb1 }
+@end lilypond
+@tab
+@code{chinesecymbal @* cymch @*}
+@lilypond[notime,ragged-right]
+\drums { cymch4 cymch1 }
+@end lilypond
+@tab
+@code{splashcymbal @* cyms @*}
+@lilypond[notime,ragged-right]
+\drums { cyms4 cyms1 }
+@end lilypond
+
+@item
+@code{ridebell @* rb @*}
+@lilypond[notime,ragged-right]
+\drums { rb4 rb1 }
+@end lilypond
+@tab
+@code{cowbell @* cb @*}
+@lilypond[notime,ragged-right]
+\drums { cb4 cb1 }
+@end lilypond
+@tab
+@code{hibongo @* boh @*}
+@lilypond[notime,ragged-right]
+\drums { boh4 boh1 }
+@end lilypond
+@tab
+@code{openhibongo @* boho @*}
+@lilypond[notime,ragged-right]
+\drums { boho4 boho1 }
+@end lilypond
+
+@item
+@code{mutehibongo @* bohm @*}
+@lilypond[notime,ragged-right]
+\drums { bohm4 bohm1 }
+@end lilypond
+@tab
+@code{lobongo @* bol @*}
+@lilypond[notime,ragged-right]
+\drums { bol4 bol1 }
+@end lilypond
+@tab
+@code{openlobongo @* bolo @*}
+@lilypond[notime,ragged-right]
+\drums { bolo4 bolo1 }
+@end lilypond
+@tab
+@code{mutelobongo @* bolm @*}
+@lilypond[notime,ragged-right]
+\drums { bolm4 bolm1 }
+@end lilypond
+
+
+@item
+@code{hiconga @* cgh @*}
+@lilypond[notime,ragged-right]
+\drums { cgh4 cgh1 }
+@end lilypond
+@tab
+@code{openhiconga @* cgho @*}
+@lilypond[notime,ragged-right]
+\drums { cgho4 cgho1 }
+@end lilypond
+@tab
+@code{mutehiconga @* cghm @*}
+@lilypond[notime,ragged-right]
+\drums { cghm4 cghm1 }
+@end lilypond
+@tab
+@code{loconga @* cgl @*}
+@lilypond[notime,ragged-right]
+\drums { cgl4 cgl1 }
+@end lilypond
+
+@item
+@code{openloconga @* cglo @*}
+@lilypond[notime,ragged-right]
+\drums { cglo4 cglo1 }
+@end lilypond
+@tab
+@code{muteloconga @* cglm @*}
+@lilypond[notime,ragged-right]
+\drums { cglm4 cglm1 }
+@end lilypond
+@tab
+@code{hitimbale @* timh @*}
+@lilypond[notime,ragged-right]
+\drums { timh4 timh1 }
+@end lilypond
+@tab
+@code{lotimbale @* timl @*}
+@lilypond[notime,ragged-right]
+\drums { timl4 timl1 }
+@end lilypond
+
+@item
+@code{hiagogo @* agh @*}
+@lilypond[notime,ragged-right]
+\drums { agh4 agh1 }
+@end lilypond
+@tab
+@code{loagogo @* agl @*}
+@lilypond[notime,ragged-right]
+\drums { agl4 agl1 }
+@end lilypond
+@tab
+@code{sidestick @* ss @*}
+@lilypond[notime,ragged-right]
+\drums { ss4 ss1 }
+@end lilypond
+@tab
+@code{hisidestick @* ssh @*}
+@lilypond[notime,ragged-right]
+\drums { ssh4 ssh1 }
+@end lilypond
+
+@item
+@code{losidestick @* ssl @*}
+@lilypond[notime,ragged-right]
+\drums { ssl4 ssl1 }
+@end lilypond
+@tab
+@code{guiro @* gui @*}
+@lilypond[notime,ragged-right]
+\drums { gui4 gui1 }
+@end lilypond
+@tab
+@code{shortguiro @* guis @*}
+@lilypond[notime,ragged-right]
+\drums { guis4 guis1 }
+@end lilypond
+@tab
+@code{longguiro @* guil @*}
+@lilypond[notime,ragged-right]
+\drums { guil4 guil1 }
+@end lilypond
+
+@item
+@code{cabasa @* cab @*}
+@lilypond[notime,ragged-right]
+\drums { cab4 cab1 }
+@end lilypond
+@tab
+@code{maracas @* mar @*}
+@lilypond[notime,ragged-right]
+\drums { mar4 mar1 }
+@end lilypond
+@tab
+@code{shortwhistle @* whs @*}
+@lilypond[notime,ragged-right]
+\drums { whs4 whs1 }
+@end lilypond
+@tab
+@code{longwhistle @* whl @*}
+@lilypond[notime,ragged-right]
+\drums { whl4 whl1 }
+@end lilypond
+
+@item
+@code{handclap @* hc @*}
+@lilypond[notime,ragged-right]
+\drums { hc4 hc1 }
+@end lilypond
+@tab
+@code{tambourine @* tamb @*}
+@lilypond[notime,ragged-right]
+\drums { tamb4 tamb1 }
+@end lilypond
+@tab
+@code{vibraslap @* vibs @*}
+@lilypond[notime,ragged-right]
+\drums { vibs4 vibs1 }
+@end lilypond
+@tab
+@code{tamtam @* tt @*}
+@lilypond[notime,ragged-right]
+\drums { tt4 tt1 }
+@end lilypond
+
+@item
+@code{claves @* cl @*}
+@lilypond[notime,ragged-right]
+\drums { cl4 cl1 }
+@end lilypond
+@tab
+@code{hiwoodblock @* wbh @*}
+@lilypond[notime,ragged-right]
+\drums { wbh4 wbh1 }
+@end lilypond
+@tab
+@code{lowoodblock @* wbl @*}
+@lilypond[notime,ragged-right]
+\drums { wbl4 wbl1 }
+@end lilypond
+@tab
+@code{opencuica @* cuio @*}
+@lilypond[notime,ragged-right]
+\drums { cuio4 cuio1 }
+@end lilypond
+
+@item
+@code{mutecuica @* cuim @*}
+@lilypond[notime,ragged-right]
+\drums { cuim4 cuim1 }
+@end lilypond
+@tab
+@code{triangle @* tri @*}
+@lilypond[notime,ragged-right]
+\drums { tri4 tri1 }
+@end lilypond
+@tab
+@code{opentriangle @* trio @*}
+@lilypond[notime,ragged-right]
+\drums { trio4 trio1 }
+@end lilypond
+@tab
+@code{mutetriangle @* trim}
+@lilypond[notime,ragged-right]
+\drums { trim4 trim1 }
+@end lilypond
+
+@item
+@code{oneup @* ua @*}
+@lilypond[notime,ragged-right]
+\drums { ua4 ua1 }
+@end lilypond
+@tab
+@code{twoup @* ub @*}
+@lilypond[notime,ragged-right]
+\drums { ub4 ub1 }
+@end lilypond
+@tab
+@code{threeup @* uc @*}
+@lilypond[notime,ragged-right]
+\drums { uc4 uc1 }
+@end lilypond
+@tab
+@code{fourup @* ud @*}
+@lilypond[notime,ragged-right]
+\drums { ud4 ud1 }
+@end lilypond
+
+@item
+@code{fiveup @* ue @*}
+@lilypond[notime,ragged-right]
+\drums { ue4 ue1 }
+@end lilypond
+@tab
+@code{onedown @* da @*}
+@lilypond[notime,ragged-right]
+\drums { da4 da1 }
+@end lilypond
+@tab
+@code{twodown @* db @*}
+@lilypond[notime,ragged-right]
+\drums { db4 db1 }
+@end lilypond
+@tab
+@code{threedown @* dc @*}
+@lilypond[notime,ragged-right]
+\drums { dc4 dc1 }
+@end lilypond
+
+@item
+@code{fourdown @* dd @*}
+@lilypond[notime,ragged-right]
+\drums { dd4 dd1 }
+@end lilypond
+@tab
+@code{fivedown @* de @*}
+@lilypond[notime,ragged-right]
+\drums { de4 de1 }
+@end lilypond
+
+
+@end multitable
 
 
 @node Technical glossary
index b4b3d7a80b95d8705c505be54fdddf6c6eb884c7..e90d71a45f9b52460f8b6f7c875ca5bb4b70783f 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.30"
+@c \version "2.19.12"
 
 @ignore
 GDP TODO list
@@ -508,7 +508,7 @@ redefines the variable:
 
 @example
 \paper @{
-  system-system-spacing #'basic-distance = #8
+  system-system-spacing.basic-distance = #8
   score-system-spacing =
     #'((basic-distance . 12)
        (minimum-distance . 6)
index 187e10566f2970b358bce44a92f543ae645e25b5..912378ab0877cede4d7fa8d02fc0fc68d1a076bc 100644 (file)
@@ -1682,13 +1682,6 @@ words = \lyricmode { la __ la __ }
 >>
 @end lilypond
 
-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
-the staff.
-
 This method also can be used with the @code{\partcombine}
 function, which does not allow lyrics on its own:
 
@@ -1724,23 +1717,13 @@ aligner = \relative { b'8( c d c) d( d d d) }
 words = \lyricmode { la __ la __ }
 
 \new ChoirStaff <<
-  \new Staff <<
-    \soprano
-    \new NullVoice = "aligner" \aligner
-  >>
+  \new Staff \soprano
+  \new NullVoice = "aligner" \aligner
   \new Lyrics \lyricsto "aligner" \words
   \new Staff \partcombine \altoOne \altoTwo
 >>
 @end lilypond
 
-However, note that in the second half of the measure above, the
-notes in the @code{NullVoice} context reflect the rhythm of the
-lower staff, but they do not deviate from the single pitch being
-displayed in the staff to which the @code{NullVoice} belongs.
-While not actually required in this particular example, it is a
-good idea in general to enter the notes in this way.
-
-
 @node Stanzas
 @subsection Stanzas
 
@@ -2592,11 +2575,13 @@ c c c
 Alternatively, if there are many character changes, it may be
 easier to set up @qq{instrument} definitions for each character at
 the top level so that @code{\instrumentSwitch} can be used to
-indicate each change.
+indicate each change.  As notes for vocal parts are usually entered
+at sounding pitch no instrument transposition is required, even
+when, as here, the tenor line is printed an octave higher.
 
 @lilypond[quote,verbatim]
 \addInstrumentDefinition #"kaspar"
-  #`((instrumentTransposition . ,(ly:make-pitch -1 0 0))
+  #`((instrumentTransposition . ,(ly:make-pitch 0 0 0))
      (shortInstrumentName . "Kas.")
      (clefGlyph . "clefs.G")
      (clefTransposition . -7)
index 7a75bb1a33fa98170414298349e200e51c5c806d..ba68c27a01d8c9ca01b5cbfd6b01bf9bd85da6af 100644 (file)
@@ -1,10 +1,11 @@
-%% DO NOT EDIT this file manually; it is automatically
-%% generated from LSR http://lsr.di.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.18.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.12
+\version "2.19.12"
 
 \header {
   lsrtags = "devel, scheme-language, tweaks-and-overrides"
@@ -39,7 +40,7 @@ When called this way
 
 
 @{
- \\once \\override NoteHead #'before-line-breaking = #display-ancestry
+ \\once \\override NoteHead.before-line-breaking = #display-ancestry
  c @}
 
 
diff --git a/Documentation/snippets/new/displaying-grob-ancestry.ly b/Documentation/snippets/new/displaying-grob-ancestry.ly
new file mode 100644 (file)
index 0000000..2f8919c
--- /dev/null
@@ -0,0 +1,118 @@
+\version "2.19.12"
+
+\header {
+  lsrtags = "devel, scheme-language, tweaks-and-overrides"
+
+  texidoc = "
+When working with grob callbacks, it can be helpful to understand a
+grob's @qq{ancestry}. Most grobs have @qq{parents} which influence the
+positioning of the grob. X- and Y-parents influence the horizontal and
+vertical positions for the grob, respectively. Additionally, each
+parent may have parents of its own.
+
+
+Unfortunately, there are several aspects of a grob's ancestry that can
+lead to confusion:
+
+* The types of parents a grob has may depend on context. * For some
+grobs, the X- and Y-parents are the same. * A particular @qq{ancestor}
+may be related to a grob in multiple ways. * The concept of
+@qq{generations} is misleading.
+
+
+For example, the @code{System} grob can be both parent (on the Y-side)
+and grandparent (twice on the X-side) to a @code{VerticalAlignment}
+grob.
+
+
+This macro prints (to the console) a textual representation of a grob's
+ancestry.
+
+
+When called this way
+
+
+@{
+ \\once \\override NoteHead.before-line-breaking = #display-ancestry
+ c @}
+
+
+The following output is generated:
+
+
+------------------------------------
+
+NoteHead X,Y: NoteColumn
+    X: PaperColumn
+       X,Y: System
+    Y: VerticalAxisGroup
+       X: NonMusicalPaperColumn
+          X,Y: System
+       Y: VerticalAlignment
+          X: NonMusicalPaperColumn
+             X,Y: System
+          Y: System
+
+
+
+"
+  doctitle = "Displaying grob ancestry"
+}
+%% http://lsr.di.unimi.it/LSR/Item?id=622
+%% see also http://www.lilypond.org/doc/v2.18/Documentation/snippets/tweaks-and-overrides#tweaks-and-overrides-displaying-grob-ancestry
+
+#(define (grob-name grob)
+   (if (ly:grob? grob)
+       (assoc-ref (ly:grob-property grob 'meta) 'name)
+       #f))
+
+#(define (get-ancestry grob)
+   (if (not (null? (ly:grob-parent grob X)))
+       (list (grob-name grob)
+             (get-ancestry (ly:grob-parent grob X))
+             (get-ancestry (ly:grob-parent grob Y)))
+       (grob-name grob)))
+
+#(define (format-ancestry lst padding)
+   (string-append
+    (symbol->string (car lst))
+    "\n"
+    (let ((X-ancestry
+           (if (list? (cadr lst))
+               (format-ancestry (cadr lst) (+ padding 3))
+               (symbol->string (cadr lst))))
+          (Y-ancestry
+           (if (list? (caddr lst))
+               (format-ancestry (caddr lst) (+ padding 3))
+               (symbol->string (caddr lst)))))
+      (if (equal? X-ancestry Y-ancestry)
+          (string-append
+           (format #f "~&")
+           (make-string padding #\space)
+           "X,Y: "
+           (if (list? (cadr lst))
+               (format-ancestry (cadr lst) (+ padding 5))
+               (symbol->string (cadr lst))))
+          (string-append
+           (format #f "~&")
+           (make-string padding #\space)
+           "X: " X-ancestry
+           "\n"
+           (make-string padding #\space)
+           "Y: " Y-ancestry
+           (format #f "~&"))))
+    (format #f "~&")))
+
+#(define (display-ancestry grob)
+   (format (current-error-port)
+      "~3&~a~2%~a~&"
+      (make-string 36 #\-)
+      (format-ancestry (get-ancestry grob) 0)))
+
+\relative c' {
+  \once \override NoteHead.before-line-breaking = #display-ancestry
+  f4
+  \once \override Accidental.before-line-breaking = #display-ancestry
+  \once \override Arpeggio.before-line-breaking = #display-ancestry
+  <f as c>4\arpeggio
+}
diff --git a/Documentation/snippets/new/vocal-ensemble-template-with-automatic-piano-reduction.ly b/Documentation/snippets/new/vocal-ensemble-template-with-automatic-piano-reduction.ly
new file mode 100644 (file)
index 0000000..efc99f2
--- /dev/null
@@ -0,0 +1,101 @@
+\version "2.19.12"
+
+\header {
+  lsrtags = "automatic-notation, keyboards, template, vocal-music"
+
+  texidoc = "
+This template adds an automatic piano reduction to the standard SATB
+vocal score demonstrated in @qq{Vocal ensemble template}. This
+demonstrates one of the strengths of LilyPond – you can use a music
+definition more than once. If any changes are made to the vocal notes
+(say, @code{tenorMusic}), then the changes will also apply to the piano
+reduction.
+
+"
+  doctitle = "Vocal ensemble template with automatic piano reduction"
+}
+\paper {
+  top-system-spacing.basic-distance = #10
+  score-system-spacing.basic-distance = #20
+  system-system-spacing.basic-distance = #20
+  last-bottom-spacing.basic-distance = #10
+}
+
+global = {
+  \key c \major
+  \time 4/4
+}
+
+sopMusic = \relative c'' {
+  c4 c c8[( b)] c4
+}
+sopWords = \lyricmode {
+  hi hi hi hi
+}
+
+altoMusic = \relative c' {
+  e4 f d e
+}
+altoWords =\lyricmode {
+  ha ha ha ha
+}
+
+tenorMusic = \relative c' {
+  g4 a f g
+}
+tenorWords = \lyricmode {
+  hu hu hu hu
+}
+
+bassMusic = \relative c {
+  c4 c g c
+}
+bassWords = \lyricmode {
+  ho ho ho ho
+}
+
+\score {
+  <<
+    \new ChoirStaff <<
+      \new Lyrics = "sopranos" \with {
+        % This is needed for lyrics above a staff
+        \override VerticalAxisGroup.staff-affinity = #DOWN
+      }
+      \new Staff = "women" <<
+        \new Voice = "sopranos" { \voiceOne << \global \sopMusic >> }
+        \new Voice = "altos" { \voiceTwo << \global \altoMusic >> }
+      >>
+      \new Lyrics = "altos"
+      \new Lyrics = "tenors" \with {
+        % This is needed for lyrics above a staff
+        \override VerticalAxisGroup.staff-affinity = #DOWN
+      }
+
+      \new Staff = "men" <<
+        \clef bass
+        \new Voice = "tenors" { \voiceOne << \global \tenorMusic >> }
+        \new Voice = "basses" { \voiceTwo << \global \bassMusic >> }
+      >>
+      \new Lyrics = "basses"
+      \context Lyrics = "sopranos" \lyricsto "sopranos" \sopWords
+      \context Lyrics = "altos" \lyricsto "altos" \altoWords
+      \context Lyrics = "tenors" \lyricsto "tenors" \tenorWords
+      \context Lyrics = "basses" \lyricsto "basses" \bassWords
+    >>
+    \new PianoStaff <<
+      \new Staff <<
+        \set Staff.printPartCombineTexts = ##f
+        \partcombine
+        << \global \sopMusic >>
+        << \global \altoMusic >>
+      >>
+      \new Staff <<
+        \clef bass
+        \set Staff.printPartCombineTexts = ##f
+        \partcombine
+        << \global \tenorMusic >>
+        << \global \bassMusic >>
+      >>
+    >>
+  >>
+}
diff --git a/Documentation/snippets/new/vocal-ensemble-template.ly b/Documentation/snippets/new/vocal-ensemble-template.ly
new file mode 100644 (file)
index 0000000..3832db6
--- /dev/null
@@ -0,0 +1,93 @@
+\version "2.19.12"
+
+\header {
+  lsrtags = "really-simple, template, vocal-music"
+
+  texidoc = "
+Here is a standard four-part SATB vocal score. With larger ensembles,
+it is often useful to include a section which is included in all parts.
+For example, the time signature and key signature are almost always the
+same for all parts. Like in the @qq{Hymn} template, the four voices are
+regrouped on only two staves.
+
+"
+  doctitle = "Vocal ensemble template"
+}
+\paper {
+  top-system-spacing.basic-distance = #10
+  score-system-spacing.basic-distance = #20
+  system-system-spacing.basic-distance = #20
+  last-bottom-spacing.basic-distance = #10
+}
+
+global = {
+  \key c \major
+  \time 4/4
+}
+
+sopMusic = \relative c'' {
+  c4 c c8[( b)] c4
+}
+sopWords = \lyricmode {
+  hi hi hi hi
+}
+
+altoMusic = \relative c' {
+  e4 f d e
+}
+altoWords = \lyricmode {
+  ha ha ha ha
+}
+
+tenorMusic = \relative c' {
+  g4 a f g
+}
+tenorWords = \lyricmode {
+  hu hu hu hu
+}
+
+bassMusic = \relative c {
+  c4 c g c
+}
+bassWords = \lyricmode {
+  ho ho ho ho
+}
+
+\score {
+  \new ChoirStaff <<
+    \new Lyrics = "sopranos" \with {
+      % this is needed for lyrics above a staff
+      \override VerticalAxisGroup.staff-affinity = #DOWN
+    }
+    \new Staff = "women" <<
+      \new Voice = "sopranos" {
+        \voiceOne
+        << \global \sopMusic >>
+      }
+      \new Voice = "altos" {
+        \voiceTwo
+        << \global \altoMusic >>
+      }
+    >>
+    \new Lyrics = "altos"
+    \new Lyrics = "tenors" \with {
+      % this is needed for lyrics above a staff
+      \override VerticalAxisGroup.staff-affinity = #DOWN
+    }
+    \new Staff = "men" <<
+      \clef bass
+      \new Voice = "tenors" {
+        \voiceOne
+        << \global \tenorMusic >>
+      }
+      \new Voice = "basses" {
+        \voiceTwo << \global \bassMusic >>
+      }
+    >>
+    \new Lyrics = "basses"
+    \context Lyrics = "sopranos" \lyricsto "sopranos" \sopWords
+    \context Lyrics = "altos" \lyricsto "altos" \altoWords
+    \context Lyrics = "tenors" \lyricsto "tenors" \tenorWords
+    \context Lyrics = "basses" \lyricsto "basses" \bassWords
+  >>
+}
index 8eba692deb16a55ca20e9a6c5f2f1a4699f2754c..747e1ae8dcb0ea754cd86410478f2d1ca6c1b1b0 100644 (file)
@@ -1,10 +1,11 @@
-%% DO NOT EDIT this file manually; it is automatically
-%% generated from LSR http://lsr.di.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.18.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.12
+\version "2.19.12"
 
 \header {
   lsrtags = "automatic-notation, keyboards, template, vocal-music"
@@ -22,10 +23,10 @@ reduction.
 } % begin verbatim
 
 \paper {
-  top-system-spacing #'basic-distance = #10
-  score-system-spacing #'basic-distance = #20
-  system-system-spacing #'basic-distance = #20
-  last-bottom-spacing #'basic-distance = #10
+  top-system-spacing.basic-distance = #10
+  score-system-spacing.basic-distance = #20
+  system-system-spacing.basic-distance = #20
+  last-bottom-spacing.basic-distance = #10
 }
 
 global = {
index e78416a1069e3c03f135afa0893c9e8221668886..16f28d9e31cb3ac82f1b629e60be14990fd06e37 100644 (file)
@@ -1,10 +1,11 @@
-%% DO NOT EDIT this file manually; it is automatically
-%% generated from LSR http://lsr.di.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.18.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.12
+\version "2.19.12"
 
 \header {
   lsrtags = "really-simple, template, vocal-music"
@@ -21,10 +22,10 @@ regrouped on only two staves.
 } % begin verbatim
 
 \paper {
-  top-system-spacing #'basic-distance = #10
-  score-system-spacing #'basic-distance = #20
-  system-system-spacing #'basic-distance = #20
-  last-bottom-spacing #'basic-distance = #10
+  top-system-spacing.basic-distance = #10
+  score-system-spacing.basic-distance = #20
+  system-system-spacing.basic-distance = #20
+  last-bottom-spacing.basic-distance = #10
 }
 
 global = {
index 4b6367f03384f990964126ebfaef747b110f91fa..9c0ec4b35d8565c2bf96ae5fd83434d257174d9a 100644 (file)
@@ -9,9 +9,9 @@
 @c used for news about the upcoming release; see CG 10.2
 
 @newsItem
-@subsubheading LilyPond 2.19.11 released  @emph{August 3, 2014}
+@subsubheading LilyPond 2.19.12 released  @emph{August 17, 2014}
 
-We are happy to announce the release of LilyPond 2.19.11.  This
+We are happy to announce the release of LilyPond 2.19.12.  This
 release includes a number of enhancements, and contains some work
 in progress.  You will have access to the very latest features, but
 some may be incomplete, and you may encounter bugs and crashes.  If you
index 8f1d4e349cb18af353a61afba5410b5913b879f6..ddb034998768ce6bee2fdbeff31dc8b05304f7b9 100644 (file)
@@ -26,6 +26,18 @@ NOTE:
   * don't duplicate entries from news-front.itexi
 @end ignore
 
+@newsItem
+@subsubheading LilyPond 2.19.11 released  @emph{August 3, 2014}
+
+We are happy to announce the release of LilyPond 2.19.11.  This
+release includes a number of enhancements, and contains some work
+in progress.  You will have access to the very latest features, but
+some may be incomplete, and you may encounter bugs and crashes.  If you
+require a stable version of Lilypond, we recommend using the 2.18
+version.
+
+@newsEnd
+
 @newsItem
 @subsubheading LilyPond 2.19.10 released  @emph{July 13, 2014}
 
diff --git a/VERSION b/VERSION
index a8d8464e1f961df652a571f60a6770c19085c0b3..db178adabd87aeb3cef3536edf62e6dc2d263620 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
 MINOR_VERSION=19
-PATCH_LEVEL=12
+PATCH_LEVEL=13
 MY_PATCH_LEVEL=
 VERSION_STABLE=2.18.2
-VERSION_DEVEL=2.19.11
+VERSION_DEVEL=2.19.12
index 7f22cdf0baa539a006e486cc0233e746baa739f5..fc3e78c6e4c99615619f53c85694ab9d3700cb12 100644 (file)
@@ -1,14 +1,22 @@
 
 \header {
-texidoc = "Tied notes with accidentals do not cause problems with spacing."
+texidoc = "Space is allowed for the actual size of accidentals on tied notes."
 }
 
-\version "2.16.0"
-
+\version "2.19.13"
+\paper {ragged-right = ##t }
 \relative c' {
   \clef treble
   \time 3/4
   c8 b2  <g b des f>8 ~ |
-  <g b des f>8
+  <g b des f>8 r
+  % Large accidental
+  \override Staff.Accidental.stencil =
+  #(lambda (g)
+     (let ((alt (ly:grob-property g 'alteration)))
+       (grob-interpret-markup g
+         (make-circle-markup (number->string alt)))))
+  bes4 ~ bes ~ | bes ~ bes bes ~ | \break
+  bes ~ bes bes
 }
 
index ab22af643bc049e00bc02065a66ed33cf9dc94b4..db542afb84b1dde5055253b4ab0fe84cb0069dad 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.10"
+\version "2.19.12"
 
 \header {
   texidoc = "@code{add-stem-support} can be removed or implemented
@@ -18,8 +18,8 @@ music = {
 
 {
   \music
-  \override Fingering #'add-stem-support = ##f
+  \override Fingering.add-stem-support = ##f
   \music
-  \override Fingering #'add-stem-support = #only-if-beamed
+  \override Fingering.add-stem-support = #only-if-beamed
   \music
 }
\ No newline at end of file
index 892359dfc2a060ad5279d13405b85000597dc06c..f7814f4f3b4e1392d0c5c63337c87193cee6d956 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.6"
+\version "2.19.12"
 
 forcedLastBreak =  {} %%  { \break } if needed to match original breaks
 
@@ -171,10 +171,10 @@ smallerPaper = \layout {
   ragged-bottom = ##t
   indent = 7. \mm
   line-width =183.5 \mm
-  system-system-spacing #'basic-distance = 14.22 % 25mm, in staff-spaces
-  system-system-spacing #'padding = #0
-  score-system-spacing #'basic-distance = #0
-  score-system-spacing #'padding = #0
+  system-system-spacing.basic-distance = 14.22 % 25mm, in staff-spaces
+  system-system-spacing.padding = #0
+  score-system-spacing.basic-distance = #0
+  score-system-spacing.padding = #0
   system-count = 6
 
 %%  annotatespacing = ##t
index 119e00a903a28ef7b5be816d84748e1a58df51e7..4598cf4f340da6f2eaffc9ad083b5d3fe9e1e92a 100644 (file)
@@ -1,18 +1,50 @@
-\version "2.16.0"
+\version "2.18.0"
 
 \header {
 
   texidoc="Transposition symbols should be correctly positioned
-close to the parent clef."
+close to the parent clef.  Horizontal alignment is fine-tuned
+for standard C, G and F clefs: for example, downwards transposition
+of a G clef should be centered exactly under the middle of clef hook.
+For clefs that don't have fine-tuned alignment the transposition
+number should be centered."
 
 }
+
+% use huge staff-size to see the tiny differencies better.
+#(set-global-staff-size 35)
+
+clefVariations =
+#(define-music-function (parser location type)(string?)
+   #{
+     \once \omit Staff.Clef s4
+     \override Staff.Clef.full-size-change = ##t
+     \clef #(string-append type "8") s4
+     \clef #(string-append type "15") s4
+     \clef #(string-append type "(8)") s4
+     \clef #(string-append type "(141)") s4
+     % change clefs are omitted - too similar to regular ones
+     \cueClef #(string-append type "8") s4
+     \cueClef #(string-append type "15") s4
+     \cueClef #(string-append type "(8)") s4
+     \cueClef #(string-append type "(141)") s4
+   #})
+
+\markup "Even the smallest positioning changes may indicate a problem!"
 \score {
   <<
-    \new Staff { \clef "G^8" g''1 }
-    \new Staff { \clef "F^8" c'1 }
-    \new Staff { \clef "C^8" c''1 }
-    \new Staff { \clef "G_8" g1 }
-    \new Staff { \clef "F_8" c,1 }
-    \new Staff { \clef "C_8" c1 }
+    \new Staff { \clefVariations "C_" }
+    \new Staff { \clefVariations "C^" }
+    \new Staff { \clefVariations "G_" }
+    \new Staff { \clefVariations "G^" }
+    \new Staff { \clefVariations "F_" }
+    \new Staff { \clefVariations "F^" }
   >>
 }
+
+\layout {
+  \context {
+    \Staff
+    \remove Time_signature_engraver
+  }
+}
\ No newline at end of file
diff --git a/input/regression/divisi-staves.ly b/input/regression/divisi-staves.ly
new file mode 100644 (file)
index 0000000..64c8439
--- /dev/null
@@ -0,0 +1,54 @@
+\version "2.19.13"
+
+\header {
+  texidoc = "The @code{VerticalAxisGroup.remove-layer}
+property can be used for typesetting temporary divisi staves where
+the switch to split staves is done only at line breaks such that all
+complex passages are rendered in separate staves."
+}
+
+boring = \set Staff.keepAliveInterfaces = #'()
+tricky = \unset Staff.keepAliveInterfaces
+
+violI=\relative d' {
+  \boring \repeat unfold 100 d4
+  \tricky <d g'>2
+  \boring \repeat unfold 98 d4
+  \bar "|."
+}
+
+violII=\relative g {
+  \boring \repeat unfold 100 g4
+  \tricky <g d'>2
+  \boring \repeat unfold 98 g4
+  \bar "|."
+}
+
+\score {
+  \new StaffGroup \with { \consists "Keep_alive_together_engraver" }
+  <<
+    \new Staff \with { instrumentName = "Violin I"
+                      shortInstrumentName = "V I"
+                      \override VerticalAxisGroup.remove-empty = ##t
+                      \override VerticalAxisGroup.remove-first = ##t
+                      \override VerticalAxisGroup.remove-layer = 1
+                    }
+    \violI
+    \new Staff \with { instrumentName = "Violin II"
+                      shortInstrumentName = "V II"
+                      \override VerticalAxisGroup.remove-empty = ##t
+                      \override VerticalAxisGroup.remove-first = ##t
+                      \override VerticalAxisGroup.remove-layer = 1
+                    }
+    \violII
+    \new Staff \with { instrumentName = "Violins"
+                      shortInstrumentName = "V I&II"
+                      \override VerticalAxisGroup.remove-layer = 2
+                    }
+    <<  \violI \\ \violII  >>
+  >>
+  \layout {
+    short-indent = 2\cm
+    indent = 3\cm
+  }
+}
index 4b06d96faefe05bc5c0ec6c2d330fd52ce218700..cdf907a490b0dcb2173873abc4c4f08aa7b5a750 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.18"
+\version "2.19.12"
 
 \header {
   texidoc = "An empty Dynamics context does not confuse the spacing."
@@ -19,7 +19,7 @@
   \layout {
     \context {
       \Dynamics
-      \override VerticalAxisGroup #'nonstaff-relatedstaff-spacing
+      \override VerticalAxisGroup.nonstaff-relatedstaff-spacing
         = #'((minimum-distance . 5))
     }
   }
index 000d9da4033f00c6b9427657a9627fd6235ae62a..a49892c140b5b0e4b1b33ba004325d3f653b31b1 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.14"
+\version "2.19.12"
 
 \header {
   texidoc = "LilyPond creates hairpins found in Ferneyhough scores.
@@ -6,19 +6,19 @@
 }
 
 \relative c'' {
-  \override Hairpin #'stencil = #flared-hairpin
+  \override Hairpin.stencil = #flared-hairpin
   a4\< a a a\f
   a4\p\< a a a\ff
   a4\sfz\< a a a\!
-  \override Hairpin #'stencil = #constante-hairpin
+  \override Hairpin.stencil = #constante-hairpin
   a4\< a a a\f
   a4\p\< a a a\ff
   a4\sfz\< a a a\!
-  \override Hairpin #'stencil = #flared-hairpin
+  \override Hairpin.stencil = #flared-hairpin
   a4\> a a a\f
   a4\p\> a a a\ff
   a4\sfz\> a a a\!
-  \override Hairpin #'stencil = #constante-hairpin
+  \override Hairpin.stencil = #constante-hairpin
   a4\> a a a\f
   a4\p\> a a a\ff
   a4\sfz\> a a a\!
index 935f068db7c392386cdc0b746f9702313bc95770..ebe18303f57bb951dbe728a680248d8fc141e4e4 100644 (file)
@@ -18,7 +18,8 @@ OUT_TELY_FILES += ${TELY_FILES:%.tely=$(outdir)/%.pdf}
 
 XML_FILES = $(filter-out include%,$(call src-wildcard,*.xml))
 
-local-test: $(OUT_FILES)
+local-test:
+       make LYS_OUTPUT_DIR=$(top-build-dir)/out/lybook-testdb $(OUT_FILES)
 
 $(outdir)/collated-files.list: $(OUT_FILES)
        echo $(sort $(filter-out %.xml,$(OUT_FILES))) > $@
index 1e790908a61c133ad9a9fa1f33e95bf6698ef839..2444ac853600668eb4900a4e58399d430fbcece1 100644 (file)
@@ -1,4 +1,5 @@
 \version "2.16.0"
+\include "melody.ly"
 \score {
-       \relative c'' { \key c \minor c4 es g2 }
+       \melody
 }
diff --git a/input/regression/lilypond-book/melody.ly b/input/regression/lilypond-book/melody.ly
new file mode 100644 (file)
index 0000000..e21f02c
--- /dev/null
@@ -0,0 +1,3 @@
+\version "2.16.0"
+\include "include/myvar.ily"
+melody = \relative c'' { \key c \minor c4 es g2 \myVar }
index bcad93601b0e8f39325bb93f6f03cb61dfd5a399..f5005ed71cbc981326b217997d308afa69e8f49b 100644 (file)
@@ -14,4 +14,9 @@ Within a lilypond block:
   \include "include/myvar.ily"
   \relative c'' { \myVar }
 \end{lilypond}
+
+Include a file that includes a file:
+
+\lilypondfile{include.ly}
+
 \end{document}
index 251fa087d80ebe334ec150d2cce2011e58da4a7d..bcc2a6ef4abefc374dfc39d00046bc3c14ea3e7d 100644 (file)
@@ -14,4 +14,9 @@ Within a lilypond block:
   \include "include/myvar.ily"
   \relative c'' { \myVar }
 \end{lilypond}
+
+Include a file that includes a file:
+
+\lilypondfile[quote,noindent]{include.ly}
+
 \end{document}
index 610eb23a3eb46e34eaa9d07f1e9ae3de34d71e2d..d32e767c176d8b740b37ea30b887920637fff636 100644 (file)
@@ -20,4 +20,8 @@ Within a lilypond block:
   \relative c'' { \myVar }
 @end lilypond
 
+Include a file that includes a file:
+
+@lilypondfile{include.ly}
+
 @bye
diff --git a/input/regression/lyric-combine-nullvoice.ly b/input/regression/lyric-combine-nullvoice.ly
new file mode 100644 (file)
index 0000000..0592dc4
--- /dev/null
@@ -0,0 +1,15 @@
+\version "2.19.11"
+\header {
+  texidoc ="Lyrics can be aligned to a @code{NullVoice} context,
+  which prints no notes, with the usual mechanisms for melismata."
+}
+\paper { ragged-right = ##f }
+\score { <<
+  \new Staff <<
+    { c''4. g'8 c''2 | g'8( f' g'4)~ g'2 } \\
+    { c'4 b c'8 e' g' e' | c'1 }
+    \new NullVoice = "nv" {
+      \autoBeamOff c4 r16 b,8. c8[ e8 g8 e8] | g8( f g4)~ g2 }
+  >>
+  \new Lyrics \lyricsto "nv" { free a -- lign -- ment }
+>> }
index 9ca834b542d9a45fa56d0a87db907b1c81c8d10d..82bfe0641d0435c5f482aebf8df38dedf38e26b3 100644 (file)
@@ -1,7 +1,7 @@
-\version "2.16.0"
+\version "2.19.13"
 #(ly:set-option 'warning-as-error #f)
-#(ly:expect-warning (ly:translate-cpp-warning-scheme "Cyclic markup detected: %s") 'cycle-markup)
-#(ly:expect-warning (ly:translate-cpp-warning-scheme "Cyclic markup detected: %s") 'cycleI-markup)
+#(ly:expect-warning (ly:translate-cpp-warning-scheme "Markup depth exceeds maximal value of %d; Markup: %s") 1024 'cycle-markup)
+#(ly:expect-warning (ly:translate-cpp-warning-scheme "Markup depth exceeds maximal value of %d; Markup: %s") 1024 'cycleI-markup)
 
 \header {
   texidoc = "Cyclic markup definitions should cause a warning, but
index c33568319802e06e098d82263a2f88cf0c8a6e68..550489f92d14df514943f2f561e46a1fc0735fbe 100644 (file)
@@ -27,7 +27,7 @@ been lowered
 
 }
 
-\version "2.19.2"
+\version "2.19.12"
 manuscriptBreak = { \break }
 
 
@@ -38,7 +38,7 @@ manuscriptBreak = { \break }
 %#(set-global-staff-size (* 5.8 mm))
     line-width = #(* mm 160)
     indent = 8\mm
-    system-system-spacing #'basic-distance = #10.3
+    system-system-spacing.basic-distance = #10.3
     ragged-bottom = ##t 
     }
 
index 3908f6bc6020884d1c768585931ca765c7f9bd18..ae58603ecf7f1671c77c3f065c2fedf6e849ccdf 100644 (file)
@@ -48,7 +48,7 @@ virtuoso that taught in Geneva.
 "
 }
 
-\version "2.16.0"
+\version "2.19.12"
 
 \include "mozart-hrn3-defs.ily"
 \include "mozart-hrn3-allegro.ily"
@@ -56,8 +56,8 @@ virtuoso that taught in Geneva.
 \include "mozart-hrn3-rondo.ily"
 
 \paper {
-  system-system-spacing #'basic-distance = 10
-  score-system-spacing #'basic-distance = 20
+  system-system-spacing.basic-distance = 10
+  score-system-spacing.basic-distance = 20
 }
 
 \book {
index 30417977366285e3fa472af0ac1667c43076f763..52e4c4e9142388ed97ea2e76b1e0deec214c798e 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.16.0"
+\version "2.19.12"
 
 \header {
 
@@ -9,8 +9,7 @@
 }
 
 \paper {
-  system-system-spacing
-    #'basic-distance = #10 % increase this value for more space
+  system-system-spacing.basic-distance = #10 % increase this value for more space
 }
 
 notes = \relative c {
index 08a45d36d6d4cda97ee27faf51407b445d048db3..117e6c244747b746e7fed314ff987c8e066bae48 100644 (file)
@@ -9,6 +9,6 @@ grob is tweaked."
 \relative c' {
   \override Stem.details.beamed-lengths = #'(6 10 8)
   c8[ c] c16[ c] c32[ c]
-  \revert Stem.details
+  \revert Stem.details.beamed-lengths
   c8[ c] c16[ c] c32[ c]
 }
index db23c7f2742662ae08f3c3fb561011403d4e81ab..71c2dd91da0148dfd1ba8c42688e014f370f169d 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.16.0"
+\version "2.19.12"
 
 \header {
   texidoc = "minimum-distance is correctly accounted for in page breaking."
@@ -6,7 +6,7 @@
 
 \book {
   \paper {
-    score-system-spacing #'minimum-distance = #'20
+    score-system-spacing.minimum-distance = #'20
     paper-height = 8\cm
   }
 
index f62e4722551e4c3f1e72041947f4c32c81efc3a9..2e150e61b6e94e05178fb99ea774fddfceb32607 100644 (file)
@@ -13,7 +13,7 @@ By setting @code{annotate-spacing}, we can see the effect of each property.
 
 }
 
-\version "2.17.6"
+\version "2.19.12"
 
 #(set-global-staff-size 11)
 
@@ -65,8 +65,8 @@ By setting @code{annotate-spacing}, we can see the effect of each property.
     ragged-last-bottom = ##f
     annotate-spacing = ##t
     obsolete-between-system-space = 1.0
-    system-system-spacing #'basic-distance = #(/ obsolete-between-system-space staff-space)
-    score-system-spacing #'basic-distance = #(/ obsolete-between-system-space staff-space)
+    system-system-spacing.basic-distance = #(/ obsolete-between-system-space staff-space)
+    score-system-spacing.basic-distance = #(/ obsolete-between-system-space staff-space)
     #(set! text-font-defaults
       (acons
        'font-size 6
index 80494988c36b1ed15945bde37d319fcdaf2227ef..2e73a60a4b2895e64a44a69847c53f3b0c6e9924 100644 (file)
@@ -4,7 +4,7 @@
 first system can be forced to be uniform."
 
 }
-\version "2.17.6"
+\version "2.19.12"
 
 #(set-default-paper-size "a6")
 
@@ -23,7 +23,7 @@ first system can be forced to be uniform."
 
   \paper {
     obsolete-page-top-space = 3 \cm
-    top-system-spacing #'basic-distance = #(/ obsolete-page-top-space staff-space)
+    top-system-spacing.basic-distance = #(/ obsolete-page-top-space staff-space)
   }
 }
 
index 5af168c697f06b761750039c00cf5fbd464b9341..3c16f09ab392f0332d5d9bf1416a4664c8aec0a9 100644 (file)
@@ -1,11 +1,11 @@
-\version "2.16.0"
+\version "2.19.12"
 
 \header {
   texidoc = "Nested properties can be set in the paper block."
 }
 
 \paper {
-  system-system-spacing #'minimum-distance = #0.0
+  system-system-spacing.minimum-distance = #0.0
 }
 
 { c1 \break c1 }
index ce359b740355c76fbc295290b22a94c54193ad83..3c1a6c88384cff1a8a9758059ed9d365ffb572b1 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.16.0"
+\version "2.19.12"
 
 \header {
   texidoc = "Setting individual nested paper properties does not
@@ -9,7 +9,7 @@ remove existing settings or break spacing annotation."
   \paper {
     annotate-spacing = ##t
     system-system-spacing = #'((basic-distance . 12) (minimum-distance . 8))
-    system-system-spacing #'padding = #1
+    system-system-spacing.padding = #1
   }
   \relative c' {
     \repeat unfold 10 { a4 d e f }
index fc60c5b33964bf8eb11cebe61224ae26225d704f..8442f60a96573d6e2810e9d1e8557f8878821f8e 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.6"
+\version "2.19.12"
 
 \header {
   texidoc = "Use @code{define-event-class}, scheme engraver methods,
@@ -12,7 +12,7 @@ in scheme."
    (let* ((meta-entry   (assoc-get 'meta grob-entry))
           (class        (assoc-get 'class meta-entry))
           (ifaces-entry (assoc-get 'interfaces meta-entry)))
-     (set-object-property! grob-name 'translation-type? list?)
+     (set-object-property! grob-name 'translation-type? ly:grob-properties?)
      (set-object-property! grob-name 'is-grob? #t)
      (set! ifaces-entry (append (case class
                                   ((Item) '(item-interface))
index ceb27b24902517a4b3178314338476bda505d460..9d13cbd213411eb38a2e879834e4273a4adfb2c9 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.17.15"
+\version "2.19.12"
 
 \header {
   texidoc = "The @code{Script} grobs should follow the descending melody line,
@@ -16,7 +16,7 @@ even though the @code{NoteHead} stencils are point stencils. The
 }
 
 {
-  \override Script #'direction = #DOWN
-  \override NoteHead #'stencil = #point-stencil
+  \override Script.direction = #DOWN
+  \override NoteHead.stencil = #point-stencil
   c'2.-> b8-- a-- g1->
 }
index 45a9945dfd7f67e4f613014121f0cab9b9a05932..8f51e2147545b31f7825b0453e2ef18bd4f38298 100644 (file)
@@ -8,7 +8,7 @@ heavily mutilated Edition Peters Morgenlied by Schubert"
 
 }
 
-\version "2.19.2"
+\version "2.19.12"
 #(ly:expect-warning (_ "(De)crescendo with unspecified starting volume in MIDI."))
 
 ignoreMelisma =        \set ignoreMelismata = ##t
@@ -20,7 +20,7 @@ ignoreMelismaOff = \unset ignoreMelismata
                                %#(set-global-staff-size (* 5.8 mm))
   indent = #(* mm 4)
   line-width = #(* mm 140)
-  system-system-spacing #'basic-distance = #10.3
+  system-system-spacing.basic-distance = #10.3
   ragged-bottom = ##t 
 }
 
index 62f5235b1c4693eb6b4f0fdb8bfd45703e4bdb38..ee0b6e88b9a55d3b2b42abc94a07d52c97aac18c 100644 (file)
@@ -25,6 +25,7 @@
 #include "paper-column.hh"
 #include "pitch.hh"
 #include "stencil.hh"
+#include "system.hh"
 #include "skyline-pair.hh"
 
 Stencil
@@ -43,32 +44,6 @@ parenthesize (Grob *me, Stencil m)
   return m;
 }
 
-/* If this gets called before line breaking, we will return a non-trivial
-   extent even if we belong to a tie and won't actually get printed. */
-static SCM
-get_extent (Grob *me, Axis a)
-{
-  Stencil *s = Stencil::unsmob (Accidental_interface::get_stencil (me));
-
-  if (s)
-    return ly_interval2scm (s->extent (a));
-  return ly_interval2scm (Interval ());
-}
-
-MAKE_SCHEME_CALLBACK (Accidental_interface, height, 1);
-SCM
-Accidental_interface::height (SCM smob)
-{
-  return get_extent (Grob::unsmob (smob), Y_AXIS);
-}
-
-MAKE_SCHEME_CALLBACK (Accidental_interface, width, 1);
-SCM
-Accidental_interface::width (SCM smob)
-{
-  return get_extent (Grob::unsmob (smob), X_AXIS);
-}
-
 MAKE_SCHEME_CALLBACK (Accidental_interface, horizontal_skylines, 1);
 SCM
 Accidental_interface::horizontal_skylines (SCM smob)
@@ -77,12 +52,7 @@ Accidental_interface::horizontal_skylines (SCM smob)
   if (!me->is_live ())
     return Skyline_pair ().smobbed_copy ();
 
-  /*
-   * Using the print function may trigger a suicide
-   * before line breaking. It is therefore `unpure' (c).
-   * We use the more basic get_stencil.
-   */
-  Stencil *my_stencil = Stencil::unsmob (get_stencil (me));
+  Stencil *my_stencil = Stencil::unsmob (me->get_property ("stencil"));
   if (!my_stencil)
     return Skyline_pair ().smobbed_copy ();
 
@@ -116,41 +86,42 @@ Accidental_interface::horizontal_skylines (SCM smob)
   return sky->smobbed_copy ();
 }
 
-MAKE_SCHEME_CALLBACK (Accidental_interface, pure_height, 3);
+MAKE_SCHEME_CALLBACK (Accidental_interface, height, 1);
 SCM
-Accidental_interface::pure_height (SCM smob, SCM start_scm, SCM)
+Accidental_interface::height (SCM smob)
 {
-  Item *me = dynamic_cast<Item *> (Grob::unsmob (smob));
-  int start = scm_to_int (start_scm);
-  int rank = me->get_column ()->get_rank ();
-
-  if (to_boolean (me->get_property ("forced"))
-      || !Grob::unsmob (me->get_object ("tie"))
-      || (rank == start + 1 && /* we are at the start of a line */
-          !to_boolean (me->get_property ("hide-tied-accidental-after-break"))))
-    {
-      Stencil *s = Stencil::unsmob (get_stencil (me));
-      if (s)
-        return ly_interval2scm (s->extent (Y_AXIS));
-    }
+  Grob *me = Grob::unsmob (smob);
+  Grob *tie = Grob::unsmob (me->get_object ("tie"));
+
+  if (tie
+      && !to_boolean (me->get_property ("forced"))
+      && to_boolean (me->get_property ("hide-tied-accidental-after-break")))
+    return ly_interval2scm (Interval ());
 
-  return ly_interval2scm (Interval ());
+  return Grob::stencil_height (smob);
 }
 
-MAKE_SCHEME_CALLBACK (Accidental_interface, print, 1);
+MAKE_SCHEME_CALLBACK (Accidental_interface, remove_tied, 1);
 SCM
-Accidental_interface::print (SCM smob)
+Accidental_interface::remove_tied (SCM smob)
 {
   Grob *me = Grob::unsmob (smob);
   Grob *tie = Grob::unsmob (me->get_object ("tie"));
 
   if (tie
+      && !to_boolean (me->get_property ("forced"))
       && (to_boolean (me->get_property ("hide-tied-accidental-after-break"))
-          || (!tie->original () && !to_boolean (me->get_property ("forced")))))
-    {
-      me->suicide ();
-      return SCM_EOL;
-    }
+          || !tie->original()))
+    me->suicide ();
+
+  return SCM_UNSPECIFIED;
+}
+
+MAKE_SCHEME_CALLBACK (Accidental_interface, print, 1);
+SCM
+Accidental_interface::print (SCM smob)
+{
+  Grob *me = Grob::unsmob (smob);
 
   return get_stencil (me);
 }
index cc756b7e21c2eec0991ba1b3c98cf53d6eb7884b..c48fe6fe338ce061a09aca899107c85407b532c3 100644 (file)
@@ -23,6 +23,7 @@
 #include "context-handle.hh"
 #include "duration.hh"
 #include "engraver.hh"
+#include "grob-properties.hh"
 #include "item.hh"
 #include "rest.hh"
 #include "spanner.hh"
@@ -240,7 +241,7 @@ Auto_beam_engraver::begin_beam ()
   stems_ = new vector<Item *>;
   grouping_ = new Beaming_pattern ();
   beaming_options_.from_context (context ());
-  beam_settings_ = updated_grob_properties (context (), ly_symbol2scm ("Beam"));
+  beam_settings_ = Grob_property_info (context (), ly_symbol2scm ("Beam")).updated ();
 
   beam_start_context_.set_context (context ()->get_parent_context ());
   beam_start_moment_ = now_mom ();
diff --git a/lily/clef-modifier.cc b/lily/clef-modifier.cc
new file mode 100644 (file)
index 0000000..c56b935
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2014--2014 Janek Warchoł <lemniskata.bernoullego@gmail.com>
+
+  LilyPond 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.
+
+  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/>.
+*/
+
+#include "item.hh"
+
+struct Clef_modifier
+{
+  DECLARE_SCHEME_CALLBACK (calc_parent_alignment, (SCM));
+  DECLARE_GROB_INTERFACE ();
+};
+
+MAKE_SCHEME_CALLBACK (Clef_modifier, calc_parent_alignment, 1)
+SCM
+Clef_modifier::calc_parent_alignment (SCM smob)
+{
+  Grob *me = Grob::unsmob (smob);
+  Grob *clef = me->get_parent (X_AXIS);
+  string full_clef_name = ly_scm2string (clef->get_property ("glyph"));
+  string clef_name = replace_all(&full_clef_name, "clefs.", "");
+
+  // find entry with keyname clef_type in clef-alignments
+  SCM alist_entry = scm_assq (ly_symbol2scm (clef_name.c_str ()),
+                              me->get_property ("clef-alignments"));
+
+  if (scm_is_pair (alist_entry))
+    {
+      SCM entry_value = scm_cdr (alist_entry);
+      // the value should be a pair of numbers - first is the alignment
+      // for modifiers below the clef, second for those above.
+      if (scm_is_pair (entry_value))
+        if (robust_scm2dir (me->get_property ("direction"), DOWN) == DOWN)
+          return scm_car (entry_value);
+        else
+          return scm_cdr (entry_value);
+
+      else // default alignment = centered
+        return scm_from_double (0);
+    }
+  else // default alignment = centered
+    return scm_from_double (0);
+}
+
+ADD_INTERFACE (Clef_modifier,
+               "The number describing transposition of the clef, placed below\n"
+               "or above clef sign. Usually this is 8 (octave transposition)\n"
+               "or 15 (two octaves), but LilyPond allows any integer here.",
+
+               /* properties */
+               "clef-alignments "
+              );
+
index b578321a9370c79ea79b6bd8256e687140ab55a0..5f2c8c70e5e4adeaeea4c67cc57354b4ac0b1000 100644 (file)
 #include "context.hh"
 #include "engraver.hh"
 #include "global-context.hh"
+#include "grob-properties.hh"
 #include "international.hh"
 #include "item.hh"
 #include "main.hh"
 #include "simple-closure.hh"
+#include "smobs.hh"
 #include "spanner.hh"
 #include "unpure-pure-container.hh"
 #include "warn.hh"
@@ -46,8 +48,8 @@ general_pushpop_property (Context *context,
         assert (false);
     }
 
-  sloppy_general_pushpop_property (context, context_property,
-                                   grob_property_path, new_value);
+  Grob_property_info (context, context_property).pushpop
+    (grob_property_path, new_value);
 }
 
 bool
@@ -61,6 +63,135 @@ typecheck_grob (SCM symbol, SCM value)
     || type_check_assignment (symbol, value, ly_symbol2scm ("backend-type?"));
 }
 
+class Grob_properties {
+  friend class Grob_property_info;
+  friend SCM ly_make_grob_properties (SCM);
+  // alist_ may contain unexpanded nested overrides
+  SCM alist_;
+  // based_on_ is the cooked_ value from the next higher context that
+  // alist_ is based on
+  SCM based_on_;
+  // cooked_ is a version of alist_ where nested overrides have been
+  // expanded
+  SCM cooked_;
+  // cooked_from_ is the value of alist_ from which the expansion has
+  // been done
+  SCM cooked_from_;
+  // nested_ is a count of nested overrides in alist_
+  int nested_;
+
+  Grob_properties (SCM alist, SCM based_on) :
+    alist_ (alist), based_on_ (based_on),
+    // if the constructor was called with lists possibly containing
+    // partial overrides, we would need to initialize with based_on in
+    // order to trigger an initial update.  But this should never
+    // happen, so we initialize straight with alist.
+    cooked_ (alist), cooked_from_ (alist), nested_ (0) { }
+  DECLARE_SIMPLE_SMOBS (Grob_properties);
+};
+
+#include "ly-smobs.icc"
+IMPLEMENT_SIMPLE_SMOBS (Grob_properties);
+IMPLEMENT_DEFAULT_EQUAL_P (Grob_properties);
+IMPLEMENT_TYPE_P (Grob_properties, "ly:grob-properties?");
+
+SCM
+Grob_properties::mark_smob (SCM smob)
+{
+  Grob_properties *gp = (Grob_properties *) SCM_SMOB_DATA (smob);
+  scm_gc_mark (gp->alist_);
+  scm_gc_mark (gp->based_on_);
+  scm_gc_mark (gp->cooked_);
+  return gp->cooked_from_;
+}
+
+int
+Grob_properties::print_smob (SCM /*smob*/, SCM port, scm_print_state *)
+{
+  scm_puts ("#<Grob_properties>", port);
+
+  return 1;
+}
+
+LY_DEFINE (ly_make_grob_properties, "ly:make-grob-properties",
+           1, 0, 0, (SCM alist),
+           "This packages the given property list @var{alist} in"
+           " a grob property container stored in a context property"
+           " with the name of a grob.")
+{
+  LY_ASSERT_TYPE (ly_is_list, alist, 1);
+  return Grob_properties (alist, SCM_EOL).smobbed_copy ();
+}
+
+
+Grob_property_info
+Grob_property_info::find ()
+{
+  if (props_)
+    return *this;
+  SCM res = SCM_UNDEFINED;
+  if (Context *c = context_->where_defined (symbol_, &res))
+    if (c != context_)
+      return Grob_property_info (c, symbol_, Grob_properties::unsmob (res));
+  props_  = Grob_properties::unsmob (res);
+  return *this;
+}
+
+bool
+Grob_property_info::check ()
+{
+  if (props_)
+    return true;
+  SCM res = SCM_UNDEFINED;
+  if (context_->here_defined (symbol_, &res))
+    props_ = Grob_properties::unsmob (res);
+  return props_;
+}
+
+bool
+Grob_property_info::create ()
+{
+  // Using scm_hashq_create_handle_x would seem like the one-lookup
+  // way to create a handle if it does not exist yet.  However, we
+  // need to check that there is a corresponding grob in this
+  // particular output first, and we have to do this in the global
+  // context.  By far the most frequent case will be that a
+  // Grob_properties for this context already exists, so we optimize
+  // for that and only check the global handle when the local
+  // context is pristine.
+  if (check ())
+    return true;
+  SCM current_context_val = SCM_EOL;
+  Context *g = context_->get_global_context ();
+  if (!g)
+    return false; // Context is probably dead
+
+  /*
+    Don't mess with MIDI.
+  */
+  if (g == context_
+      || !g->here_defined (symbol_, &current_context_val))
+    return false;
+
+  Grob_properties *def = Grob_properties::unsmob (current_context_val);
+
+  if (!def)
+    {
+      programming_error ("Grob definition expected");
+      return false;
+    }
+
+  // We create the new Grob_properties from the default definition
+  // since this is what we have available right now.  It may or may
+  // not be accurate since we don't take into account any
+  // prospective overrides in intermediate contexts.  If there are
+  // any, they will be factored in when `updated' is being called.
+  SCM props = Grob_properties (def->alist_, def->alist_).smobbed_copy ();
+  context_->set_property (symbol_, props);
+  props_ = Grob_properties::unsmob (props);
+  return props_;
+}
+
 /*
   Grob descriptions (ie. alists with layout properties) are
   represented as a (ALIST . BASED-ON) pair, where BASED-ON is the
@@ -72,135 +203,74 @@ typecheck_grob (SCM symbol, SCM value)
   indicates nested alists, eg. '(beamed-stem-lengths details)
 */
 void
-execute_override_property (Context *context,
-                           SCM context_property,
-                           SCM grob_property_path,
-                           SCM new_value)
+Grob_property_info::push (SCM grob_property_path, SCM new_value)
 {
-  SCM current_context_val = SCM_EOL;
-
-  if (!context->here_defined (context_property, &current_context_val))
-    {
-      Context *g = context->get_global_context ();
-      if (!g)
-        return; // Context is probably dead
-
-      /*
-        Don't mess with MIDI.
-      */
-      if (g == context
-          || !g->here_defined (context_property, &current_context_val))
-        return;
-
-      /* where != context */
-
-      SCM base = updated_grob_properties (context->get_parent_context (),
-                                          context_property);
-      current_context_val = scm_cons (base, base);
-      context->set_property (context_property, current_context_val);
-    }
-
-  if (!scm_is_pair (current_context_val))
-    {
-      programming_error ("Grob definition should be cons");
-      return;
-    }
-
-  SCM target_alist = scm_car (current_context_val);
+  /*
+    Don't mess with MIDI.
+  */
+  if (!create ())
+    return;
 
   SCM symbol = scm_car (grob_property_path);
-  if (scm_is_pair (scm_cdr (grob_property_path)))
+  SCM rest = scm_cdr (grob_property_path);
+  if (scm_is_pair (rest))
     {
-      new_value = nested_property_alist (ly_assoc_get (symbol, target_alist,
-                                                       SCM_EOL),
-                                         scm_cdr (grob_property_path),
-                                         new_value);
+      // poor man's typechecking
+      if (typecheck_grob (symbol, nested_create_alist (rest, new_value))) {
+        props_->alist_ = scm_acons (grob_property_path, new_value, props_->alist_);
+        props_->nested_++;
+      }
+      return;
     }
 
   /* it's tempting to replace the head of the list if it's the same
    property. However, we have to keep this info around, in case we have to
    \revert back to it.
   */
-  target_alist = scm_acons (symbol, new_value, target_alist);
 
-
-  /*
-    tack onto alist.  We can use set_car, since
-    updated_grob_properties () in child contexts will check
-    for changes in the car.
-  */
   if (typecheck_grob (symbol, new_value))
-    {
-      scm_set_car_x (current_context_val, target_alist);
-    }
-}
-
-/*
-  do a pop (indicated by new_value==SCM_UNDEFINED) or push
- */
-void
-sloppy_general_pushpop_property (Context *context,
-                                 SCM context_property,
-                                 SCM grob_property_path,
-                                 SCM new_value)
-{
-  if (new_value == SCM_UNDEFINED)
-    execute_revert_property (context, context_property,
-                             grob_property_path);
-  else
-    execute_override_property (context, context_property,
-                               grob_property_path,
-                               new_value);
+    props_->alist_ = scm_acons (symbol, new_value, props_->alist_);
 }
 
 /*
   Revert the property given by property_path.
 */
 void
-execute_revert_property (Context *context,
-                         SCM context_property,
-                         SCM grob_property_path)
+Grob_property_info::pop (SCM grob_property_path)
 {
-  SCM current_context_val = SCM_EOL;
-  if (context->here_defined (context_property, &current_context_val))
-    {
-      SCM current_alist = scm_car (current_context_val);
-      SCM daddy = scm_cdr (current_context_val);
+  if (!check ())
+    return;
 
-      if (!scm_is_pair (grob_property_path)
-          || !scm_is_symbol (scm_car (grob_property_path)))
-        {
-          programming_error ("Grob property path should be list of symbols.");
-          return;
-        }
+  SCM current_alist = props_->alist_;
+  SCM daddy = props_->based_on_;
 
-      SCM symbol = scm_car (grob_property_path);
-      if (scm_is_pair (scm_cdr (grob_property_path)))
-        {
-          SCM current_sub_alist = ly_assoc_get (symbol, current_alist, SCM_EOL);
-          SCM new_val
-            = nested_property_revert_alist (current_sub_alist,
-                                            scm_cdr (grob_property_path));
-
-          if (scm_is_pair (current_alist)
-              && scm_caar (current_alist) == symbol
-              && current_alist != daddy)
-            current_alist = scm_cdr (current_alist);
-
-          current_alist = scm_acons (symbol, new_val, current_alist);
-          scm_set_car_x (current_context_val, current_alist);
-        }
-      else
-        {
-          SCM new_alist = evict_from_alist (symbol, current_alist, daddy);
+  if (!scm_is_pair (grob_property_path)
+      || !scm_is_symbol (scm_car (grob_property_path)))
+    {
+      programming_error ("Grob property path should be list of symbols.");
+      return;
+    }
 
-          if (new_alist == daddy)
-            context->unset_property (context_property);
-          else
-            context->set_property (context_property,
-                                   scm_cons (new_alist, daddy));
-        }
+  if (scm_is_pair (scm_cdr (grob_property_path)))
+    {
+      SCM old_alist = current_alist;
+      current_alist = evict_from_alist (grob_property_path, current_alist, daddy);
+      if (scm_is_eq (old_alist, current_alist))
+        return;
+      props_->nested_--;
     }
+  else
+    current_alist = evict_from_alist (scm_car (grob_property_path),
+                                      current_alist, daddy);
+
+  if (scm_is_eq (current_alist, daddy))
+    {
+      assert (props_->nested_ == 0);
+      props_ = 0;
+      context_->unset_property (symbol_);
+      return;
+    }
+  props_->alist_ = current_alist;
 }
 /*
   Convenience: a push/pop grob property using a single grob_property
@@ -208,13 +278,11 @@ execute_revert_property (Context *context,
 */
 void
 execute_pushpop_property (Context *context,
-                          SCM context_property,
+                          SCM grob,
                           SCM grob_property,
                           SCM new_value)
 {
-  general_pushpop_property (context, context_property,
-                            scm_list_1 (grob_property),
-                            new_value);
+  Grob_property_info (context, grob).pushpop (scm_list_1 (grob_property), new_value);
 }
 
 /*
@@ -234,14 +302,13 @@ apply_property_operations (Context *tg, SCM pre_init_ops)
           SCM context_prop = scm_car (entry);
           SCM val = scm_cadr (entry);
           SCM grob_prop_path = scm_cddr (entry);
-          sloppy_general_pushpop_property (tg, context_prop, grob_prop_path, val);
+          Grob_property_info (tg, context_prop).push (grob_prop_path, val);
         }
       else if (type == ly_symbol2scm ("pop"))
         {
           SCM context_prop = scm_car (entry);
-          SCM val = SCM_UNDEFINED;
           SCM grob_prop_path = scm_cdr (entry);
-          sloppy_general_pushpop_property (tg, context_prop, grob_prop_path, val);
+          Grob_property_info (tg, context_prop).pop (grob_prop_path);
         }
       else if (type == ly_symbol2scm ("assign"))
         tg->set_property (scm_car (entry), scm_cadr (entry));
@@ -256,45 +323,31 @@ apply_property_operations (Context *tg, SCM pre_init_ops)
   Return the object alist for SYM, checking if its base in enclosing
   contexts has changed. The alist is updated if necessary.
 */
-SCM
-updated_grob_properties (Context *tg, SCM sym)
+SCM Grob_property_info::updated ()
 {
-  assert (scm_is_symbol (sym));
+  assert (scm_is_symbol (symbol_));
+
+  Grob_property_info where = find ();
 
-  SCM props;
-  tg = tg->where_defined (sym, &props);
-  if (!tg)
+  if (!where)
     return SCM_EOL;
 
+  Context *dad = where.context_->get_parent_context ();
+
   SCM daddy_props
-    = (tg->get_parent_context ())
-      ? updated_grob_properties (tg->get_parent_context (), sym)
-      : SCM_EOL;
+    = dad ? Grob_property_info (dad, symbol_).updated () : SCM_EOL;
 
-  if (!scm_is_pair (props))
+  SCM based_on = where.props_->based_on_;
+  SCM alist = where.props_->alist_;
+  if (!scm_is_eq (based_on, daddy_props))
     {
-      programming_error ("grob props not a pair?");
-      return SCM_EOL;
-    }
-
-  SCM based_on = scm_cdr (props);
-  if (based_on == daddy_props)
-    return scm_car (props);
-  else
-    {
-      SCM copy = daddy_props;
-      SCM *tail = &copy;
-      SCM p = scm_car (props);
-      while (p != based_on)
-        {
-          *tail = scm_cons (scm_car (p), daddy_props);
-          tail = SCM_CDRLOC (*tail);
-          p = scm_cdr (p);
-        }
-
-      scm_set_car_x (props, copy);
-      scm_set_cdr_x (props, daddy_props);
-
-      return copy;
+      where.props_->based_on_ = daddy_props;
+      alist = partial_list_copy (alist, based_on, daddy_props);
+      where.props_->alist_ = alist;
     }
+  if (scm_is_eq (where.props_->cooked_from_, alist))
+    return where.props_->cooked_;
+  where.props_->cooked_from_ = alist;
+  where.props_->cooked_ = nalist_to_alist (alist, where.props_->nested_);
+  return where.props_->cooked_;
 }
index aaa5b529b3d8033ce83a4a94972f3f0f4d46c7ca..c3822100af4b079301bef089ac0ce0f27bd9fe58 100644 (file)
@@ -21,6 +21,7 @@
 #include "context.hh"
 #include "context-def.hh"
 #include "dispatcher.hh"
+#include "grob-properties.hh"
 
 LY_DEFINE (ly_context_current_moment,
            "ly:context-current-moment",
@@ -70,7 +71,7 @@ LY_DEFINE (ly_context_grob_definition, "ly:context-grob-definition",
   LY_ASSERT_SMOB (Context, context, 1);
   LY_ASSERT_TYPE (ly_is_symbol, name, 2);
 
-  return updated_grob_properties (tr, name);
+  return Grob_property_info (tr, name).updated ();
 }
 
 LY_DEFINE (ly_context_pushpop_property, "ly:context-pushpop-property",
index 4a897c60920d5544ab84d3e69698bdeaf31b4238..a9048ccb9c60037a811a731114d8ca558ab9f8d1 100644 (file)
@@ -21,6 +21,7 @@
 #include "dispatcher.hh"
 #include "engraver-group.hh"
 #include "grob.hh"
+#include "grob-properties.hh"
 #include "paper-score.hh"
 #include "translator-dispatch-list.hh"
 #include "warn.hh"
@@ -31,10 +32,9 @@ Engraver_group::override (SCM sev)
 {
   Stream_event *ev = Stream_event::unsmob (sev);
 
-  sloppy_general_pushpop_property (context (),
-                                   ev->get_property ("symbol"),
-                                   ev->get_property ("property-path"),
-                                   ev->get_property ("value"));
+  Grob_property_info (context (), ev->get_property ("symbol"))
+    .push (ev->get_property ("property-path"),
+           ev->get_property ("value"));
 }
 
 IMPLEMENT_LISTENER (Engraver_group, revert);
@@ -43,10 +43,8 @@ Engraver_group::revert (SCM sev)
 {
   Stream_event *ev = Stream_event::unsmob (sev);
 
-  sloppy_general_pushpop_property (context (),
-                                   ev->get_property ("symbol"),
-                                   ev->get_property ("property-path"),
-                                   SCM_UNDEFINED);
+  Grob_property_info (context (), ev->get_property ("symbol"))
+    .pop (ev->get_property ("property-path"));
 }
 
 void
index 74a6554e3a413bcf2d669f2192902cc975222213..76117a66e8847e153d52c31f7513379be597e4d3 100644 (file)
@@ -20,6 +20,7 @@
 #include "engraver.hh"
 
 #include "context.hh"
+#include "grob-properties.hh"
 #include "international.hh"
 #include "music.hh"
 #include "paper-column.hh"
@@ -117,7 +118,7 @@ Engraver::internal_make_grob (SCM symbol,
   (void)fun;
 #endif
 
-  SCM props = updated_grob_properties (context (), symbol);
+  SCM props = Grob_property_info (context (), symbol).updated ();
 
   Grob *grob = 0;
 
index b7c55b5045f903b0b22ec46c3b5cd10a707b0dc5..8afef8f5ea9000df79896b278051181b14621207 100644 (file)
@@ -77,6 +77,11 @@ bool find_in_range (SCM vector, int low, int hi, int min, int max)
 bool
 Hara_kiri_group_spanner::request_suicide (Grob *me, int start, int end)
 {
+  extract_grob_set (me, "make-dead-when", foes);
+  for (vsize i = 0; i < foes.size (); i++)
+    if (foes[i]->is_live () && !request_suicide_alone (foes[i], start, end))
+      return true;
+
   if (!request_suicide_alone (me, start, end))
     return false;
 
@@ -185,13 +190,16 @@ Hara_kiri_group_spanner::add_interesting_item (Grob *me, Grob *n)
 ADD_INTERFACE (Hara_kiri_group_spanner,
                "A group spanner that keeps track of interesting items.  If it"
                " doesn't contain any after line breaking, it removes itself"
-               " and all its children.",
+               " and all its children.  Children may be prioritized in layers"
+               " via @code{remove-layer}, in which case only the"
+               " lowest-numbered non-empty layer is retained.",
 
                /* properties */
                "items-worth-living "
                "important-column-ranks "
                "keep-alive-with "
+               "make-dead-when "
                "remove-empty "
                "remove-first "
+               "remove-layer "
               );
-
index 6b2c8709fb83a67d35108fba7ed56cd5c589225f..cbb61b772a0b2fd01c54b815fae0207828ba7df3 100644 (file)
@@ -30,10 +30,9 @@ class Accidental_interface
 {
 public:
   DECLARE_SCHEME_CALLBACK (print, (SCM));
-  DECLARE_SCHEME_CALLBACK (height, (SCM));
-  DECLARE_SCHEME_CALLBACK (width, (SCM));
   DECLARE_SCHEME_CALLBACK (horizontal_skylines, (SCM));
-  DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM));
+  DECLARE_SCHEME_CALLBACK (height, (SCM));
+  DECLARE_SCHEME_CALLBACK (remove_tied, (SCM));
 
   DECLARE_GROB_INTERFACE ();
   static SCM get_stencil (Grob *me);
index 0595bf851389c655080c34e1199aaa1437bb02fa..c8bea9fad98c571201f25fb52433cc13f56be71a 100644 (file)
@@ -137,13 +137,8 @@ public:
 */
 
 void apply_property_operations (Context *tg, SCM pre_init_ops);
-void execute_revert_property (Context *context,
-                              SCM context_property,
-                              SCM grob_property_path);
 void execute_pushpop_property (Context *trg, SCM prop, SCM eltprop, SCM val);
-void sloppy_general_pushpop_property (Context *context,
-                                      SCM context_property, SCM grob_property_path, SCM val);
-SCM updated_grob_properties (Context *tg, SCM sym);
+
 Context *find_context_below (Context *where,
                              SCM type_sym, const string &id);
 bool melisma_busy (Context *);
@@ -169,7 +164,9 @@ void set_context_property_on_children (Context *trans, SCM sym, SCM val);
 }
 
 SCM nested_property_alist (SCM alist, SCM prop_path, SCM value);
-SCM nested_property_revert_alist (SCM alist, SCM prop_path);
+SCM nested_create_alist (SCM prop_path, SCM value);
+SCM partial_list_copy (SCM alist, SCM tail, SCM newtail);
 SCM evict_from_alist (SCM, SCM, SCM);
+SCM nalist_to_alist (SCM nalist, int nested);
 
 #endif /* CONTEXT_HH */
diff --git a/lily/include/grob-properties.hh b/lily/include/grob-properties.hh
new file mode 100644 (file)
index 0000000..3756944
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2014 David Kastrup <dak@gnu.org>
+
+  LilyPond 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.
+
+  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/>.
+*/
+
+// This module is concerned with managing grob-properties (more
+// exactly, grob property templates, as they are not yet part of a
+// grob) inside of context properties, in a context-hierarchical
+// manner, with one stack for properties and subproperties per
+// context.
+
+#ifndef GROB_PROPERTIES_HH
+#define GROB_PROPERTIES_HH
+
+#include "lily-proto.hh"
+
+// Several algorithms on Grob_properties need self-identifying
+// information to work properly, but there is no point in storing them
+// in the Grob_properties data structure itself.  Instead we create a
+// reflective data structure containing all necessary information for
+// the algorithms processing Grob_properties.
+
+class Grob_property_info {
+  Context * const context_;
+  SCM const symbol_;
+  Grob_properties *props_;
+public:
+  Grob_property_info (Context *context, SCM symbol, Grob_properties *props = 0)
+    : context_ (context), symbol_ (symbol), props_ (props)
+  { }
+  operator bool () { return props_; }
+  Grob_property_info find ();
+  bool check ();
+  bool create ();
+  SCM updated ();
+  void push (SCM path, SCM value);
+  void pop (SCM path);
+  void pushpop (SCM path, SCM value)
+  {
+    if (SCM_UNBNDP (value))
+      return pop (path);
+    push (path, value);
+  }
+};
+#endif
index acc817f87812779cc3c20a9290b7eac379d59363..1bdf9aa7bc20a75db5f1565e210eaf216858dd3b 100644 (file)
@@ -81,8 +81,6 @@ inline SCM ly_symbol2scm (char const *x) { return scm_from_locale_symbol ((x));
 #endif
 
 /*
-  TODO: rename me to ly_c_lily_module_eval
-
   we don't have to protect the result; it's already part of the
   exports list of the module.
 */
@@ -95,11 +93,12 @@ inline SCM ly_symbol2scm (char const *x) { return scm_from_locale_symbol ((x));
     if (__builtin_constant_p ((x)))                                     \
       {                                                                 \
         if (!cached)                                                    \
-          value = cached = scm_eval (scm_from_locale_symbol (x),                \
-                                    global_lily_module);                \
+          value = cached =                                              \
+            scm_variable_ref (scm_c_module_lookup (global_lily_module, (x))); \
       }                                                                 \
     else                                                                \
-      value = scm_eval (scm_from_locale_symbol (x), global_lily_module);        \
+      value =                                                           \
+        scm_variable_ref (scm_c_module_lookup (global_lily_module, (x))); \
     value;                                                              \
   })
 
index 83a71ab67273d4c0b3f7ef1953d24aa9b62c1254..3dd0825b27047b310b923bf66105f1f4442f5d56 100644 (file)
@@ -35,26 +35,19 @@ class Audio_piano_pedal;
 class Audio_staff;
 class Audio_tempo;
 class Audio_text;
-class Audio_tie;
 class Audio_time_signature;
 class Auto_change_iterator;
-class Auto_change_music;
 class Axis_group_engraver;
 class Bar_engraver;
-class Bar_req_collect_engraver;
 class Beaming_pattern;
 class Beam_scoring_problem;
 class Beam_configuration;
 class Beam_quant_parameters;
 class Bezier;
-class Bezier_bow;
 class Book;
 class Box;
-class Break_algorithm;
 class Change_iterator;
-class Change_translator;
 class Chord_tremolo_iterator;
-class Cluster_engraver;
 class Column_x_positions;
 class Context;
 class Context_def;
@@ -74,17 +67,15 @@ class Event_iterator;
 class Font_metric;
 class Font_size_engraver;
 class Global_context;
-class Gourlay_breaking;
 class Grace_fixup;
 class Grace_iterator;
 class Grace_music;
 class Grob;
 class Grob_array;
 class Grob_info;
-class Hara_kiri_line_group_engraver;
+class Grob_properties;
 class Includable_lexer;
 class Input;
-class Input_file_results;
 class Item;
 class Key_performer;
 class Keyword_ent;
@@ -93,16 +84,12 @@ class Ligature_bracket_engraver;
 class Ligature_engraver;
 class Lily_lexer;
 class Lily_parser;
-class Lilypond_context_key;
-class Lilypond_grob_key;
-class Line_group_engraver_group;
 class Listener;
 class Lookup;
 class Lyric_combine_music;
 class Lyric_combine_music_iterator;
 class Lyric_engraver;
 class Lyric_performer;
-class Lyric_phrasing_engraver;
 class Mensural_ligature_engraver;
 class Midi_chunk;
 class Midi_control_function_value_change;
@@ -126,7 +113,6 @@ class Modified_font_metric;
 class Moment;
 class Music;
 class Music_iterator;
-class Music_list;
 class Music_output;
 class Music_sequence;
 class Music_wrapper;
@@ -144,12 +130,10 @@ class Paper_score;
 class Performance;
 class Performer;
 class Performer_group;
-class Piano_bar_engraver;
 class Pitch;
 class Pitch_squash_engraver;
 class Prob;
 class Property_iterator;
-class Rational;
 class Relative_octave_music;
 class Repeated_music;
 class Rhythmic_music_iterator;
@@ -157,27 +141,20 @@ class Scale;
 class Scheme_hash_table;
 class Scheme_engraver;
 class Score;
-class Score_context;
 class Score_engraver;
 class Score_performer;
-class Sequential_music;
-class Sequential_music_iterator;
 class Simple_music_iterator;
 class Simple_spacer;
-class Simple_spacer_wrapper;
 class Simultaneous_music;
 class Simultaneous_music_iterator;
 class Skyline;
-class Skyline_entry;
 class Skyline_pair;
 class Slur_configuration;
 class Slur_score_state;
 class Source_file;
 class Sources;
 class Spacing_options;
-class Span_score_bar_engraver;
 class Spanner;
-class Staff_group_bar_engraver;
 class Staff_performer;
 class Stencil;
 class Stream_event;
@@ -191,14 +168,9 @@ class Tie_performer;
 class Time_scaled_music;
 class Time_scaled_music_iterator;
 class Time_signature_performer;
-class Timing_engraver;
 class Timing_translator;
-class Translation_property;
 class Translator;
-class Translator_change;
 class Translator_group;
-class Transposed_music;
-class yyFlexLexer;
 
 typedef void (Engraver::*Engraver_void_function_engraver_grob_info) (Grob_info);
 typedef void (Translator::*Translator_void_method_ptr) ();
index 9fdabd296247388778aa3588783f7d8ea5883bb1..6f688c09ffab6888e131e3271c76fc3b64969237 100644 (file)
@@ -36,7 +36,7 @@ public:
   static Grob *accidentals (Grob *me);
   static Slice head_positions_interval (Grob *me);
   static Grob *first_head (Grob *me);
-  static Interval calc_main_heads_extent (Grob *me);
+  static Interval calc_main_extent (Grob *me);
   static Grob *get_rest (Grob *me);
   static void set_stem (Grob *me, Grob *);
   static void add_head (Grob *me, Grob *);
index f007670e7ae8974fa184b612f997bb1a83bec344..bcde47616d9915d7032944a3d2374d2e19cb6b39 100644 (file)
@@ -236,7 +236,6 @@ Item::pure_height (Grob *g, int start, int end)
     return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
   /* Note: cached_pure_height_ does not notice if start changes, implicitly
      assuming that Items' pure_heights do not depend on 'start' or 'end'.
-     Accidental_interface::pure_height(), however, does depend on 'start'.
   */
 
   cache_pure_height (Grob::pure_height (this, start, end));
index 78a10050cd24ff55544f52c65618084d166aa0ba..c65ff455313f382a74a1f3c28504da924fbdc5f4 100644 (file)
@@ -51,14 +51,40 @@ Keep_alive_together_engraver::finalize ()
 {
   for (vsize i = 0; i < group_spanners_.size (); ++i)
     {
-      SCM grob_array_scm = Grob_array::make_array ();
-      Grob_array *ga = Grob_array::unsmob (grob_array_scm);
-
-      // It would make Hara_kiri_group_spanner::request_suicide a _little_
-      // faster if we removed each grob from its own array. It seems
-      // unnecessary for now, though.
-      ga->set_array (group_spanners_);
-      group_spanners_[i]->set_object ("keep-alive-with", grob_array_scm);
+      SCM this_layer = group_spanners_[i]->get_property ("remove-layer");
+      if (scm_is_false (this_layer))
+        continue;
+
+      SCM live_scm = Grob_array::make_array ();
+      Grob_array *live = Grob_array::unsmob (live_scm);
+      SCM dead_scm = Grob_array::make_array ();
+      Grob_array *dead = Grob_array::unsmob (dead_scm);
+
+      for (vsize j = 0; j < group_spanners_.size (); ++j)
+        {
+          if (i == j)
+            continue;
+          SCM that_layer = group_spanners_[j]->get_property ("remove-layer");
+          if (scm_is_false (that_layer))
+            continue;
+          if (!scm_is_integer (this_layer))
+            {
+              // Unspecified layers are kept alive by anything else
+              live->add (group_spanners_[j]);
+              continue;
+            }
+          // an explicit layer is only affected by explicit layers
+          if (!scm_is_integer (that_layer))
+            continue;
+          if (scm_is_true (scm_num_eq_p (that_layer, this_layer)))
+            live->add (group_spanners_[j]);
+          else if (scm_is_true (scm_less_p (that_layer, this_layer)))
+            dead->add (group_spanners_[j]);
+        }
+      if (!live->empty ())
+        group_spanners_[i]->set_object ("keep-alive-with", live_scm);
+      if (!dead->empty ())
+        group_spanners_[i]->set_object ("make-dead-when", dead_scm);
     }
 }
 
index 8b0859630ec04dcd0ea9c0a5fd1b3a1d0ad61843..0c364c1bb20443c148de9a5e7851740aca5ebb3e 100644 (file)
@@ -422,7 +422,7 @@ BOM_UTF8    \357\273\277
                return token;
 }
 
-<INITIAL,notes,lyrics>{ 
+<INITIAL,notes,lyrics,chords>{
        \<\<    {
                 yylval = SCM_UNSPECIFIED;
                return DOUBLE_ANGLE_OPEN;
@@ -433,7 +433,7 @@ BOM_UTF8    \357\273\277
        }
 }
 
-<INITIAL,notes>{
+<INITIAL,notes,chords>{
        \<      {
                 yylval = SCM_UNSPECIFIED;
                return ANGLE_OPEN;
index 9c3cc73387a74dbd2533206b8148a03308871225..4c79918f09b6abe37e990fcd81348ab710a82c58 100644 (file)
 #include "context.hh"
 #include "grob.hh"
 
-/*
-  Drop symbol from the list alist..alist_end.
- */
+// scm_reverse_x without the checks
 SCM
-evict_from_alist (SCM symbol, SCM alist, SCM alist_end)
+fast_reverse_x (SCM lst, SCM tail)
 {
-  SCM new_alist = SCM_EOL;
-  SCM *tail = &new_alist;
-
-  while (alist != alist_end)
+  while (!scm_is_null (lst))
     {
-      if (ly_is_equal (scm_caar (alist), symbol))
-        {
-          alist = scm_cdr (alist);
-          break;
-        }
-
-      *tail = scm_cons (scm_car (alist), SCM_EOL);
-      tail = SCM_CDRLOC (*tail);
-      alist = scm_cdr (alist);
+      SCM n = scm_cdr (lst);
+      scm_set_cdr_x (lst, tail);
+      tail = lst;
+      lst = n;
     }
+  return tail;
+}
 
-  *tail = alist;
-  return new_alist;
+// copy the spine of lst not including tail, appending newtail
+// returns new list.
+SCM
+partial_list_copy (SCM lst, SCM tail, SCM newtail)
+{
+  SCM p = SCM_EOL;
+  for (; !scm_is_eq (lst, tail); lst = scm_cdr (lst))
+    p = scm_cons (scm_car (lst), p);
+  return fast_reverse_x (p, newtail);
 }
 
-/*
-  PROP_PATH should be big-to-small ordering
- */
 SCM
-nested_property_alist (SCM alist, SCM prop_path, SCM value)
+assq_tail (SCM key, SCM alist, SCM based_on = SCM_EOL)
 {
-  SCM new_value = SCM_BOOL_F;
-  if (scm_is_pair (scm_cdr (prop_path)))
+  for (SCM p = alist; !scm_is_eq (p, based_on); p = scm_cdr (p))
     {
-      SCM sub_alist = ly_assoc_get (scm_car (prop_path), alist, SCM_EOL);
-      new_value = nested_property_alist (sub_alist, scm_cdr (prop_path), value);
+      if (scm_is_eq (scm_caar (p), key))
+        return p;
     }
-  else
+  return SCM_BOOL_F;
+}
+
+SCM
+assoc_tail (SCM key, SCM alist, SCM based_on = SCM_EOL)
+{
+  for (SCM p = alist; !scm_is_eq (p, based_on); p = scm_cdr (p))
     {
-      new_value = value;
+      if (ly_is_equal (scm_caar (p), key))
+        return p;
     }
+  return SCM_BOOL_F;
+}
 
-  return scm_acons (scm_car (prop_path), new_value, alist);
+// Like assq, but removes the found element destructively
+SCM assq_pop_x (SCM key, SCM *alist)
+{
+  for (SCM p = *alist; scm_is_pair (p); p = *(alist = SCM_CDRLOC (p)))
+    {
+      if (scm_is_eq (scm_caar (p), key))
+        {
+          *alist = scm_cdr (p);
+          return scm_car (p);
+        }
+    }
+  return SCM_BOOL_F;
 }
 
 /*
-  Recursively purge alist of prop_path:
+  Drop key from the list alist..alist_end.
+ */
+SCM
+evict_from_alist (SCM key, SCM alist, SCM alist_end)
+{
+// shortcircuit to an eq-using assoc_tail variant when key is a symbol
+// (common case)
+  SCM p = scm_is_symbol (key) ? assq_tail (key, alist, alist_end)
+    : assoc_tail (key, alist, alist_end);
+  if (scm_is_true (p))
+    return partial_list_copy (alist, p, scm_cdr (p));
+  return alist;
+}
 
-  revert ((sym, val) : L, [sym]) = L
-  revert ((sym, val) : L, sym : props) =
-    (sym, revert (val, rest-props)) ++ L
-  revert ((sym, val) : L, p ++ rest-props) =
-    (sym, val) : revert (L, p ++ rest-props)
+// This is the same as
+// nested_property_alist (SCM_EOL, prop_path, value) but faster
+SCM
+nested_create_alist (SCM prop_path, SCM value)
+{
+  if (scm_is_null (prop_path))
+    return value;
+  return scm_acons (scm_car (prop_path),
+                    nested_create_alist (scm_cdr (prop_path), value),
+                    SCM_EOL);
+}
 
+/*
+  PROP_PATH should be big-to-small ordering
  */
+
+// Take the given alist and replace the given nested property with the
+// given value.  Multiple overrides of the same property path are not
+// coalesced for efficiency reasons: they are considered rare enough
+// to not be worth the cost of detecting them.  When sublists are
+// modified, however, we remove the original sublist and copy the
+// spine before it.  The cost for finding the sublist has already been
+// paid anyway.
+
+// A typical use case for this routine is applying (possibly nested)
+// tweaks to a grob property list.
+
 SCM
-nested_property_revert_alist (SCM alist, SCM prop_path)
+nested_property_alist (SCM alist, SCM prop_path, SCM value)
 {
-  assert (scm_is_pair (prop_path));
+  // replacement moves to the front.
+  SCM key = scm_car (prop_path);
+  SCM rest = scm_cdr (prop_path);
+  if (scm_is_pair (rest))
+    {
+      SCM where = assq_tail (key, alist);
+      if (scm_is_false (where))
+        return scm_acons (key, nested_create_alist (rest, value), alist);
+      return scm_acons (key, nested_property_alist (scm_cdar (where),
+                                                    rest,
+                                                    value),
+                        partial_list_copy (alist, where, scm_cdr (where)));
+    }
+  // Outcommented code would coalesce multiple overrides of the same
+  // property
+#if 0
+  SCM where = assq_tail (alist, key);
+  if (scm_is_true (where))
+    return scm_acons (key, value,
+                      partial_list_copy (alist, where, scm_cdr (where)));
+#endif
+  return scm_acons (key, value, alist);
+}
 
-  SCM wanted_sym = scm_car (prop_path);
+void
+set_nested_property (Grob *me, SCM big_to_small, SCM value)
+{
+  SCM alist = me->get_property (scm_car (big_to_small));
 
-  SCM new_list = SCM_EOL;
-  SCM *tail = &new_list;
-  for (SCM s = alist; scm_is_pair (s); s = scm_cdr (s))
-    {
-      SCM sub_sym = scm_caar (s);
-      SCM old_val = scm_cdar (s);
+  alist = nested_property_alist (alist, scm_cdr (big_to_small), value);
 
-      if (sub_sym == wanted_sym)
-        {
-          if (scm_is_pair (scm_cdr (prop_path)))
-            {
-              SCM new_val = nested_property_revert_alist (old_val, scm_cdr (prop_path));
+  me->set_property (scm_car (big_to_small), alist);
+}
 
-              /* nothing changed: drop newly constructed list. */
-              if (old_val == new_val)
-                return alist;
+// This converts an alist with nested overrides in it to a proper
+// alist.  The number of nested overrides is known in advance,
+// everything up to the last nested override is copied, the tail is
+// shared
 
-              *tail = scm_acons (sub_sym, new_val, SCM_EOL);
-              tail = SCM_CDRLOC (*tail);
-            }
+SCM
+nalist_to_alist (SCM nalist, int nested)
+{
+  if (!nested)
+    return nalist;
+  SCM copied = SCM_EOL;
+  SCM partials = SCM_EOL;
+  // partials is a alist of partial overrides
+  for (;;)
+    {
+      SCM elt = scm_car (nalist);
+      nalist = scm_cdr (nalist);
+      SCM key = scm_car (elt);
+      if (scm_is_pair (key))
+        // nested override: record for key in partial
+        {
+          SCM pair = scm_sloppy_assq (scm_car (key), partials);
+          if (scm_is_false (pair))
+            partials = scm_acons (scm_car (key), scm_list_1 (elt),
+                                  partials);
           else
+            scm_set_cdr_x (pair, scm_cons (elt, scm_cdr (pair)));
+          if (!--nested)
+            break;
+        }
+      else
+        // plain override: apply any known corresponding partials
+        {
+          SCM pair = assq_pop_x (key, &partials);
+          if (scm_is_true (pair))
             {
-              /* old value is dropped. */
+              SCM value = scm_cdr (elt);
+              for (SCM pp = scm_cdr (pair); scm_is_pair (pp); pp = scm_cdr (pp))
+                value = nested_property_alist (value, scm_cdaar (pp), scm_cdar (pp));
+              copied = scm_acons (key, value, copied);
             }
-
-          *tail = scm_cdr (s);
-          return new_list;
+          else
+            copied = scm_cons (elt, copied);
         }
-
-      *tail = scm_acons (sub_sym, old_val, SCM_EOL);
-      tail = SCM_CDRLOC (*tail);
     }
+  // Now need to work off the remaining partials.  All of them are
+  // unique, so we can push them to `copied' after resolving without
+  // losing information.
 
-  /* Wanted symbol not found: drop newly constructed list. */
-  return alist;
+  for (;scm_is_pair (partials); partials = scm_cdr (partials))
+    {
+      SCM pair = scm_car (partials);
+      SCM key = scm_car (pair);
+      SCM elt = scm_sloppy_assq (key, nalist);
+      SCM value = SCM_EOL;
+      if (scm_is_true (elt))
+        value = scm_cdr (elt);
+
+      for (SCM pp = scm_cdr (pair); scm_is_pair (pp); pp = scm_cdr (pp))
+        value = nested_property_alist (value, scm_cdaar (pp), scm_cdar (pp));
+
+      copied = scm_acons (key, value, copied);
+    }
+  return fast_reverse_x (copied, nalist);
 }
 
-void
-set_nested_property (Grob *me, SCM big_to_small, SCM value)
+#if 0
+// Alternative approach: don't unfold those partial overrides while
+// they are part of contexts but instead use a special accessor for
+// subproperties in the grob.  Not used or tested for now.
+
+SCM
+nassq_ref (SCM key, SCM nalist, SCM fallback)
 {
-  SCM alist = me->get_property (scm_car (big_to_small));
+  SCM partials = SCM_EOL;
+  // partials is list of partial overrides for the given property
+  for (SCM p = nalist; scm_is_pair (p); p = scm_cdr (p))
+    {
+      SCM elt = scm_car (p);
+      SCM pkey = scm_car (elt);
+      if (scm_is_pair (pkey))
+        {
+          if (scm_is_eq (scm_car (pkey), key))
+            partials = scm_cons (elt, partials);
+        }
+      else if (scm_is_eq (pkey, key))
+        {
+          SCM value = scm_cdr (elt);
+          for (; scm_is_pair (partials); partials = scm_cdr (partials))
+            {
+              value = nested_property_alist (value, scm_cdaar (partials),
+                                            scm_cdar (partials));
+            }
+          return value;
+        }
+    }
+  if (scm_is_pair (partials))
+    {
+      // Bit of a quandary here: we have only subproperty overrides
+      // but no main property.  Could be a programming error, but we
+      // instead override an empty list.
+      SCM value = nested_create_alist (scm_cdaar (partials), scm_cdar (partials));
+      partials = scm_cdr (partials);
+      for (; scm_is_pair (partials); partials = scm_cdr (partials))
+        value = nested_property_alist (value, scm_cdaar (partials),
+                                      scm_cdar (partials));
+      return value;
+    }
+  return SCM_UNBNDP (fallback) ? SCM_EOL : fallback;
+}
 
-  alist = nested_property_alist (alist, scm_cdr (big_to_small), value);
+// Also needed for this approach to make sense: an accessor for true
+// subproperties.
+SCM
+nassq_nested_ref (SCM key, SCM subpath, SCM nalist, SCM fallback);
+// To be implemented
 
-  me->set_property (scm_car (big_to_small), alist);
-}
+#endif
index c5d06cfb6831a6bd678c27289132a0120129c349..760e37dc1956c045d51d3250bee9fad5269ee73b 100644 (file)
@@ -158,22 +158,29 @@ Note_column::first_head (Grob *me)
 
 /*
   Return extent of the noteheads in the "main column",
-  i.e. excluding any suspended noteheads.
+  (i.e. excluding any suspended noteheads), or extent
+  of the rest (if there are no heads).
 */
 Interval
-Note_column::calc_main_heads_extent (Grob *me)
+Note_column::calc_main_extent (Grob *me)
 {
-  if (get_stem (me))
-    return first_head (me)->extent (me, X_AXIS);
-  else
-    {
-      // no stems => no suspended noteheads.
-      extract_grob_set (me, "note-heads", heads);
-      if (heads.size())
-        return heads[0]->extent (me, X_AXIS);
-      else
-        return Interval (0, 0);
-    }
+    Grob *main_head;
+    if (get_stem (me))
+        main_head = first_head (me);
+    else
+      {
+        // no stems => no suspended noteheads.
+        extract_grob_set (me, "note-heads", heads);
+        if (heads.size())
+        main_head = heads[0];
+      }
+    Grob *main_item = main_head
+            ? main_head
+            : Grob::unsmob (me->get_object ("rest"));
+
+    return main_item
+            ? main_item->extent (me, X_AXIS)
+            : Interval (0, 0);
 }
 
 /*
index c8365abf13e05a62bda7fb9a0e6efcead001e195..4a805f1970f7a4c74b832d1c70d96e572ac965b7 100644 (file)
@@ -2656,7 +2656,7 @@ chord_body_elements:
        ;
 
 chord_body_element:
-       pitch exclamations questions octave_check post_events
+       pitch_or_tonic_pitch exclamations questions octave_check post_events
        {
                bool q = to_boolean ($3);
                bool ex = to_boolean ($2);
@@ -2919,6 +2919,11 @@ pitch:
        }
        ;
 
+pitch_or_tonic_pitch:
+       pitch
+       | steno_tonic_pitch
+       ;
+
 gen_text_def:
        full_markup {
                Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
index e4a39d4fff4a5f9715cfacd418acc26964104528..620c60634962aaf5870c371913f3d233288c7b7c 100644 (file)
@@ -66,10 +66,7 @@ Rest_collision_engraver::process_acknowledged ()
         {
           Grob *column = g->get_parent (X_AXIS);
           if (!column)
-            {
-              g->warning (_ ("rhythmic head is not part of a rhythmic column"));
               continue;
-            }
 
           // Only include rests that start now. Include notes that started any time.
           Paper_column *paper_column = dynamic_cast<Item *> (column)->get_column ();
index b361d03fc15770783150b03c11b446932054c8ca..54f34575d224045867b84c498c4311c4021a925f 100644 (file)
@@ -24,6 +24,7 @@
 #include "context-def.hh"
 #include "dispatcher.hh"
 #include "global-context.hh"
+#include "grob-properties.hh"
 #include "international.hh"
 #include "main.hh"
 #include "open-type-font.hh"
@@ -88,7 +89,7 @@ Score_engraver::initialize ()
   pscore_->unprotect ();
   context ()->set_property ("output", pscore_->self_scm ());
 
-  SCM props = updated_grob_properties (context (), ly_symbol2scm ("System"));
+  SCM props = Grob_property_info (context (), ly_symbol2scm ("System")).updated ();
 
   pscore_->typeset_system (new System (props));
 
index 9c73b6c7d8cf8cd6bf458b9648964150a28378b4..6b6662641f95bdde975af004bf9137557514fc0e 100644 (file)
@@ -115,9 +115,9 @@ Self_alignment_interface::aligned_on_parent (Grob *me, Axis a)
               (him, ly_symbol2scm ("note-column-interface"), a);
   else
     {
-      if (ly_scm2bool(me->internal_get_property (ly_symbol2scm ("X-align-on-main-noteheads")))
+      if (to_boolean (me->get_property ("X-align-on-main-noteheads"))
           && Note_column::has_interface (him))
-        he = Note_column::calc_main_heads_extent(him);
+        he = Note_column::calc_main_extent(him);
       else
         he = him->extent (him, a);
     }
index d02ff4ae54873006e1b60228684194381207b3fe..9cf52dc98f05052fbe207e266cb064fd92811b08 100644 (file)
@@ -22,6 +22,7 @@
 #include "align-interface.hh"
 #include "context.hh"
 #include "grob.hh"
+#include "grob-properties.hh"
 #include "item.hh"
 #include "pointer-group-interface.hh"
 #include "engraver.hh"
@@ -142,7 +143,7 @@ Span_bar_stub_engraver::process_acknowledged ()
 
       for (vsize j = 0; j < affected_contexts.size (); j++)
         {
-          Item *it = new Item (updated_grob_properties (affected_contexts[j], ly_symbol2scm ("SpanBarStub")));
+          Item *it = new Item (Grob_property_info (affected_contexts[j], ly_symbol2scm ("SpanBarStub")).updated ());
           it->set_parent (spanbars_[i], X_AXIS);
           Grob_info gi = make_grob_info (it, spanbars_[i]->self_scm ());
           gi.rerouting_daddy_context_ = affected_contexts[j];
index 0dc4f36360c5a83f1114c26e4a4b3cf6250372fa..f45d06ac3bb2bb1d3eaa57eaefbf82dce9034147 100644 (file)
@@ -95,6 +95,11 @@ Text_interface::interpret_string (SCM layout_smob,
   return fm->text_stencil (layout, str, is_music).smobbed_copy ();
 }
 
+static size_t markup_depth = 0;
+
+void markup_up_depth (void *) { ++markup_depth; }
+void markup_down_depth (void *) { --markup_depth; }
+
 MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Text_interface, interpret_markup, 3, 0,
                                    "Convert a text markup into a stencil."
                                    "  Takes three arguments, @var{layout}, @var{props}, and @var{markup}.\n"
@@ -114,28 +119,19 @@ Text_interface::interpret_markup (SCM layout_smob, SCM props, SCM markup)
       SCM func = scm_car (markup);
       SCM args = scm_cdr (markup);
 
-      /* Use a hare/tortoise algorithm to detect whether we are in a cycle,
-       * i.e. whether we have already encountered the same markup in the
-       * current branch of the markup tree structure. */
-      static vector<SCM> encountered_markups;
-      size_t depth = encountered_markups.size ();
-      if (depth > 0)
-        {
-          int slow = depth / 2;
-          if (ly_is_equal (encountered_markups[slow], markup))
-            {
-              string name = ly_symbol2string (scm_procedure_name (func));
-              // TODO: Also print the arguments of the markup!
-              non_fatal_error (_f ("Cyclic markup detected: %s", name));
-              return Stencil ().smobbed_copy ();
-            }
-        }
-
       /* Check for non-terminating markups, e.g. recursive calls with
        * changing arguments */
       SCM opt_depth = ly_get_option (ly_symbol2scm ("max-markup-depth"));
       size_t max_depth = robust_scm2int (opt_depth, 1024);
-      if (depth > max_depth)
+
+      // Don't use SCM_F_DYNWIND_REWINDABLE since it may be expensive
+      // without any obvious use for retaining continuations into
+      // markup expansion
+      scm_dynwind_begin ((scm_t_dynwind_flags)0);
+      // scm_dynwind_rewind_handler (markup_up_depth, 0, SCM_F_WIND_EXPLICITLY);
+      markup_up_depth (0);
+      scm_dynwind_unwind_handler (markup_down_depth, 0, SCM_F_WIND_EXPLICITLY);
+      if (markup_depth > max_depth)
         {
           string name = ly_symbol2string (scm_procedure_name (func));
           // TODO: Also print the arguments of the markup!
@@ -144,9 +140,8 @@ Text_interface::interpret_markup (SCM layout_smob, SCM props, SCM markup)
           return Stencil ().smobbed_copy ();
         }
 
-      encountered_markups.push_back (markup);
       SCM retval = scm_apply_2 (func, layout_smob, props, args);
-      encountered_markups.pop_back ();
+      scm_dynwind_end ();
       return retval;
     }
   else
index d4755f1b9a019344f1019819e9264b036cb8f9d9..8a016bde21e1d12d6bbe05f4ecce4d34a48630e9 100644 (file)
@@ -213,7 +213,7 @@ Tie_formatting_problem::set_column_chord_outline (vector<Item *> bounds,
 
           Grob *acc = Grob::unsmob (heads[i]->get_object ("accidental-grob"));
           if (acc)
-            acc->get_property ("stencil"); /* trigger tie-related suicide */
+            acc->get_property ("after-line-breaking"); /* trigger tie-related suicide */
 
           if (acc && acc->is_live () && dir == RIGHT)
             {
index 6e784a1a656df012dc60d2dd4ecd471f8fbedd57..4ff7f6f3e07c7d6f07399f228938a4f49e7eeeba 100644 (file)
@@ -23,7 +23,7 @@ That's it.  For more information, visit http://lilypond.org .
 
 %}
 
-\version "2.19.11"  % necessary for upgrading to future LilyPond versions.
+\version "2.19.12"  % necessary for upgrading to future LilyPond versions.
 
 \header{
   title = "A scale in LilyPond"
index 912a4b1a958bcb5d44065f42c2f2ab66c1175126..641c7b8512703155e316deff094c2fc7be67ef70 100644 (file)
@@ -32,7 +32,7 @@ Good luck with LilyPond!  Happy engraving.
 
 %}
 
-\version "2.19.11"  % necessary for upgrading to future LilyPond versions.
+\version "2.19.12"  % necessary for upgrading to future LilyPond versions.
 
 \header{
   title = "A scale in LilyPond"
index ec34cd64c33fa1187504bfc9ebd02f5a14ec4768..4c61334d4033ff5245816d22e5a9d7978284528e 100644 (file)
@@ -99,7 +99,6 @@
   \defaultchild "Voice"
   \accepts "Voice"
   \accepts "CueVoice"
-  \accepts "NullVoice"
 
   \description "Handles clefs, bar lines, keys, accidentals.  It can contain
 @code{Voice} contexts."
@@ -578,6 +577,7 @@ automatically when an output definition (a @code{\\score} or
   \accepts "ChoirStaff"
   \accepts "PianoStaff"
   \accepts "Devnull"
+  \accepts "NullVoice"
   \accepts "NoteNames"
   \accepts "FiguredBass"
 
@@ -772,54 +772,30 @@ context."
 \context {
   \name "NullVoice"
   \type "Engraver_group"
-
-  \description "Non-printing context, typically used for aligning
-lyrics in polyphonic situations, or with @code{\partcombine}."
+  \description "For aligning lyrics without printing notes"
 
   %% don't route anything out of here
   \alias "Staff"
   \alias "Voice"
 
-  %% all three are needed for ties to work with lyrics
+  % provide non-printing NoteHeads with proper extents for lyric alignment
   \consists "Note_heads_engraver"
-  \consists "Rhythmic_column_engraver"
-  \consists "Tie_engraver"
-
-  %% both are needed for melismas to work with \autoBeamOff
-  \consists "Beam_engraver"
-  \consists "Stem_engraver"
-
-  %% needed for slurs to work with lyrics
-  \consists "Slur_engraver"
-
-  %% keep noteheads inside the staff
-  \consists "Pitch_squash_engraver"
-  squashedPosition = 0
+  \omit NoteHead
+  \override NoteHead.X-extent = #(lambda (g)
+    (ly:stencil-extent (ly:note-head::print g) X))
 
-  %% `\omit NoteHead' would give slur attachment errors
   \omit Accidental
+  \omit AccidentalCautionary
+  \omit AccidentalSuggestion
+
+  % the engravers that control the 'busy' flags for note-onsets and melismata
+  \consists "Grob_pq_engraver"
+  \consists "Tie_engraver"
+  \omit Tie
+  \consists "Beam_engraver"
   \omit Beam
-  \omit Dots
-  \omit Flag
-  \omit Rest
+  \consists "Slur_engraver"
   \omit Slur
-  \omit Stem
-  \omit Tie
-
-  %% let these take up space (for lyric extenders, etc.)
-  \override NoteHead.transparent = ##t
-  \override TabNoteHead.transparent = ##t
-
-  %% don't let notes shift
-  \override NoteHead.X-offset = 0
-  \override NoteColumn.ignore-collision = ##t
-
-  %% keep beams and stems inside the staff
-  \override Beam.positions = #'(1 . 1)
-  \override Stem.length = 0
-
-  %% prevent "weird stem size" warnings
-  \override Stem.direction = #UP
 }
 
 \context {
index b7b8ca086acc2fa467c93390b5c6c79033062804..706b160755d458a9b2f1ac41b25fd487df8853f5 100644 (file)
@@ -192,8 +192,8 @@ as an engraver for convenience."
 #(define (format-textspan engraver event)
    (let* ((context (ly:translator-context engraver))
           (moment (ly:context-current-moment context))
-          (spanner-props (ly:context-property context 'TextSpanner))
-          (details (chain-assoc-get 'bound-details spanner-props))
+          (spanner-props (ly:context-grob-definition context 'TextSpanner))
+          (details (assoc-get 'bound-details spanner-props))
           (left-props (assoc-get 'left details '()))
           (left-text (assoc-get 'text left-props '())))
      (print-line engraver
index fea1c9b8884bee6d59a5eb9808b303b3e6d26fb4..477c9c6538172a9b098b831c7542d9155ea1b3aa 100644 (file)
@@ -467,8 +467,8 @@ grobdescriptions =
 in the format of @code{all-grob-descriptions}.")
    (ly:make-context-mod
     (map (lambda (p)
-          (list 'assign (car p) (list (cdr p))))
-        descriptions)))
+          (list 'assign (car p) (ly:make-grob-properties (cdr p))))
+         descriptions)))
 
 harmonicByFret = #(define-music-function (parser location fret music) (number? ly:music?)
   (_i "Convert @var{music} into mixed harmonics; the resulting notes resemble
index ecc97aedb72d9004dc6fbe0e84b96e6f1ffa95d6..297a40d2f5f867f868c7e4c147163ed91d4c51f6 100644 (file)
@@ -26,7 +26,6 @@
   \name Staff
   \accepts Voice
   \accepts CueVoice
-  \accepts NullVoice
   \defaultchild Voice
 
   \consists "Staff_performer"
   \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"
   \accepts TabStaff
   \accepts StaffGroup
   \accepts Devnull
+  \accepts NullVoice
   \accepts ChoirStaff
   \accepts RhythmicStaff
   \accepts ChordNames
index 8ee48b782111cc7492481817d365574f76691871..790b11cdadc5ec777abd2d0f46c4e796d34c4c7c 100644 (file)
@@ -6,10 +6,10 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: lilypond 2.19.11\n"
+"Project-Id-Version: lilypond 2.19.12\n"
 "Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu."
 "lilypond.bugs\n"
-"POT-Creation-Date: 2014-08-03 14:21+0100\n"
+"POT-Creation-Date: 2014-08-17 16:01+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1811,7 +1811,7 @@ msgstr ""
 msgid "cannot find line breaking that satisfies constraints"
 msgstr ""
 
-#: context-property.cc:43
+#: context-property.cc:44
 msgid "need symbol arguments for \\override and \\revert"
 msgstr ""
 
@@ -2750,7 +2750,7 @@ msgstr ""
 msgid "no such internal option: %s"
 msgstr ""
 
-#: property-iterator.cc:119
+#: property-iterator.cc:115
 #, c-format
 msgid "not a grob name, `%s'"
 msgstr ""
index 69fdc4fa6867401cdcd40fecbf16b4e6324ed4b7..4bc4252e79da3bad9cb15876eb2f4218a4f24d2f 100644 (file)
@@ -644,10 +644,20 @@ printing diff against existing file." % filename)
             if not os.path.isdir (dst_path):
                 os.makedirs (dst_path)
             try:
-                os.link (src, dst)
-            except AttributeError:
-                shutil.copyfile (src, dst)
-            except OSError:
+                if (self.global_options.use_source_file_names
+                        and isinstance (self, LilypondFileSnippet)):
+                    fout = open (dst, 'w')
+                    fin = open (src, 'r')
+                    for line in fin.readlines ():
+                        fout.write (line.replace (self.basename (), self.final_basename ()))
+                    fout.close ()
+                    fin.close ()
+                else:
+                    try:
+                        os.link (src, dst)
+                    except AttributeError:
+                        shutil.copyfile (src, dst)
+            except (IOError, OSError):
                 error (_ ('Could not overwrite file %s') % dst)
                 raise CompileError(self.basename())
 
index 2c3290a4c88573a25a90b2c6cd688105b1430e0f..e07006e35048c3aca50207c2516492ceb708f955 100644 (file)
@@ -83,7 +83,7 @@ found in @file{scm/bar-line.scm}.
  "The number describing transposition of the clef, placed below
 or above clef sign. Usually this is 8 (octave transposition)
 or 15 (two octaves), but LilyPond allows any integer here."
- '())
+ '(clef-alignments))
 
 (ly:add-interface
  'dynamic-interface
index 35f0074a88de07538712e29d39c651af28445cb2..a81eed50092532ff51f15dac177a062e2edc8386 100644 (file)
@@ -179,6 +179,8 @@ 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).")
+     (clef-alignments ,list? "An alist of parent-alignments
+that should be used for clef modifiers with various clefs")
      (clip-edges ,boolean? "Allow outward pointing beamlets at the
 edges of beams?")
      (collapse-height ,ly:dimension? "Minimum height of system start
@@ -467,9 +469,9 @@ etc. are already taken.")
 ;;; h
 ;;;
      (hair-thickness ,number? "Thickness of the thin line in a bar
-line, expressed as a multiple of the default staff-line thickness
-(i.e. the visual output is @emph{not} influenced by changes to
-@code{@var{Staff}.StaffSymbol.thickness}).")
+line, expressed as a multiple of the default staff-line
+thickness (i.e. the visual output is @emph{not} influenced by changes
+to @code{@var{Staff}.StaffSymbol.thickness}).")
      (harp-pedal-details ,list? "An alist of detailed grob properties
 for harp pedal diagrams.  Each alist entry consists of a
 @code{(@var{property} . @var{value})} pair.  The properties which can
@@ -593,9 +595,9 @@ if this column is the start of a system.")
      (line-positions ,list? "Vertical positions of staff lines.")
      (line-thickness ,number? "For slurs and ties, this is the
 diameter of the virtual @qq{pen} that draws the two arcs of the
-curve's outline, which intersect at the endpoints.  This property
-is expressed as a multiple of the current staff-line thickness
-(i.e. the visual output is influenced by changes to
+curve's outline, which intersect at the endpoints.  This property is
+expressed as a multiple of the current staff-line thickness (i.e. the
+visual output is influenced by changes to
 @code{@var{Staff}.StaffSymbol.thickness}).")
      (long-text ,markup? "Text markup.  See @ruser{Formatting text}.")
 
@@ -786,6 +788,12 @@ number, the quicker the slur attains its @code{height-limit}.")
 interesting items.")
      (remove-first ,boolean? "Remove the first staff of an orchestral
 score?")
+     (remove-layer ,integer? "The @code{Keep_alive_together_engraver}
+removes all @code{VerticalAxisGroup} grobs with a @code{remove-layer}
+larger than the smallest retained @code{remove-layer}.  Set to
+@code{#f} to make a layer invisible to the
+@code{Keep_alive_together_engraver}, set to @code{'()} to have it not
+participate in the layering decisions.")
      (replacement-alist ,list? "Alist of strings.
 The key is a string of the pattern to be replaced.  The value is a
 string of what should be displayed.  Useful for ligatures.")
@@ -1239,6 +1247,8 @@ empty in a particular staff, then that staff is erased.")
      (left-neighbor ,ly:grob? "The right-most column that has a spacing-wish
 for this column.")
 
+     (make-dead-when ,ly:grob-array? "An array of other
+@code{VerticalAxisGroup}s.  If any of them are alive, then we will turn dead.")
      (melody-spanner ,ly:grob? "The @code{MelodyItem} object for a stem.")
      (minimum-translations-alist ,list? "An list of translations for a given
 start and end point.")
index 53401d3a42daf2362d464c7bd42ad11c260382e6..4139ff13daeea48e9b46d94320a023c4b12f7f60 100644 (file)
@@ -29,6 +29,7 @@
   `(
     (Accidental
      . (
+        (after-line-breaking . ,ly:accidental-interface::remove-tied)
         (alteration . ,accidental-interface::calc-alteration)
         (avoid-slur . inside)
         (glyph-name . ,accidental-interface::glyph-name)
@@ -36,7 +37,6 @@
         (stencil . ,ly:accidental-interface::print)
         (horizontal-skylines . ,(ly:make-unpure-pure-container ly:accidental-interface::horizontal-skylines))
         (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
-        (X-extent . ,ly:accidental-interface::width)
         (Y-extent . ,accidental-interface::height)
         (meta . ((class . Item)
                  (interfaces . (accidental-interface
@@ -45,6 +45,7 @@
 
     (AccidentalCautionary
      . (
+        (after-line-breaking . ,ly:accidental-interface::remove-tied)
         (alteration . ,accidental-interface::calc-alteration)
         (avoid-slur . inside)
         (glyph-name-alist . ,standard-alteration-glyph-name-alist)
@@ -74,6 +75,7 @@
 
     (AccidentalSuggestion
      . (
+        (after-line-breaking . ,ly:accidental-interface::remove-tied)
         (alteration . ,accidental-interface::calc-alteration)
         (direction . ,UP)
         (font-size . -2)
@@ -85,7 +87,6 @@
         (side-axis . ,Y)
         (staff-padding . 0.25)
         (stencil . ,ly:accidental-interface::print)
-        (X-extent . ,ly:accidental-interface::width)
         (X-offset . ,ly:self-alignment-interface::aligned-on-x-parent)
         (Y-extent . ,accidental-interface::height)
         (Y-offset . ,side-position-interface::y-aligned-side)
      . (
         (break-visibility . ,(grob::inherit-parent-property
                               X 'break-visibility))
+        (clef-alignments . ((G . (-0.2 . 0.1))
+                            (F . (-0.3 . -0.2))
+                            (C . (0 . 0))))
         (color . ,(grob::inherit-parent-property
                    X 'color))
         (font-shape . italic)
         (font-size . -4)
-        (parent-alignment-X . ,CENTER)
+        (parent-alignment-X . ,ly:clef-modifier::calc-parent-alignment)
         (self-alignment-X . ,CENTER)
         (staff-padding . 0.7)
         (stencil . ,ly:text-interface::print)
         (extra-spacing-width . (+inf.0 . -inf.0))
         (outside-staff-priority . 500)
         (padding . 0.5)
+        (parent-alignment-X . #f)
         (self-alignment-X . ,LEFT)
         (side-axis . ,Y)
         (staff-padding . 0.5)
         (stencil . ,ly:text-interface::print)
         (Y-extent . ,grob::always-Y-extent-from-stencil)
-        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+        (X-offset . ,ly:self-alignment-interface::aligned-on-x-parent)
         (Y-offset . ,side-position-interface::y-aligned-side)
         (meta . ((class . Item)
                  (interfaces . (font-interface
         (font-encoding . fetaMusic)
         (horizon-padding . 0.1) ; to avoid interleaving with accidentals
         (positioning-done . ,ly:script-interface::calc-positioning-done)
+        (self-alignment-X . ,CENTER)
         (side-axis . ,Y)
 
         ;; padding set in script definitions.
                  (interfaces . (font-interface
                                 outside-staff-interface
                                 script-interface
+                                self-alignment-interface
                                 side-position-interface))))))
 
     (ScriptColumn
         (extra-spacing-width . (+inf.0 . -inf.0))
         (font-shape . italic)
         (padding . 0.0) ;; padding relative to SostenutoPedalLineSpanner
+        (parent-alignment-X . #f)
         (self-alignment-X . ,CENTER)
         (stencil . ,ly:text-interface::print)
         (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
-        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+        (X-offset . ,ly:self-alignment-interface::aligned-on-x-parent)
         (Y-extent . ,grob::always-Y-extent-from-stencil)
         (meta . ((class . Item)
                  (interfaces . (font-interface
      . (
         (extra-spacing-width . (+inf.0 . -inf.0))
         (padding . 0.0)  ;; padding relative to SustainPedalLineSpanner
+        (parent-alignment-X . #f)
         (self-alignment-X . ,CENTER)
         (stencil . ,ly:sustain-pedal::print)
         (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
-        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+        (X-offset . ,ly:self-alignment-interface::aligned-on-x-parent)
         (Y-extent . ,grob::always-Y-extent-from-stencil)
         (meta . ((class . Item)
                  (interfaces . (font-interface
         (extra-spacing-width . (+inf.0 . -inf.0))
         (font-shape . italic)
         (padding . 0.0)  ;; padding relative to UnaCordaPedalLineSpanner
+        (parent-alignment-X . #f)
         (self-alignment-X . ,CENTER)
         (stencil . ,ly:text-interface::print)
         (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
         (Y-extent . ,grob::always-Y-extent-from-stencil)
-        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+        (X-offset . ,ly:self-alignment-interface::aligned-on-x-parent)
         (meta . ((class . Item)
                  (interfaces . (font-interface
                                 piano-pedal-script-interface
 (for-each (lambda (x)
             ;; (display (car x)) (newline)
 
-            (set-object-property! (car x) 'translation-type? list?)
+            (set-object-property! (car x) 'translation-type? ly:grob-properties?)
             (set-object-property! (car x) 'is-grob? #t))
           all-grob-descriptions)
 
index 2f589d01ffd04c3f6aef037f36c8969bc8a7e351..e4126ef3ffb50c6ebd4a8fe9a506dadf321d9c9f 100644 (file)
@@ -750,7 +750,7 @@ messages into errors.")
 (define (dump-profile base last this)
   (let* ((outname (format #f "~a.profile" (dir-basename base ".ly")))
          (diff (map - this last)))
-    (ly:progress "\nWriting timing to ~a..." outname)
+    (ly:progress "\nWriting timing to ~a...\n" outname)
     (format (open-file outname "w")
             "time: ~a\ncells: ~a\n"
             (if (ly:get-option 'dump-cpu-profile)
index 2df06bd528bdd29bcbc3dc73e290c1445618326a..739c581a14816bbccf0e92d33bed84ea3b60f0e8 100644 (file)
@@ -731,8 +731,7 @@ and duration-log @var{log}."
 
 (define-public accidental-interface::height
   (ly:make-unpure-pure-container
-   ly:accidental-interface::height
-   ly:accidental-interface::pure-height))
+   ly:accidental-interface::height))
 
 (define-public cancellation-glyph-name-alist
   '((0 . "accidentals.natural")))
@@ -1157,7 +1156,7 @@ parent or the parent has no setting."
   (ly:grob-property grob 'positioning-done)
   (let* ((shift (ly:grob-property grob 'toward-stem-shift 0.0))
          (note-head-location
-          (ly:self-alignment-interface::centered-on-x-parent grob))
+          (ly:self-alignment-interface::aligned-on-x-parent grob))
          (note-head-grob (ly:grob-parent grob X))
          (stem-grob (ly:grob-object note-head-grob 'stem)))
 
index 7f40b63fb83bd3aa5f8e2d5c2ab1a1813fd1f135..bb51d83e416b787ae2bbf7e44390f4d3dff6e5a6 100755 (executable)
@@ -14,7 +14,7 @@ fi
 
 ### make sure convert-ly is up-to-date
 cd $BUILD_DIR
-make pythonmodules
+make python-modules
 cd $TOP_SRC_DIR
 
 ### update manuals
index 9cdd14742b76e1dda97211f351f818fdc8d15921..f38fb4f7e38d5ec62e46b319f1cd174269448e20 100644 (file)
@@ -417,7 +417,7 @@ def process_snippets (cmd, snippets,
     logfile = name.replace('.ly', '')
     file (name, 'wb').write (contents)
 
-    system_in_directory (' '.join ([cmd, ly.mkarg (name)]),
+    system_in_directory (' '.join ([cmd, ly.mkarg (name.replace (os.path.sep, '/'))]),
                          lily_output_dir,
                          logfile)
 
@@ -621,12 +621,25 @@ def do_file (input_filename, included=False):
         progress (_ ("Removing `%s'") % output_filename)
         raise BookSnippet.CompileError
 
+def adjust_include_path (path, outpath):
+    """Rewrite an include path relative to the dir where lilypond is launched.
+    Always use forward slashes since this is what lilypond expects."""
+    path = os.path.expanduser (path)
+    path = os.path.expandvars (path)
+    path = os.path.normpath (path)
+    if os.path.isabs (outpath):
+        return os.path.abspath (path).replace (os.path.sep, '/')
+    if os.path.isabs (path):
+        return path.replace (os.path.sep, '/')
+    return os.path.join (inverse_relpath (original_dir, outpath), path).replace (os.path.sep, '/')
+
 def inverse_relpath (path, relpath):
     """Given two paths, the second relative to the first,
-    return the first path relative to the second."""
+    return the first path relative to the second.
+    Always use forward slashes since this is what lilypond expects."""
     if os.path.isabs (relpath):
-        return os.path.abspath (path)
-    relparts = []
+        return os.path.abspath (path).replace (os.path.sep, '/')
+    relparts = ['']
     parts = os.path.normpath (path).split (os.path.sep)
     for part in os.path.normpath (relpath).split (os.path.sep):
         if part == '..':
@@ -635,7 +648,7 @@ def inverse_relpath (path, relpath):
         else:
             relparts.append ('..')
             parts.append (part)
-    return os.path.sep.join (relparts[::-1])
+    return '/'.join (relparts[::-1])
 
 def do_options ():
     global global_options
@@ -648,13 +661,17 @@ def do_options ():
 
     if global_options.lily_output_dir:
         global_options.lily_output_dir = os.path.expanduser (global_options.lily_output_dir)
+        for i, path in enumerate(global_options.include_path):
+            global_options.include_path[i] = adjust_include_path (path, global_options.lily_output_dir)
         global_options.include_path.insert (0, inverse_relpath (original_dir, global_options.lily_output_dir))
 
-    if global_options.output_dir:
+    elif global_options.output_dir:
         global_options.output_dir = os.path.expanduser (global_options.output_dir)
+        for i, path in enumerate(global_options.include_path):
+            global_options.include_path[i] = adjust_include_path (path, global_options.output_dir)
         global_options.include_path.insert (0, inverse_relpath (original_dir, global_options.output_dir))
 
-    global_options.include_path.insert (0, ".")
+    global_options.include_path.insert (0, "./")
 
     # Load the python packages (containing e.g. custom formatter classes)
     # passed on the command line
@@ -701,10 +718,6 @@ def main ():
 
     if global_options.process_cmd:
         includes = global_options.include_path
-        if global_options.lily_output_dir:
-            # This must be first, so lilypond prefers to read .ly
-            # files in the other lybookdb dir.
-            includes = [global_options.lily_output_dir] + includes
         global_options.process_cmd += ' '.join ([' -I %s' % ly.mkarg (p)
                                                  for p in includes])