From: Jean-Charles Malahieude Date: Sun, 31 Aug 2014 10:24:26 +0000 (+0200) Subject: Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation X-Git-Tag: release/2.19.14-1~40 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=324ff94afc62c7011b7377f24392f95391ed3b84;hp=59edf02a1acae41e21a080617aa7bd8673125762;p=lilypond.git Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation --- diff --git a/Documentation/contributor/issues.itexi b/Documentation/contributor/issues.itexi index 09b049f53c..091d72b82d 100644 --- a/Documentation/contributor/issues.itexi +++ b/Documentation/contributor/issues.itexi @@ -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 diff --git a/Documentation/de/essay/engraving.itely b/Documentation/de/essay/engraving.itely index fbc27ef8fe..cc8066e717 100644 --- a/Documentation/de/essay/engraving.itely +++ b/Documentation/de/essay/engraving.itely @@ -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 diff --git a/Documentation/de/notation/spacing.itely b/Documentation/de/notation/spacing.itely index 1b4d0ce673..35748c26f4 100644 --- a/Documentation/de/notation/spacing.itely +++ b/Documentation/de/notation/spacing.itely @@ -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 diff --git a/Documentation/es/essay/engraving.itely b/Documentation/es/essay/engraving.itely index 7f78637b78..f3f1ca40ed 100644 --- a/Documentation/es/essay/engraving.itely +++ b/Documentation/es/essay/engraving.itely @@ -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 diff --git a/Documentation/es/extending/programming-interface.itely b/Documentation/es/extending/programming-interface.itely index 726f316dca..a0a61b0cb9 100644 --- a/Documentation/es/extending/programming-interface.itely +++ b/Documentation/es/extending/programming-interface.itely @@ -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 diff --git a/Documentation/es/notation/spacing.itely b/Documentation/es/notation/spacing.itely index d93a82571f..52e79ddc8b 100644 --- a/Documentation/es/notation/spacing.itely +++ b/Documentation/es/notation/spacing.itely @@ -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) diff --git a/Documentation/essay/engraving.itely b/Documentation/essay/engraving.itely index 5136a331e0..7797a5468a 100644 --- a/Documentation/essay/engraving.itely +++ b/Documentation/essay/engraving.itely @@ -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 diff --git a/Documentation/extending/programming-interface.itely b/Documentation/extending/programming-interface.itely index be58003442..9da93f5615 100644 --- a/Documentation/extending/programming-interface.itely +++ b/Documentation/extending/programming-interface.itely @@ -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 diff --git a/Documentation/extending/scheme-tutorial.itely b/Documentation/extending/scheme-tutorial.itely index 7503306b1f..fc2eba1c6d 100644 --- a/Documentation/extending/scheme-tutorial.itely +++ b/Documentation/extending/scheme-tutorial.itely @@ -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: diff --git a/Documentation/fr/essay/engraving.itely b/Documentation/fr/essay/engraving.itely index 430e225240..1f41b047b0 100644 --- a/Documentation/fr/essay/engraving.itely +++ b/Documentation/fr/essay/engraving.itely @@ -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 diff --git a/Documentation/fr/extending/programming-interface.itely b/Documentation/fr/extending/programming-interface.itely index a1c0433794..ca6b33a505 100644 --- a/Documentation/fr/extending/programming-interface.itely +++ b/Documentation/fr/extending/programming-interface.itely @@ -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 diff --git a/Documentation/fr/notation/editorial.itely b/Documentation/fr/notation/editorial.itely index ac33088e47..cfb7aeb577 100644 --- a/Documentation/fr/notation/editorial.itely +++ b/Documentation/fr/notation/editorial.itely @@ -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 diff --git a/Documentation/fr/notation/spacing.itely b/Documentation/fr/notation/spacing.itely index 548e70867d..d0877e0087 100644 --- a/Documentation/fr/notation/spacing.itely +++ b/Documentation/fr/notation/spacing.itely @@ -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) diff --git a/Documentation/ja/notation/spacing.itely b/Documentation/ja/notation/spacing.itely index 9c16677ce7..82234a683a 100644 --- a/Documentation/ja/notation/spacing.itely +++ b/Documentation/ja/notation/spacing.itely @@ -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 diff --git a/Documentation/ly-examples/cary-layout.ily b/Documentation/ly-examples/cary-layout.ily index c002e111d0..66c6a7fbd3 100644 --- a/Documentation/ly-examples/cary-layout.ily +++ b/Documentation/ly-examples/cary-layout.ily @@ -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) diff --git a/Documentation/notation/changing-defaults.itely b/Documentation/notation/changing-defaults.itely index 70ffece67e..c38727bc85 100644 --- a/Documentation/notation/changing-defaults.itely +++ b/Documentation/notation/changing-defaults.itely @@ -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 diff --git a/Documentation/notation/chords.itely b/Documentation/notation/chords.itely index 8ba8009edd..5ae834f3b7 100644 --- a/Documentation/notation/chords.itely +++ b/Documentation/notation/chords.itely @@ -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' { 2 1 \chordmode { diff --git a/Documentation/notation/editorial.itely b/Documentation/notation/editorial.itely index fe624548cc..c121cf7bb3 100644 --- a/Documentation/notation/editorial.itely +++ b/Documentation/notation/editorial.itely @@ -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 diff --git a/Documentation/notation/notation-appendices.itely b/Documentation/notation/notation-appendices.itely index 91d7d81998..ae2e671b5b 100644 --- a/Documentation/notation/notation-appendices.itely +++ b/Documentation/notation/notation-appendices.itely @@ -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 diff --git a/Documentation/notation/spacing.itely b/Documentation/notation/spacing.itely index b4b3d7a80b..e90d71a45f 100644 --- a/Documentation/notation/spacing.itely +++ b/Documentation/notation/spacing.itely @@ -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) diff --git a/Documentation/notation/vocal.itely b/Documentation/notation/vocal.itely index 187e10566f..912378ab08 100644 --- a/Documentation/notation/vocal.itely +++ b/Documentation/notation/vocal.itely @@ -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) diff --git a/Documentation/snippets/displaying-grob-ancestry.ly b/Documentation/snippets/displaying-grob-ancestry.ly index 7a75bb1a33..ba68c27a01 100644 --- a/Documentation/snippets/displaying-grob-ancestry.ly +++ b/Documentation/snippets/displaying-grob-ancestry.ly @@ -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 index 0000000000..2f8919c2d9 --- /dev/null +++ b/Documentation/snippets/new/displaying-grob-ancestry.ly @@ -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 + 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 index 0000000000..efc99f22d0 --- /dev/null +++ b/Documentation/snippets/new/vocal-ensemble-template-with-automatic-piano-reduction.ly @@ -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 index 0000000000..3832db63d1 --- /dev/null +++ b/Documentation/snippets/new/vocal-ensemble-template.ly @@ -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 + >> +} diff --git a/Documentation/snippets/vocal-ensemble-template-with-automatic-piano-reduction.ly b/Documentation/snippets/vocal-ensemble-template-with-automatic-piano-reduction.ly index 8eba692deb..747e1ae8dc 100644 --- a/Documentation/snippets/vocal-ensemble-template-with-automatic-piano-reduction.ly +++ b/Documentation/snippets/vocal-ensemble-template-with-automatic-piano-reduction.ly @@ -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 = { diff --git a/Documentation/snippets/vocal-ensemble-template.ly b/Documentation/snippets/vocal-ensemble-template.ly index e78416a106..16f28d9e31 100644 --- a/Documentation/snippets/vocal-ensemble-template.ly +++ b/Documentation/snippets/vocal-ensemble-template.ly @@ -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 = { diff --git a/Documentation/web/news-front.itexi b/Documentation/web/news-front.itexi index 4b6367f033..9c0ec4b35d 100644 --- a/Documentation/web/news-front.itexi +++ b/Documentation/web/news-front.itexi @@ -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 diff --git a/Documentation/web/news.itexi b/Documentation/web/news.itexi index 8f1d4e349c..ddb0349987 100644 --- a/Documentation/web/news.itexi +++ b/Documentation/web/news.itexi @@ -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 a8d8464e1f..db178adabd 100644 --- 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 diff --git a/input/regression/accidental-unbroken-tie-spacing.ly b/input/regression/accidental-unbroken-tie-spacing.ly index 7f22cdf0ba..fc3e78c6e4 100644 --- a/input/regression/accidental-unbroken-tie-spacing.ly +++ b/input/regression/accidental-unbroken-tie-spacing.ly @@ -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 8 ~ | - 8 + 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 } diff --git a/input/regression/add-stem-support.ly b/input/regression/add-stem-support.ly index ab22af643b..db542afb84 100644 --- a/input/regression/add-stem-support.ly +++ b/input/regression/add-stem-support.ly @@ -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 diff --git a/input/regression/baerenreiter-sarabande.ly b/input/regression/baerenreiter-sarabande.ly index 892359dfc2..f7814f4f3b 100644 --- a/input/regression/baerenreiter-sarabande.ly +++ b/input/regression/baerenreiter-sarabande.ly @@ -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 diff --git a/input/regression/clef-transposition-placement.ly b/input/regression/clef-transposition-placement.ly index 119e00a903..4598cf4f34 100644 --- a/input/regression/clef-transposition-placement.ly +++ b/input/regression/clef-transposition-placement.ly @@ -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 index 0000000000..64c8439afe --- /dev/null +++ b/input/regression/divisi-staves.ly @@ -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 2 + \boring \repeat unfold 98 d4 + \bar "|." +} + +violII=\relative g { + \boring \repeat unfold 100 g4 + \tricky 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 + } +} diff --git a/input/regression/dynamics-empty.ly b/input/regression/dynamics-empty.ly index 4b06d96fae..cdf907a490 100644 --- a/input/regression/dynamics-empty.ly +++ b/input/regression/dynamics-empty.ly @@ -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)) } } diff --git a/input/regression/ferneyhough-hairpins.ly b/input/regression/ferneyhough-hairpins.ly index 000d9da403..a49892c140 100644 --- a/input/regression/ferneyhough-hairpins.ly +++ b/input/regression/ferneyhough-hairpins.ly @@ -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\! diff --git a/input/regression/lilypond-book/GNUmakefile b/input/regression/lilypond-book/GNUmakefile index 935f068db7..ebe18303f5 100644 --- a/input/regression/lilypond-book/GNUmakefile +++ b/input/regression/lilypond-book/GNUmakefile @@ -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))) > $@ diff --git a/input/regression/lilypond-book/include.ly b/input/regression/lilypond-book/include.ly index 1e790908a6..2444ac8536 100644 --- a/input/regression/lilypond-book/include.ly +++ b/input/regression/lilypond-book/include.ly @@ -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 index 0000000000..e21f02cd44 --- /dev/null +++ b/input/regression/lilypond-book/melody.ly @@ -0,0 +1,3 @@ +\version "2.16.0" +\include "include/myvar.ily" +melody = \relative c'' { \key c \minor c4 es g2 \myVar } diff --git a/input/regression/lilypond-book/tex-include-file.lytex b/input/regression/lilypond-book/tex-include-file.lytex index bcad93601b..f5005ed71c 100644 --- a/input/regression/lilypond-book/tex-include-file.lytex +++ b/input/regression/lilypond-book/tex-include-file.lytex @@ -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} diff --git a/input/regression/lilypond-book/tex-include-options.lytex b/input/regression/lilypond-book/tex-include-options.lytex index 251fa087d8..bcc2a6ef4a 100644 --- a/input/regression/lilypond-book/tex-include-options.lytex +++ b/input/regression/lilypond-book/tex-include-options.lytex @@ -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} diff --git a/input/regression/lilypond-book/texinfo-include-file.tely b/input/regression/lilypond-book/texinfo-include-file.tely index 610eb23a3e..d32e767c17 100644 --- a/input/regression/lilypond-book/texinfo-include-file.tely +++ b/input/regression/lilypond-book/texinfo-include-file.tely @@ -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 index 0000000000..0592dc4e40 --- /dev/null +++ b/input/regression/lyric-combine-nullvoice.ly @@ -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 } +>> } diff --git a/input/regression/markup-cyclic-reference.ly b/input/regression/markup-cyclic-reference.ly index 9ca834b542..82bfe0641d 100644 --- a/input/regression/markup-cyclic-reference.ly +++ b/input/regression/markup-cyclic-reference.ly @@ -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 diff --git a/input/regression/morgenlied.ly b/input/regression/morgenlied.ly index c335683198..550489f92d 100644 --- a/input/regression/morgenlied.ly +++ b/input/regression/morgenlied.ly @@ -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 } diff --git a/input/regression/mozart-hrn-3.ly b/input/regression/mozart-hrn-3.ly index 3908f6bc60..ae58603ecf 100644 --- a/input/regression/mozart-hrn-3.ly +++ b/input/regression/mozart-hrn-3.ly @@ -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 { diff --git a/input/regression/note-names-context.ly b/input/regression/note-names-context.ly index 3041797736..52e4c4e914 100644 --- a/input/regression/note-names-context.ly +++ b/input/regression/note-names-context.ly @@ -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 { diff --git a/input/regression/override-nest.ly b/input/regression/override-nest.ly index 08a45d36d6..117e6c2447 100644 --- a/input/regression/override-nest.ly +++ b/input/regression/override-nest.ly @@ -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] } diff --git a/input/regression/page-breaking-min-distance.ly b/input/regression/page-breaking-min-distance.ly index db23c7f274..71c2dd91da 100644 --- a/input/regression/page-breaking-min-distance.ly +++ b/input/regression/page-breaking-min-distance.ly @@ -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 } diff --git a/input/regression/page-spacing.ly b/input/regression/page-spacing.ly index f62e472255..2e150e61b6 100644 --- a/input/regression/page-spacing.ly +++ b/input/regression/page-spacing.ly @@ -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 diff --git a/input/regression/page-top-space.ly b/input/regression/page-top-space.ly index 80494988c3..2e73a60a4b 100644 --- a/input/regression/page-top-space.ly +++ b/input/regression/page-top-space.ly @@ -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) } } diff --git a/input/regression/paper-nested-override.ly b/input/regression/paper-nested-override.ly index 5af168c697..3c16f09ab3 100644 --- a/input/regression/paper-nested-override.ly +++ b/input/regression/paper-nested-override.ly @@ -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 } diff --git a/input/regression/paper-nested-override2.ly b/input/regression/paper-nested-override2.ly index ce359b7403..3c1a6c8838 100644 --- a/input/regression/paper-nested-override2.ly +++ b/input/regression/paper-nested-override2.ly @@ -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 } diff --git a/input/regression/scheme-text-spanner.ly b/input/regression/scheme-text-spanner.ly index fc60c5b339..8442f60a96 100644 --- a/input/regression/scheme-text-spanner.ly +++ b/input/regression/scheme-text-spanner.ly @@ -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)) diff --git a/input/regression/skyline-point-extent.ly b/input/regression/skyline-point-extent.ly index ceb27b2490..9d13cbd213 100644 --- a/input/regression/skyline-point-extent.ly +++ b/input/regression/skyline-point-extent.ly @@ -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-> } diff --git a/input/regression/typography-demo.ly b/input/regression/typography-demo.ly index 45a9945dfd..8f51e21475 100644 --- a/input/regression/typography-demo.ly +++ b/input/regression/typography-demo.ly @@ -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 } diff --git a/lily/accidental.cc b/lily/accidental.cc index 62f5235b1c..ee0b6e88b9 100644 --- a/lily/accidental.cc +++ b/lily/accidental.cc @@ -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 (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); } diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index cc756b7e21..c48fe6fe33 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -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; 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 index 0000000000..c56b935a16 --- /dev/null +++ b/lily/clef-modifier.cc @@ -0,0 +1,67 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2014--2014 Janek Warchoł + + 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 . +*/ + +#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 " + ); + diff --git a/lily/context-property.cc b/lily/context-property.cc index b578321a93..5f2c8c70e5 100644 --- a/lily/context-property.cc +++ b/lily/context-property.cc @@ -20,10 +20,12 @@ #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 ("#", 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_, ¤t_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, ¤t_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, ¤t_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, ¤t_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 = © - 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_; } diff --git a/lily/context-scheme.cc b/lily/context-scheme.cc index aaa5b529b3..c3822100af 100644 --- a/lily/context-scheme.cc +++ b/lily/context-scheme.cc @@ -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", diff --git a/lily/engraver-group.cc b/lily/engraver-group.cc index 4a897c6092..a9048ccb9c 100644 --- a/lily/engraver-group.cc +++ b/lily/engraver-group.cc @@ -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 diff --git a/lily/engraver.cc b/lily/engraver.cc index 74a6554e3a..76117a66e8 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -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; diff --git a/lily/hara-kiri-group-spanner.cc b/lily/hara-kiri-group-spanner.cc index b7c55b5045..8afef8f5ea 100644 --- a/lily/hara-kiri-group-spanner.cc +++ b/lily/hara-kiri-group-spanner.cc @@ -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 " ); - diff --git a/lily/include/accidental-interface.hh b/lily/include/accidental-interface.hh index 6b2c8709fb..cbb61b772a 100644 --- a/lily/include/accidental-interface.hh +++ b/lily/include/accidental-interface.hh @@ -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); diff --git a/lily/include/context.hh b/lily/include/context.hh index 0595bf8513..c8bea9fad9 100644 --- a/lily/include/context.hh +++ b/lily/include/context.hh @@ -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 index 0000000000..37569442c6 --- /dev/null +++ b/lily/include/grob-properties.hh @@ -0,0 +1,59 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2014 David Kastrup + + 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 . +*/ + +// 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 diff --git a/lily/include/lily-guile-macros.hh b/lily/include/lily-guile-macros.hh index acc817f878..1bdf9aa7bc 100644 --- a/lily/include/lily-guile-macros.hh +++ b/lily/include/lily-guile-macros.hh @@ -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; \ }) diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index 83a71ab672..3dd0825b27 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -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) (); diff --git a/lily/include/note-column.hh b/lily/include/note-column.hh index 9fdabd2962..6f688c09ff 100644 --- a/lily/include/note-column.hh +++ b/lily/include/note-column.hh @@ -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 *); diff --git a/lily/item.cc b/lily/item.cc index f007670e7a..bcde47616d 100644 --- a/lily/item.cc +++ b/lily/item.cc @@ -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)); diff --git a/lily/keep-alive-together-engraver.cc b/lily/keep-alive-together-engraver.cc index 78a10050cd..c65ff45531 100644 --- a/lily/keep-alive-together-engraver.cc +++ b/lily/keep-alive-together-engraver.cc @@ -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); } } diff --git a/lily/lexer.ll b/lily/lexer.ll index 8b0859630e..0c364c1bb2 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -422,7 +422,7 @@ BOM_UTF8 \357\273\277 return token; } -{ +{ \<\< { yylval = SCM_UNSPECIFIED; return DOUBLE_ANGLE_OPEN; @@ -433,7 +433,7 @@ BOM_UTF8 \357\273\277 } } -{ +{ \< { yylval = SCM_UNSPECIFIED; return ANGLE_OPEN; diff --git a/lily/nested-property.cc b/lily/nested-property.cc index 9c3cc73387..4c79918f09 100644 --- a/lily/nested-property.cc +++ b/lily/nested-property.cc @@ -1,112 +1,261 @@ #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 diff --git a/lily/note-column.cc b/lily/note-column.cc index c5d06cfb68..760e37dc19 100644 --- a/lily/note-column.cc +++ b/lily/note-column.cc @@ -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); } /* diff --git a/lily/parser.yy b/lily/parser.yy index c8365abf13..4a805f1970 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -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", @$); diff --git a/lily/rest-collision-engraver.cc b/lily/rest-collision-engraver.cc index e4a39d4fff..620c606349 100644 --- a/lily/rest-collision-engraver.cc +++ b/lily/rest-collision-engraver.cc @@ -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 (column)->get_column (); diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index b361d03fc1..54f34575d2 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -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)); diff --git a/lily/self-alignment-interface.cc b/lily/self-alignment-interface.cc index 9c73b6c7d8..6b6662641f 100644 --- a/lily/self-alignment-interface.cc +++ b/lily/self-alignment-interface.cc @@ -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); } diff --git a/lily/span-bar-stub-engraver.cc b/lily/span-bar-stub-engraver.cc index d02ff4ae54..9cf52dc98f 100644 --- a/lily/span-bar-stub-engraver.cc +++ b/lily/span-bar-stub-engraver.cc @@ -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]; diff --git a/lily/text-interface.cc b/lily/text-interface.cc index 0dc4f36360..f45d06ac3b 100644 --- a/lily/text-interface.cc +++ b/lily/text-interface.cc @@ -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 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 diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index d4755f1b9a..8a016bde21 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -213,7 +213,7 @@ Tie_formatting_problem::set_column_chord_outline (vector 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) { diff --git a/ly/Welcome-to-LilyPond-MacOS.ly b/ly/Welcome-to-LilyPond-MacOS.ly index 6e784a1a65..4ff7f6f3e0 100644 --- a/ly/Welcome-to-LilyPond-MacOS.ly +++ b/ly/Welcome-to-LilyPond-MacOS.ly @@ -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" diff --git a/ly/Welcome_to_LilyPond.ly b/ly/Welcome_to_LilyPond.ly index 912a4b1a95..641c7b8512 100644 --- a/ly/Welcome_to_LilyPond.ly +++ b/ly/Welcome_to_LilyPond.ly @@ -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" diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index ec34cd64c3..4c61334d40 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -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 { diff --git a/ly/event-listener.ly b/ly/event-listener.ly index b7b8ca086a..706b160755 100644 --- a/ly/event-listener.ly +++ b/ly/event-listener.ly @@ -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 diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index fea1c9b888..477c9c6538 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -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 diff --git a/ly/performer-init.ly b/ly/performer-init.ly index ecc97aedb7..297a40d2f5 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -26,7 +26,6 @@ \name Staff \accepts Voice \accepts CueVoice - \accepts NullVoice \defaultchild Voice \consists "Staff_performer" @@ -188,9 +187,6 @@ \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" @@ -225,6 +221,7 @@ \accepts TabStaff \accepts StaffGroup \accepts Devnull + \accepts NullVoice \accepts ChoirStaff \accepts RhythmicStaff \accepts ChordNames diff --git a/po/lilypond.pot b/po/lilypond.pot index 8ee48b7821..790b11cdad 100644 --- a/po/lilypond.pot +++ b/po/lilypond.pot @@ -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 \n" "Language-Team: LANGUAGE \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 "" diff --git a/python/book_snippets.py b/python/book_snippets.py index 69fdc4fa68..4bc4252e79 100644 --- a/python/book_snippets.py +++ b/python/book_snippets.py @@ -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()) diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index 2c3290a4c8..e07006e350 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -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 diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 35f0074a88..a81eed5009 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -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.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 53401d3a42..4139ff13da 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -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) @@ -573,11 +574,14 @@ . ( (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) @@ -1177,12 +1181,13 @@ (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 @@ -1898,6 +1903,7 @@ (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. @@ -1913,6 +1919,7 @@ (interfaces . (font-interface outside-staff-interface script-interface + self-alignment-interface side-position-interface)))))) (ScriptColumn @@ -1954,10 +1961,11 @@ (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 @@ -2205,10 +2213,11 @@ . ( (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 @@ -2618,11 +2627,12 @@ (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 @@ -2813,7 +2823,7 @@ (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) diff --git a/scm/lily.scm b/scm/lily.scm index 2f589d01ff..e4126ef3ff 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -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) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 2df06bd528..739c581a14 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -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))) diff --git a/scripts/auxiliar/update-with-convert-ly.sh b/scripts/auxiliar/update-with-convert-ly.sh index 7f40b63fb8..bb51d83e41 100755 --- a/scripts/auxiliar/update-with-convert-ly.sh +++ b/scripts/auxiliar/update-with-convert-ly.sh @@ -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 diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index 9cdd14742b..f38fb4f7e3 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -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])