@end ignore
+@item
+When @code{\relative} is used without an explicit reference pitch,
+the reference pitch now is the middle of the first octave, making
+the first entered pitch indistinguishable from absolute pitch.
+Previously, omitting the reference pitch would have lead to a
+default of @code{c'}. Since that choice was somewhat arbitrary,
+recommended usage was to always specify the reference pitch.
+
+@item
+A new command @code{\single} can be used for converting a property
+override into a tweak to be applied on a single music expression:
+
+@lilypond[quote,verbatim,relative=2]
+<a \single\voiceTwoStyle e' a>1
+@end lilypond
+
+@item
+Two ways of letting graphical objects not appear in the output are
+overriding its @code{transparent} property with @code{#t}
+(retaining the original spacing) or overriding its @code{stencil}
+property with @code{#f} (not using any space at all). Those two
+operations now have the shorthands @code{\hide} and @code{\omit},
+respectively. They can either be given a music expression to
+tweak, or the name of a graphical object for which an override
+should be created (for specifying both, use @code{\single} on the
+override form):
+
+@lilypond[quote,verbatim]
+\new Staff \with { \omit Clef }
+\relative c'' <a e' \hide a>1
+@end lilypond
+
+@item
+A new command @code{\temporary} can be applied to overrides in
+order to not have them replace previous property settings. If a
+@code{\revert} is applied to the same property subsequently, the
+previous setting reappears:
+
+@lilypond[quote,verbatim,relative=2]
+\override NoteHead.color = #red c4
+\override NoteHead.color = #green d
+\revert NoteHead.color e2
+\override NoteHead.color = #red c4
+\temporary\override NoteHead.color = #green d
+\revert NoteHead.color e
+\revert NoteHead.color c
+@end lilypond
+
+This is mainly useful for writing music functions that need to
+have some property changed just for the duration of the function.
+
+@item
+@code{\tag}, @code{\removeWithTag}, and @code{\keepWithTag} can
+now accept a list of symbols rather than just a single symbol for
+marking, removing, and keeping music with any of multiple tags.
+This is particularly important for @code{\keepWithTag} since one
+cannot achieve the same effect by using multiple consecutive
+@code{\keepWithTag} commands.
+
@item
The @samp{-d old-relative} option has been removed. Not actually
accessible from the command line any more, its remaining use was
* Precompiled regression tests::
* Compiling regression tests::
* Regtest comparison::
+* Pixel-based regtest comparison::
* Finding the cause of a regression::
* Memory and coverage tests::
* MusicXML tests::
@code{make test-clean}, @code{make} and @code{make check} it without doing
@code{make test-baseline} again.}
+@node Pixel-based regtest comparison
+@section Pixel-based regtest comparison
+
+As an alternative to the @code{make test} method for regtest checking (which
+relies upon @code{.signature} files created by a LilyPond run and which describe
+the placing of grobs) there is a script which compares the output of two
+LilyPond versions pixel-by-pixel. To use this, start by checking out the
+version of LilyPond you want to use as a baseline, and run @code{make}. Then,
+do the following:
+
+@example
+cd $LILYPOND_GIT/scripts/auxiliar/
+./make-regtest-pngs.sh -j9 -o
+@end example
+
+The @code{-j9} option tells the script to use 9 CPUs to create the
+images - change this to your own CPU count+1. @code{-o} means this is the "old"
+version. This will create images of all the regtests in
+
+@example
+$LILYPOND_BUILD_DIR/out-png-check/old-regtest-results/
+@end example
+
+Now checkout the version you want to compare with the baseline. Run
+@code{make} again to recreate the LilyPond binary. Then, do the following:
+
+@example
+cd $LILYPOND_GIT/scripts/auxiliar/
+./make-regtest-pngs.sh -j9 -n
+@end example
+
+The @code{-n} option tells the script to make a "new" version of the
+images. They are created in
+
+@example
+$LILYPOND_BUILD_DIR/out-png-check/new-regtest-results/
+@end example
+
+Once the new images have been created, the script compares the old images with
+the new ones pixel-by-pixel and prints a list of the different images to the
+terminal, together with a count of how many differences were found. The
+results of the checks are in
+
+@example
+$LILYPOND_BUILD_DIR/out-png-check/regtest-diffs/
+@end example
+
+To check for differences, browse that directory with an image
+viewer. Differences are shown in red. Be aware that some images with complex
+fonts or spacing annotations always display a few minor differences. These can
+safely be ignored.
+
@node Finding the cause of a regression
@section Finding the cause of a regression
export LILYPOND_WEB_MEDIA_GIT=$HOME/dir/of/lilypond-extra/
@end example
+Be aware that @code{lilypond-extra} is the definitive source for some binary
+files - in particular PDF versions of papers concerning LilyPond. To add
+further PDFs of this sort, all that is necessary is to add the PDF to
+@code{lilypond-extra} and then add a reference to it in the documentation. The
+file will then be copied to the website when @code{make website} is run.
+
+However, pictures that are also used in the documentation build are mastered in
+the main git repository. If any of these is changed, it should be updated in
+git, and then the updates copied to @code{lilypond-extra}.
+
@node Grand Unified Builder (GUB)
@unnumberedsubsubsec Grand Unified Builder (GUB)
\remove "Phrasing_slur_engraver"
\remove "Slur_engraver"
\remove "Script_engraver"
+ \remove "New_fingering_engraver"
\remove "Beam_engraver"
\remove "Auto_beam_engraver"
}
\remove "Phrasing_slur_engraver"
\remove "Slur_engraver"
\remove "Script_engraver"
+ \remove "New_fingering_engraver"
\remove "Beam_engraver"
\remove "Auto_beam_engraver"
}
\remove "Phrasing_slur_engraver"
\remove "Slur_engraver"
\remove "Script_engraver"
+ \remove "New_fingering_engraver"
\remove "Beam_engraver"
\remove "Auto_beam_engraver"
}
\remove "Phrasing_slur_engraver"
\remove "Slur_engraver"
\remove "Script_engraver"
+ \remove "New_fingering_engraver"
\remove "Beam_engraver"
\remove "Auto_beam_engraver"
}
Marc Hohl,
Keith OHara,
Benkő Pál,
+Anders Pilegaard,
Julien Rioux
@c no comma for last entry
\score {
<<
- \context ChordNames {
+ \new ChordNames {
\chordsline
}
- \context FretBoards {
+ \new FretBoards {
\chordsline
}
- \context Staff {
+ \new Staff {
\chordsline
}
>>
}
<<
- \context ChordNames {
+ \new ChordNames {
\chordsline
}
- \context FretBoards {
+ \new FretBoards {
\set Staff.stringTunings = #mandolin-tuning
\chordsline
}
- \context Staff {
+ \new Staff {
\chordsline
}
>>
}
<<
- \context ChordNames {
+ \new ChordNames {
\chordsline
}
- \context FretBoards {
+ \new FretBoards {
\set Staff.stringTunings = #ukulele-tuning
\chordsline
}
- \context Staff {
+ \new Staff {
\chordsline
}
>>
little) space there is at the beginning of a line, but indenting
LilyPond code like this makes it much easier for humans to read.
-@warning{each note is relative to the previous note in
-the input, not relative to the @code{c''} in the initial
+@warning{each note is relative to the previous note in the input,
+only the first is relative to the @code{c''} in the initial
@code{@bs{}relative} command.}
@cindex absolute note names
So far we have always used @code{\relative} to define pitches.
-This is the easiest way to enter most music, but another way of
-defining pitches exists: absolute mode.
+This is usually the fastest way to enter most music. Without
+@code{\relative}, pitches are interpreted in absolute mode.
-If you omit the @code{\relative}, LilyPond treats all pitches as
-absolute values. A @code{c'} will always mean middle C, a
-@code{b} will always mean the note one step below middle C, and a
-@code{g,} will always mean the note on the bottom staff of the
-bass clef.
+In this mode, LilyPond treats all pitches as absolute values. A
+@code{c'} will always mean middle C, a @code{b} will always mean
+the note one step below middle C, and a @code{g,} will always mean
+the note on the bottom staff of the bass clef.
@lilypond[verbatim,quote]
{
However, absolute mode is useful for music which has large
intervals, and is extremely useful for computer-generated LilyPond
-files.
+files. When cutting and pasting melody fragments, absolute mode
+preserves the original octave.
+Sometimes music is arranged in more complex ways. If you are
+using @code{\relative} inside of @code{\relative}, the outer and
+inner relative sections are independent:
+@lilypond[verbatim,quote]
+\relative c { c'4 \relative c'' { f g } c }
+@end lilypond
+
+@funindex \absolute
+If you are using absolute music inside of relative, you'll need to
+mark the absolute music explicitly with @code{\absolute} to stop
+it from becoming part of the relative music:
+
+@lilypond[verbatim,quote]
+\relative c { c'4 \absolute { f'' g'' } c }
+@end lilypond
@node After the tutorial
@subsection After the tutorial
\header @{ @}
\score @{
- @var{...compound music expression...} % all the music goes here!
+ @var{ @dots{} compound music expression @dots{} } % all the music goes here!
\layout @{ @}
\midi @{ @}
@}
@example
@{
\new StaffGroup <<
- @var{...insert the whole score of a Wagner opera in here...}
+ @var{ @dots{} insert the whole score of a Wagner opera in here @dots{} }
>>
@}
@end example
@noindent
-Since everything is inside @code{@{ ... @}}, it counts
+Since everything is inside @code{@{ @dots{} @}}, it counts
as one music expression.
As we saw previously, the @code{\score} block can contain other
to cultivate so that you can see at a glance what each stave is
for.
-Remember that we use @code{<< ... >>} instead of @code{@{ ... @}} to
+Remember that we use @code{<< @dots{} >>} instead of @code{@{ @dots{} @}} to
show simultaneous music. This causes the vocal part and piano part
-to appear one above the other in the score. The @code{<< ... >>}
+to appear one above the other in the score. The @code{<< @dots{} >>}
construct would not be necessary for the Singer staff in the example
above if it were going to contain only one sequential music
-expression, but @code{<< ... >>} rather than braces is necessary if
+expression, but @code{<< @dots{} >>} rather than braces is necessary if
the music in the Staff is to contain two or more simultaneous
expressions, e.g. two simultaneous Voices, or a Voice with lyrics.
We're going to have a voice with lyrics, so angle brackets are
@multitable @columnfractions .3 .7
@headitem Bracket Type
@tab Function
-@item @code{@{ .. @}}
+@item @code{@{ @dots{} @}}
@tab Encloses a sequential segment of music
-@item @code{< .. >}
+@item @code{< @dots{} >}
@tab Encloses the notes of a chord
-@item @code{<< .. >>}
+@item @code{<< @dots{} >>}
@tab Encloses simultaneous music expressions
-@item @code{( .. )}
+@item @code{( @dots{} )}
@tab Marks the start and end of a slur
-@item @code{\( .. \)}
+@item @code{\( @dots{} \)}
@tab Marks the start and end of a phrasing slur
-@item @code{[ .. ]}
+@item @code{[ @dots{} ]}
@tab Marks the start and end of a manual beam
@end multitable
To these we should add other constructs which generate lines
between or across notes: ties (marked by a tilde, @code{~}),
-tuplets written as @code{\times x/y @{..@}}, and grace notes
-written as @code{\grace@{..@}}.
+tuplets written as @code{\tuplet x/y @{ @dots{} @}}, and grace notes
+written as @code{\grace @{ @dots{} @}}.
Outside LilyPond, the conventional use of brackets requires the
-different types to be properly nested, like this, @code{<< [ @{ ( .. )
+different types to be properly nested, like this, @code{<< [ @{ ( @dots{} )
@} ] >>}, with the closing brackets being encountered in exactly the
opposite order to the opening brackets. This @strong{is} a
requirement for the three types of bracket described by the word
@end lilypond
This can be expressed using just the single angle bracket chord
-symbols, @code{< ... >}, and for this just a single voice is
+symbols, @code{< @dots{} >}, and for this just a single voice is
needed. But suppose the F-sharp were actually an eighth-note
followed by an eighth-note G, a passing note on the way to the A?
Now we have two notes which start at the same time but have
@funindex \\
The easiest way to enter fragments with more than one voice on a
-staff is to enter each voice as a sequence (with @code{@{...@}}),
-and combine them simultaneously with angle brackets, @code{<<...>>}.
+staff is to enter each voice as a sequence (with @code{@{ @dots{} @}}),
+and combine them simultaneously with angle brackets, @code{<< @dots{} >>}.
The fragments must also be separated with double backward slashes,
@code{\\}, to place them in separate voices. Without these, the
notes would be entered into a single voice, which would usually
@end lilypond
These voices are all separate from the main voice that contains
-the notes just outside the @code{<< .. >>} construct. Let's call
+the notes just outside the @code{<< @dots{} >>} construct. Let's call
this the @emph{simultaneous construct}. Slurs and ties may only
connect notes within the same voice, so slurs and ties cannot go
into or out of a simultaneous construct. Conversely,
command at the start of each voice:
@example
-\relative c' @{ noteA ... @}
+\relative c' @{ noteA @dots{} @}
<<
- \relative c'' @{ < noteB noteC > ... @}
+ \relative c'' @{ < noteB noteC > @dots{} @}
\\
- \relative g' @{ noteD ... @}
+ \relative g' @{ noteD @dots{} @}
>>
-\relative c' @{ noteE ... @}
+\relative c' @{ noteE @dots{} @}
@end example
Let us finally analyze the voices in a more complex piece of music.
context is created. Sometimes this is a clearer way of setting a
property value if it is to remain fixed for the duration of
the context. When a context is created with a @code{\new}
-command it may be followed immediately by a @code{\with @{ .. @}}
+command it may be followed immediately by a @code{\with @{ @dots{} @}}
block in which the default property values are set. For example,
if we wish to suppress the printing of extra naturals for the
duration of a staff we would write:
@end example
It is not necessary to use the simultaneous construct
-@code{<< .. >>} for the manual two staff and the pedal organ staff,
+@code{<< @dots{} >>} for the manual two staff and the pedal organ staff,
since they contain only one music expression, but it does no harm,
and always using angle brackets after @code{\new Staff} is a good
habit to cultivate in case there are multiple voices. The opposite
is true for Voices: these should habitually be followed by braces
-@code{@{ .. @}} in case your music is coded in several variables
+@code{@{ @dots{} @}} in case your music is coded in several variables
which need to run consecutively.
Let's add this structure to the score block, and adjust the indenting.
second voice.
@node The force-hshift property
-@unnumberedsubsubsec The @code{force-hshift property}
+@unnumberedsubsubsec The @code{force-hshift} property
We can now see how to apply the final corrections to the Chopin
example introduced at the end of @ref{I'm hearing Voices}, which
global = {
\key c \minor
\time 4/4
+ \tempo Largo
\accidentalStyle default
}
halsup = {
- \stemUp
- \tieUp
+ \voiceOne
}
halsdown = {
- \stemDown
- \tieDown
+ \voiceTwo
}
staffup = {
\global
\halsup
\repeat volta 2 {
- g4^\markup { \hspace #-4 \large "Largo" } g f es
+ g4 g f es
d2 c\fermata
g'4 g a h
c2 h\fermata
}
text = \lyricmode {
- My eyes are dim, I can -- not see,
- I have not brought my specs with me!
+ My eyes are __ dim, I can -- not see,
+ I have not __ brought my specs with me!
}
\score {
\version "2.17.6"
-#(set-global-staff-size 22.45)
-
#(define (glissando::calc-extra-dy grob)
(let* ((original (ly:grob-original grob))
(left-bound (ly:spanner-bound original LEFT))
(- (ly:pitch-alteration right-pitch) (ly:pitch-alteration left-pitch))
0 )))
-\paper {
- indent= #0
- line-width= #180
-}
-
upper= \relative c' {
\time 4/4
\key e \major
}
\score {
- \new StaffGroup <<
+ \new StaffGroup \with {instrumentName = #"Guitar" } <<
\new Staff = "guitar" <<
\context Voice = "upper guitar" {
\clef "G_8" \voiceOne
\include "example-header.ily"
#(ly:set-option 'point-and-click #f)
+#(set-global-staff-size 24)
global = {
\time 4/4
\numericTimeSignature
\key c \major
- #(set-global-staff-size 24)
}
cf = \relative c {
@section alla breve
ES: alla breve,
-I: ?,
+I: alla breve,
F: alla breve, à la brève,
D: Allabreve, alla breve
NL: ?,
@section Common Practice Period
ES: ?,
-I: ?,
+I: Periodo di pratica comune,
F: ?,
D: Kunstmusik,
NL: ?,
@section compound time
ES: compás compuesto, compás de amalgama (def. 2),
-I: ?,
+I: tempo misto,
F: temps composé,
D: zusammengesetzte Taktart,
NL: ?,
@section divisio
ES: división,
-I: ?,
+I: divisio,
F: ?,
D: Divisio,
NL: ?,
@section doit
ES: elevación [de tono],
-I: ?,
+I: portamento indeterminato verso l'alto/l'acuto,
F: saut,
D: Glissando zu unbestimmter Tonhöhe,
NL: ?,
@section double time signature
ES: compás polimétrico,
-I: ?,
+I: indicazione di tempo doppia/polimetrica,
F: ?,
D: zusammengesetzte Taktart,
NL: ?,
@section fall
ES: caÃda [de tono],
-I: ?,
+I: portamento indeterminato verso il basso/il grave,
F: chute,
D: Glissando zu unbestimmter Tonhöhe nach unten,
NL: ?,
@section feathered beam
ES: barra progresiva,
-I: ?,
+I: travatura convergente/divergente,
F: ligature en soufflet, lien de croches en soufflet,
D: gespreizter Balken,
NL: ?,
@section flageolet
ES: armónico,
-I: ?,
+I: armonico,
F: flageolet,
D: Flageolett,
NL: ?,
@section Frenched score
ES: partitura a la francesa,
-I: ?,
+I: partitura senza i righi vuoti,
F: ?,
D: Orchesterpartitur ohne leere Systeme,
NL: ?,
@section Frenched staff
ES: pentagrama a la francesa,
-I: ?,
+I: rigo temporaneo,
F: ?,
D: zeitweiliges Notensystem,
NL: ?,
@section hymn meter
ES: ?,
-I: ?,
+I: metrica dell'inno,
F: ?,
D: Silbenanzahl,
NL: ?,
@section incomplete dominant seventh chord
ES: ?,
-I: ?,
+I: accordo di settima dominante incompleto,
F: ?,
D: verkürzter Dominantseptakkord,
NL: ?,
@section ligature
ES: ligadura,
-I: ?,
+I: ligatura,
F: ligature,
DE: Ligatur,
NL: ?,
@section lyric tie
ES: ligadura de letra,
-I: ?,
+I: legatura del testo,
F: ligature de mots,
D: Textbindung,
NL: ?,
@c TODO: add languages
ES: signo de mensuración,
-I: ?,
+I: indicazione mensurale,
F: signe de mensuration,
D: Mensurzeichen,
NL: ?,
@c TODO: add definition.
ES: tonos vecinos,
-I: ?,
+I: nota di volta,
F: tons voisins,
D: ?,
NL: ?,
@section simple meter
ES: compás simple, compás de subdivisión binaria,
-I: ?,
+I: tempo semplice,
F: mesure binaire,
D: grader Takt,
NL: ?,
@lilypond[quote,ragged-right,verbatim]
\relative c'' {
- \[ g c a f d' \]
+ \[ g c, a' f d' \]
a g f
\[ e f a g \]
}
@lilypond[quote,ragged-right,verbatim]
\score {
<<
- \new MensuralVoice = "discantus" \relative c' {
+ \new MensuralVoice = "discantus" \relative c'' {
\override Score.BarNumber.transparent = ##t {
- c'1\melisma bes a g\melismaEnd
+ c1\melisma bes a g\melismaEnd
f\breve
\[ f1\melisma a c\breve d\melismaEnd \]
c\longa
\override NoteHead.ligature-flexa = ##t
\once \override NoteHead.flexa-width = #3.2
c\breve f e d \]
- \[ c\maxima d\longa \]
- \[ e1 a g\breve \]
+ \[ c'\maxima d\longa \]
+ \[ e1 a, g\breve \]
}
\layout {
\context {
\override NoteHead.ligature-flexa = ##t
\once \override NoteHead.flexa-width = #3.2
c\breve f e d \]
- \[ c\maxima d\longa \]
- \[ e1 a g\breve \]
+ \[ c'\maxima d\longa \]
+ \[ e1 a, g\breve \]
}
@end lilypond
@lilypond[staffsize=26,line-width=1.5\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum
\[ b \]
}
@lilypond[staffsize=26,line-width=1.5\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum
\[ \cavum b \]
}
@lilypond[staffsize=26,line-width=1.5\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum
\[ \linea b \]
}
@lilypond[staffsize=26,line-width=2.5\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum Auctum Ascendens
\[ \auctum \ascendens b \]
}
@lilypond[staffsize=26,line-width=2.5\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum Auctum Descendens
\[ \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.5\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum Inclinatum
\[ \inclinatum b \]
}
@lilypond[staffsize=26,line-width=2.5\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum Inclinatum Auctum
\[ \inclinatum \auctum b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Punctum Inclinatum Parvum
\[ \inclinatum \deminutum b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Virga
\[ \virga b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Clivis vel Flexa
\[ b \flexa g \]
}
@lilypond[staffsize=26,line-width=2.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Clivis Aucta Descendens
\[ b \flexa \auctum \descendens g \]
}
@lilypond[staffsize=26,line-width=2.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Clivis Aucta Ascendens
\[ b \flexa \auctum \ascendens g \]
}
@lilypond[staffsize=26,line-width=2.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Cephalicus
\[ b \flexa \deminutum g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Podatus vel Pes
\[ g \pes b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Pes Auctus Descendens
\[ g \pes \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Pes Auctus Ascendens
\[ g \pes \auctum \ascendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Epiphonus
\[ g \pes \deminutum b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Pes Initio Debilis
\[ \deminutum g \pes b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Pes Auctus Descendens Initio Debilis
\[ \deminutum g \pes \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Torculus
\[ a \pes b \flexa g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Torculus Auctus Descendens
\[ a \pes b \flexa \auctum \descendens g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Torculus Deminutus
\[ a \pes b \flexa \deminutum g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Torculus Initio Debilis
\[ \deminutum a \pes b \flexa g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Torculus Auctus Descendens Initio Debilis
\[ \deminutum a \pes b \flexa \auctum \descendens g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Torculus Deminutus Initio Debilis
\[ \deminutum a \pes b \flexa \deminutum g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Porrectus
\[ a \flexa g \pes b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Porrectus Auctus Descendens
\[ a \flexa g \pes \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Porrectus Deminutus
\[ a \flexa g \pes \deminutum b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Climacus
\[ \virga b \inclinatum a \inclinatum g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Climacus Auctus
\[ \virga b \inclinatum a \inclinatum \auctum g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Climacus Deminutus
\[ \virga b \inclinatum a \inclinatum \deminutum g \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Scandicus
\[ g \pes a \virga b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Scandicus Auctus Descendens
\[ g \pes a \pes \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Scandicus Deminutus
\[ g \pes a \pes \deminutum b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Quilisma
\[ g \pes \quilisma a \pes b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Quilisma Pes Auctus Descendens
\[ g \quilisma a \pes \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Oriscus
\[ \oriscus b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Pes Quassus
\[ \oriscus g \pes \virga b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Pes Quassus Auctus Descendens
\[ \oriscus g \pes \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Salicus
\[ g \oriscus a \pes \virga b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Salicus Auctus Descendens
\[ g \oriscus a \pes \auctum \descendens b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Stropha
\[ \stropha b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Stropha Aucta
\[ \stropha \auctum b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Bistropha
\[ \stropha b \stropha b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Tristropha
\[ \stropha b \stropha b \stropha b \]
}
@lilypond[staffsize=26,line-width=1.0\cm]
\include "gregorian.ly"
\score {
- \relative c' {
+ \relative c'' {
% Trigonus
\[ \stropha b \stropha b \stropha a \]
}
with the @code{VaticanaVoice} context substituted for the @code{Voice}
context in the @qq{accepts} list.
-Note that a context will be silently created implicitly if a command
-is encountered when there is no suitable context available to
-contain it. This can give rise to unexpected new staves or scores.
+@cindex contexts, implicit
+@cindex implicit contexts
+@funindex \defaultchild
+
+Note that a context will be silently created implicitly if a
+command is encountered when there is no suitable context available
+to contain it.
+
+Within a context definition, the type of subcontext to be
+implicitly created is specified using @code{\defaultchild}. A
+number of music events require a @samp{Bottom} context: when such
+an event is encountered, subcontexts are created recursively until
+reaching a context with no @samp{defaultchild} setting.
+
+Implicit context creation can at times give rise to unexpected new
+staves or scores. Using @code{\new} to create contexts explicitly
+avoids those problems.
@cindex alignAboveContext
@cindex alignBelowContext
\score {
<<
\new StaffGroup <<
- \context Staff {
+ \new Staff {
\clef "treble_8"
\ties
}
- \context TabStaff {
+ \new TabStaff {
\ties
}
>>
\score {
<<
\new StaffGroup <<
- \context Staff {
+ \new Staff {
\clef "treble_8"
\ties
}
- \context TabStaff {
+ \new TabStaff {
\hideSplitTiedTabNotes
\ties
}
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 d:m
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<c e g c' e'>1^\markup {
\fret-diagram #"6-x;5-3;4-2;3-o;2-1;1-o;"
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
f1 g
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<f, c f a c' f'>1^\markup {
\fret-diagram #"c:6-1-1;6-1;5-3;4-3;3-2;2-1;1-1;"
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
f1 g
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<f, c f a c' f'>1^\markup {
\fret-diagram #"s:1.5;c:6-1-1;6-1;5-3;4-3;3-2;2-1;1-1;"
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
a1
}
}
- \context Staff {
+ \new Staff {
% An 'A' chord for ukulele
a'1^\markup {
\fret-diagram #"w:4;4-2-2;3-1-1;2-o;1-o;"
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 d:m
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<c e g c' e'>1^\markup {
\fret-diagram #"f:1;6-x;5-3-3;4-2-2;3-o;2-1-1;1-o;"
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 d:m
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<c e g c' e'>1^\markup {
\fret-diagram #"d:0.35;6-x;5-3;4-2;3-o;2-1;1-o;"
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 d:m
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<c e g c' e'>1^\markup {
\fret-diagram-terse #"x;3;2;o;1;o;"
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
f1 g
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<f, c f a c' f'>1^\markup {
\fret-diagram-terse #"1-(;3;3;2;1;1-);"
@c Need to use override to enable fingerings to show this -- can we do so?
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 d:m
}
}
- \context Staff {
+ \new Staff {
\override Voice.TextScript.fret-diagram-details.finger-code = #'below-string
\clef "treble_8"
<c e g c' e'>1^\markup {
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 d:m
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<c e g c' e'>1^\markup {
\fret-diagram-verbose #'(
@c \override is necessary to make fingering visible
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
f1 g c
}
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
\override Voice.TextScript.fret-diagram-details.finger-code = #'below-string
<f, c f a c' f'>1^\markup {
@lilypond[verbatim, ragged-right, quote]
\include "predefined-guitar-fretboards.ly"
-\context FretBoards {
+\new FretBoards {
\chordmode {
c1 d
}
@lilypond[verbatim, ragged-right,quote]
\include "predefined-guitar-fretboards.ly"
-\context FretBoards {
+\new FretBoards {
\chordmode { c1 }
<c' e' g'>1
}
}
<<
- \context ChordNames {
+ \new ChordNames {
\mychords
}
- \context FretBoards {
+ \new FretBoards {
\mychords
}
>>
\transpose c e { \mychords }
}
<<
- \context ChordNames {
+ \new ChordNames {
\mychordlist
}
- \context FretBoards {
+ \new FretBoards {
\mychordlist
}
>>
}
<<
- \context ChordNames {
+ \new ChordNames {
\mychords
}
- \context FretBoards {
+ \new FretBoards {
\mychords
}
>>
}
<<
- \context ChordNames {
+ \new ChordNames {
\mychords
}
- \context FretBoards {
+ \new FretBoards {
\mychords
}
>>
}
<<
- \context ChordNames {
+ \new ChordNames {
\mychords
}
- \context FretBoards {
+ \new FretBoards {
\mychords
}
>>
}
<<
- \context ChordNames {
+ \new ChordNames {
\mychords
}
- \context FretBoards {
+ \new FretBoards {
\mychords
}
>>
@lilypond[quote,ragged-right,verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
f1 g
}
}
- \context FretBoards {
+ \new FretBoards {
<f, c f a c' f'>1
<g,\6 b, d g b g'>1
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<f, c f a c' f'>1
<g, b, d g b' g'>1
#guitar-tuning
#"x;3-1-(;5-2;5-3;5-4;3-1-1-);"
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 c c
}
}
- \context FretBoards {
+ \new FretBoards {
<c e g c' e'>1
\predefinedFretboardsOff
<c e g c' e'>1
\predefinedFretboardsOn
<c e g c' e'>1
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<c e g c' e'>1
<c e g c' e'>1
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
c1 d:m
}
}
- \context FretBoards {
+ \new FretBoards {
<c-3 e-2 g c'-1 e'>1
<d a-2 d'-3 f'-1>1
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<c e g c' e'>1
<d a d' f'>1
@lilypond[quote, verbatim]
<<
- \context ChordNames {
+ \new ChordNames {
\chordmode {
d1:m d:m
}
}
- \context FretBoards {
+ \new FretBoards {
<d a d' f'>1
\set FretBoards.minimumFret = #5
<d a d' f'>1
}
- \context Staff {
+ \new Staff {
\clef "treble_8"
<d a d' f'>1
<d a d' f'>1
\book @{
\bookOutputSuffix "Romanze"
\score @{ @dots{} @}
-Â \layout @{ @dots{} @}
+ \paper @{ @dots{} @}
@}
\book @{
\bookOutputSuffix "Menuetto"
\score @{ @dots{} @}
-Â \layout @{ @dots{} @}
+ \paper @{ @dots{} @}
@}
\book @{
\bookOutputSuffix "Nocturne"
\score @{ @dots{} @}
-Â \layout @{ @dots{} @}
+ \paper @{ @dots{} @}
@}
@end example
\book @{
\bookOutputName "Romanze"
\score @{ @dots{} @}
-Â \layout @{ @dots{} @}
+ \paper @{ @dots{} @}
@}
\book @{
\bookOutputName "Menuetto"
\score @{ @dots{} @}
-Â \layout @{ @dots{} @}
+ \paper @{ @dots{} @}
@}
\book @{
\bookOutputName "Nocturne"
\score @{ @dots{} @}
-Â \layout @{ @dots{} @}
+ \paper @{ @dots{} @}
@}
@end example
@headitem Filter
@tab Result
@item
-Tagged music preceded by @code{\keepWithTag #'@var{name}}
- @tab Untagged music and music tagged with @var{name} is included;
- music tagged with any other tag name is excluded.
+Tagged music preceded by @code{\keepWithTag #'@var{name}} or
+ @code{\keepWithTag #'(@var{name1} @var{name2}@dots{})}
+@tab Untagged music and music tagged with any of the given tag
+ names is included;
+ music tagged with any other tag name is excluded.
@item
-Tagged music preceded by @code{\removeWithTag #'@var{name}}
-@tab Untagged music and music tagged with any tag name other than
- @var{name} is included; music tagged with @var{name} is
+Tagged music preceded by @code{\removeWithTag #'@var{name}} or
+ @code{\removeWithTag #'(@var{name1} @var{name2}@dots{})}
+@tab Untagged music and music not tagged with any of the given tag names
+ is included; music tagged with any of the given tag names is
excluded.
@item
Tagged music not preceded by either @code{\keepWithTag} or
@end example
Multiple tags may be placed on expressions with multiple
-@code{\tag} entries:
+@code{\tag} entries, or by combining multiple tags into one symbol
+list:
@lilypond[quote,verbatim]
music = \relative c'' {
\tag #'a \tag #'both { a4 a a a }
- \tag #'b \tag #'both { b4 b b b }
+ \tag #'(b both) { b4 b b b }
}
<<
\keepWithTag #'a \music
@end lilypond
Multiple @code{\removeWithTag} filters may be applied to a single
-music expression to remove several differently named tagged sections:
+music expression to remove several differently named tagged
+sections. Alternatively, you can use a single
+@code{\removeWithTag} with a list of tags.
@lilypond[verbatim,quote]
music = \relative c'' {
\removeWithTag #'B
\removeWithTag #'C
\music
+\removeWithTag #'(B C)
+\music
}
@end lilypond
expression will cause @emph{all} tagged sections to be removed, as
the first filter will remove all tagged sections except the one
named, and the second filter will remove even that tagged section.
+Usually you would rather want to use a single @code{\keepWithTag}
+command with a list of multiple tags: this will only remove tagged
+sections not given in @emph{any} of the tags.
Sometimes you want to splice some music at a particular place in an
existing music expression. You can use @code{\pushToTag} and
@ref{Automatic part combining},
@ref{Including LilyPond files}.
-@ignore
-@c This warning is more general than this placement implies.
-@c Rests are not merged whether or not they come from tagged sections.
-@c Should be deleted? -td
-
@knownissues
-Multiple rests are not merged if you create a score with more
-than one tagged section at the same place.
-
-@end ignore
+Calling @code{\relative} on a music expression obtained by filtering
+music through @code{\keepWithTag} or @code{\removeWithTag} might cause
+the octave relations to change, as only the pitches actually
+remaining in the filtered expression will be considered. Applying
+@code{\relative} first, before @code{\keepWithTag} or
+@code{\removeWithTag}, avoids this danger as @code{\relative} then
+acts on all the pitches as-input.
@node Using global settings
@item
The pitch of the first note is relative to
@code{@var{startpitch}}. @code{@var{startpitch}} is specified in
-absolute octave mode, and it is recommended that it be a octave of
-@code{c}.
+absolute octave mode. Which choices are meaningful?
+
+@table @asis
+@item an octave of @code{c}
+Identifying middle C with @code{c'} is quite basic, so finding
+octaves of @code{c} tends to be straightforward. If your music
+starts with @code{gis} above @code{c'''}, you'd write something
+like @code{\relative c''' @{ gis' @dots{} @}}
+
+@item an octave of the first note inside
+Writing @code{\relative gis''' @{ gis @dots{} @}} makes it easy to
+determine the absolute pitch of the first note inside.
+
+@item no explicit starting pitch
+This (namely writing @code{\relative @{ gis''' @dots{} @}}) can be
+viewed as a compact version of the previous option: the first note
+inside is written in absolute pitch itself. This happens to be
+equivalent to choosing @code{f} as the reference pitch.
+@end table
+
+The documentation will usually employ the first option.
@end itemize
Here is the relative mode shown in action:
}
@end lilypond
+It is common in choral music to have a voice part split for
+several measures. The @code{<< @{@dots{}@} \\ @{@dots{}@} >>}
+construct, where the two (or more) musical expressions are
+separated by double backslashes, might seem the proper way to
+set the split voices. This construct, however, will assign
+@strong{all} the expressions within it to @strong{NEW Voice
+contexts} which will result in @emph{no lyrics} being set for
+them since the lyrics will be set to the original voice context
+-- not, typically, what one wants. The temporary polyphonic
+passage is the proper construct to use, see section
+@emph{Temporary polyphonic passages} in @ref{Single-staff polyphony}.
+
@node Stanzas
@subsection Stanzas
down. To do this, use @code{\voiceOne} and @code{\voiceTwo}. See
@ref{Single-staff polyphony}.
+@item
+When a vocal part temporarily splits, you should use
+@emph{Temporary polyphonic passages}
+(see @ref{Single-staff polyphony}).
+
@end itemize
@predefined
-%% DO NOT EDIT this file manually; it is automatically
-%% generated from LSR http://lsr.dsi.unimi.it
-%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
-%% and then run scripts/auxiliar/makelsr.py
-%%
-%% This file is in the public domain.
+% 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.16.0
\version "2.16.0"
\header {
shortInstrumentName = #'()
\accepts "Voice"
+ \defaultchild "Voice"
}
% and then run scripts/auxiliar/makelsr.py
%
% This file is in the public domain.
-%% Note: this file works from version 2.17.6
-\version "2.17.6"
+%% Note: this file works from version 2.17.10
+\version "2.17.10"
\header {
lsrtags = "staff-notation, ancient-notation, really-cool"
% escaping lexical closure and evaluating
% everything respective to (current-module).
#(primitive-eval
- '(or (false-if-exception (- indent (* mm incipit-width)))
+ '(or (false-if-exception (- indent incipit-width))
(* 0.5 indent)))
ragged-right = ##f
ragged-last = ##f
--- /dev/null
+\version "2.16.0"
+
+\header {
+ lsrtags = "contexts-and-engravers, specific-notation"
+
+ texidoc = "
+The notation problem, creating a certain symbol, is handled by plugins.
+ Each plugin is called an Engraver. In this example, engravers are
+switched on one by one, in the following order:
+
+- note heads,
+
+
+- staff symbol,
+
+
+- clef,
+
+
+- stem,
+
+
+- beams, slurs, accents,
+
+
+- accidentals, bar lines, time signature and key signature.
+
+
+
+Engravers are grouped. For example, note heads, slurs, beams etc. form
+a @code{Voice} context. Engravers for key signature, accidentals, bar
+line, etc. form a @code{Staff} context.
+
+"
+ doctitle = "Engravers one-by-one"
+}
+
+%% sample music
+topVoice = \relative c' {
+ \key d \major
+ es8([ g] a[ fis])
+ b4
+ b16[-. b-. b-. cis-.]
+ d4->
+}
+
+botVoice = \relative c' {
+ \key d \major
+ c8[( f] b[ a)]
+ es4
+ es16[-. es-. es-. fis-.]
+ b4->
+}
+
+hoom = \relative c {
+ \key d \major
+ \clef bass
+ g8-. r
+ r4
+ fis8-.
+ r8
+ r4
+ b'4->
+}
+
+pah = \relative c' {
+ r8 b-.
+ r4
+ r8 g8-.
+ r16 g-. r8
+ \clef treble
+ fis'4->
+}
+
+%
+% setup for Request->Element conversion. Guru-only
+%
+
+MyStaff = \context {
+ \type "Engraver_group"
+ \name Staff
+
+ \description "Handles clefs, bar lines, keys, accidentals. It can contain
+@code{Voice} contexts."
+
+ \consists "Output_property_engraver"
+
+ \consists "Font_size_engraver"
+
+ \consists "Volta_engraver"
+ \consists "Separating_line_group_engraver"
+ \consists "Dot_column_engraver"
+
+ \consists "Ottava_spanner_engraver"
+ \consists "Rest_collision_engraver"
+ \consists "Piano_pedal_engraver"
+ \consists "Piano_pedal_align_engraver"
+ \consists "Instrument_name_engraver"
+ \consists "Grob_pq_engraver"
+ \consists "Forbid_line_break_engraver"
+ \consists "Axis_group_engraver"
+
+ \consists "Pitch_squash_engraver"
+
+ localKeySignature = #'()
+
+ % explicitly set instrumentName, so we don't get
+ % weird effects when doing instrument names for
+ % piano staves
+
+ instrumentName = #'()
+ shortInstrumentName = #'()
+
+ \accepts "Voice"
+ \defaultchild "Voice"
+}
+
+
+MyVoice = \context {
+ \type "Engraver_group"
+ \name Voice
+
+ \description "
+ Corresponds to a voice on a staff. This context handles the
+ conversion of dynamic signs, stems, beams, super- and subscripts,
+ slurs, ties, and rests.
+
+ You have to instantiate this explicitly if you want to have
+ multiple voices on the same staff."
+
+ localKeySignature = #'()
+ \consists "Font_size_engraver"
+
+ % must come before all
+ \consists "Output_property_engraver"
+ \consists "Arpeggio_engraver"
+ \consists "Multi_measure_rest_engraver"
+ \consists "Text_spanner_engraver"
+ \consists "Grob_pq_engraver"
+ \consists "Note_head_line_engraver"
+ \consists "Glissando_engraver"
+ \consists "Ligature_bracket_engraver"
+ \consists "Breathing_sign_engraver"
+ % \consists "Rest_engraver"
+ \consists "Grace_beam_engraver"
+ \consists "New_fingering_engraver"
+ \consists "Chord_tremolo_engraver"
+ \consists "Percent_repeat_engraver"
+ \consists "Slash_repeat_engraver"
+
+ %{
+ Must come before text_engraver, but after note_column engraver.
+ %}
+ \consists "Text_engraver"
+ \consists "Dynamic_engraver"
+ \consists "Fingering_engraver"
+
+ \consists "Script_column_engraver"
+ \consists "Rhythmic_column_engraver"
+ \consists "Cluster_spanner_engraver"
+ \consists "Tie_engraver"
+ \consists "Tie_engraver"
+ \consists "Tuplet_engraver"
+ \consists "Note_heads_engraver"
+ \consists "Rest_engraver"
+}
+
+
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
+
+
+MyStaff = \context {
+ \MyStaff
+ \consists "Staff_symbol_engraver"
+}
+
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
+
+MyStaff = \context {
+ \MyStaff
+ \consists "Clef_engraver"
+ \remove "Pitch_squash_engraver"
+}
+
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
+
+MyVoice = \context {
+ \MyVoice
+ \consists "Stem_engraver"
+}
+
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
+
+MyVoice = \context {
+ \MyVoice
+ \consists "Beam_engraver"
+}
+
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
+
+MyVoice = \context {
+ \MyVoice
+ \consists "Phrasing_slur_engraver"
+ \consists "Slur_engraver"
+ \consists "Script_engraver"
+}
+
+
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
+
+MyStaff = \context {
+ \MyStaff
+ \consists "Bar_engraver"
+ \consists "Time_signature_engraver"
+}
+
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
+
+MyStaff = \context {
+ \MyStaff
+ \consists "Accidental_engraver"
+ \consists "Key_engraver"
+}
+\score {
+ \topVoice
+ \layout {
+ \context { \MyStaff }
+ \context { \MyVoice }
+ }
+}
-\version "2.17.6"
+\version "2.17.10"
\header {
lsrtags = "staff-notation, ancient-notation, really-cool"
% escaping lexical closure and evaluating
% everything respective to (current-module).
#(primitive-eval
- '(or (false-if-exception (- indent (* mm incipit-width)))
+ '(or (false-if-exception (- indent incipit-width))
(* 0.5 indent)))
ragged-right = ##f
ragged-last = ##f
* Error message Unbound variable %::
* Error message FT_Get_Glyph_Name::
* Warning staff affinities should only decrease::
+* Error message unexpected \new::
@end menu
@node Music runs off the page
@noindent
at its start. For details, see @qq{Spacing of non-staff lines} in
@ruser{Flexible vertical spacing within systems}.
+
+
+@node Error message unexpected \new
+@unnumberedsubsec Error message unexpected @code{\new}
+
+A @code{\score} block must contain a @emph{single} music expression.
+If instead it contains several @code{\new Staff},
+@code{\new StaffGroup} or similar contexts introduced with @code{\new}
+without them being enclosed in either curly brackets,
+@code{@{ @dots{} @}}, or double angle brackets, @code{<< @dots{} >>},
+like this:
+
+@example
+\score @{
+ % Invalid! Generates error: syntax error, unexpected \new
+ \new Staff @{ @dots{} @}
+ \new Staff @{ @dots{} @}
+@}
+@end example
+
+@noindent
+the error message will be produced.
+
+To avoid the error, enclose all the @code{\new} statements in
+curly or double angle brackets.
+
+Using curly brackets will introduce the @code{\new} statements
+sequentially:
+
+@lilypond[quote,verbatim]
+\score {
+ {
+ \new Staff { a' a' a' a' }
+ \new Staff { g' g' g' g' }
+ }
+}
+@end lilypond
+
+@noindent
+but more likely you should be using double angle brackets so the new
+staves are introduced in parallel, i.e. simultaneously:
+
+@lilypond[quote,verbatim]
+\score {
+ <<
+ \new Staff { a' a' a' a' }
+ \new Staff { g' g' g' g' }
+ >>
+}
+@end lilypond
@c used for news about the upcoming release; see CG 10.2
@newsItem
-@subsubheading LilyPond 2.17.14 released! @emph{March 10, 2013}
+@subsubheading LilyPond 2.17.16 released! @emph{April 13, 2013}
-We are happy to announce the release of LilyPond 2.17.14. This
-release contains the usual number of bugfixes (including putting span bars back
-where they should be) and enhancements, and contains
+We are happy to announce the release of LilyPond 2.17.16. This
+release contains the usual number of bugfixes and 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.16 version.
* don't duplicate entries from news-front.itexi
@end ignore
+@newsItem
+@subsubheading LilyPond 2.17.15 released! @emph{March 30, 2013}
+
+We are happy to announce the release of LilyPond 2.17.15. This
+release contains the usual number of bugfixes and 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.16 version.
+
+@newsEnd
+
+@newsItem
+@subsubheading LilyPond 2.17.14 released! @emph{March 10, 2013}
+
+We are happy to announce the release of LilyPond 2.17.14. This
+release contains the usual number of bugfixes (including putting span bars back
+where they should be) and 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.16 version.
+
+@newsEnd
+
@newsItem
@subsubheading LilyPond 2.17.13 released! @emph{February 23, 2013}
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=17
-PATCH_LEVEL=15
+PATCH_LEVEL=17
MY_PATCH_LEVEL=
VERSION_STABLE=2.16.2
-VERSION_DEVEL=2.17.14
+VERSION_DEVEL=2.17.16
d-4_\markup { \italic "cantabile" } }
{ e } } \acciaccatura { c16 }
- f4\ff^""^\markup { \large "Largo" } \mark "B" g
+ f4\ff^\markup { \large "Largo" } \mark "B" g
}
-\version "2.16.0"
+\version "2.17.17"
\header {
texidoc = "Arpeggio stays clear of accidentals and flipped note heads."
\context{
\Staff
connectArpeggios = ##t
+ \consists "Span_arpeggio_engraver"
}
}
<fis'' g d a>\arpeggio
<fis, g d a>\arpeggio
<fis'' g d a>\arpeggio
+ << { <e' a>\arpeggio } \\ { <g cis>\arpeggio } >>
}
+++ /dev/null
-\version "2.17.14"
-
-\header {
- texidoc =
-"Property @code{chord-dots}: If set, remove dots which the
-@code{DotColumn} algorithm would vertically position too far away from
-note heads."
-}
-
-\layout{ ragged-right = ##t }
-
-
-\relative c'' {
- \override Score.DotColumn.chord-dots = ##f
- << { <d e f g a>4. } \\
- { <a, b c d e>4. } >>
-
- \override Score.DotColumn.chord-dots = ##t
- << { <d' e f g a>4. } \\
- { <a, b c d e>4. } >>
-}
--- /dev/null
+\version "2.17.16"
+
+\header {
+ texidoc = "@code{DynamicText}, @code{DynamicLineSpanner}, and
+@code{Hairpin} do not have @code{outside-staff-priority} in @code{Dynamics}
+contexts. This allows grobs with @code{outside-staff-priority} set
+to be positioned above and below them.
+"
+}
+
+<<
+ \new Staff = "Test" {
+ \tempo "Andante" c'1
+ }
+ \new Dynamics \with { alignAboveContext = "Test" } {
+ s1\f
+ }
+>>
--- /dev/null
+\version "2.17.14"
+
+\header {
+ texidoc = "LilyPond creates hairpins found in Ferneyhough scores.
+"
+}
+
+\relative c'' {
+ \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
+ a4\< a a a\f
+ a4\p\< a a a\ff
+ a4\sfz\< a a a\!
+ \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
+ a4\> a a a\f
+ a4\p\> a a a\ff
+ a4\sfz\> a a a\!
+}
\ No newline at end of file
--- /dev/null
+\version "2.17.16"
+
+\header {
+ texidoc = "Horizontally-offset @code{Fingerings} align along the Y axis when
+they are within @code{FingeringColumn.snap-radius} of each other.
+"
+}
+
+\relative f'' {
+ \set fingeringOrientations = #'(left)
+ <cis-1 a-1 e-1>4
+ <ceses-1 a-1 e-1>4
+}
-\version "2.17.6"
+\version "2.17.10"
\header {
texidoc = "Incipits can be printed using an @code{InstrumentName}
'MensuralStaff)
(ly:grob-property grob 'music))))
(score (ly:make-score music))
- (mm (ly:output-def-lookup layout 'mm))
(indent (ly:output-def-lookup layout 'indent))
- (incipit-width (ly:output-def-lookup layout 'incipit-width))
- (scaled-incipit-width (if (number? incipit-width)
- (* incipit-width mm)
- (* indent 0.5))))
- (ly:output-def-set-variable! layout 'indent (- indent scaled-incipit-width))
+ (incipit-width (ly:output-def-lookup layout 'incipit-width
+ (* indent 0.5))))
+ (ly:output-def-set-variable! layout 'indent (- indent incipit-width))
(ly:output-def-set-variable! layout 'line-width indent)
(ly:output-def-set-variable! layout 'ragged-right #f)
(ly:score-add-output-def! score layout)
\new StaffGroup <<
\new Staff {
\override Staff.InstrumentName.self-alignment-X = #LEFT
- \set Staff . instrumentName = \markup \column {
+ \set Staff . instrumentName = \markup \left-column {
"Left aligned" "instrument name"
}
\set Staff . shortInstrumentName = "Left"
}
\new Staff {
\override Staff.InstrumentName.self-alignment-X = #RIGHT
- \set Staff . instrumentName = \markup \column \right-align {
+ \set Staff . instrumentName = \markup \right-column {
"Right aligned" "instrument name"
}
\set Staff . shortInstrumentName = "Right"
--- /dev/null
+\version "2.17.16"
+
+\header {
+ texidoc = "Long spanners at the end of the lines stretch measures
+correctly.
+"
+}
+
+{
+ \override Hairpin.minimum-length = #60
+ \override Hairpin.to-barline = ##t
+ \repeat unfold 4 a1
+ a1\<
+ a1\>
+ a1\!
+}
dis[( e)] r e-. e[( f)] r f-. |
g4-.\f e-. c-. bes-. |
g-.\ff e-. c-. r |
- a'2 ~ a8[_""_\markup { \bold \italic "sempre " \dynamic "f" } b16 c] d[( e d e)]
+ a'2 ~ a8[_\markup { \bold \italic "sempre " \dynamic "f" } b16 c] d[( e d e)]
f4. ( d8) f8[ ( d) f d]
c[ (e] g2) \appoggiatura f16
\tupletUp
\override TupletNumber.stencil = ##f
- \tuplet 3/2 { c8^""^""^"up, no digit" c[ c] }
+ \tuplet 3/2 { c8^"up, no digit" c[ c] }
\revert TupletNumber.stencil
\override TupletBracket.bracket-visibility = ##t
\revert TupletBracket.shorten-pair
\override TupletBracket.bracket-flare = #'(0.5 . 0.5)
- \tuplet 3/2 { b^""^""^"angled edges" b b }
+ \tuplet 3/2 { b^"angled edges" b b }
\tupletNeutral
\tuplet 3/2 { b b b }
}
#include "engraver.hh"
-#include "pointer-group-interface.hh"
#include "arpeggio.hh"
-#include "stem.hh"
+#include "item.hh"
+#include "note-column.hh"
+#include "pointer-group-interface.hh"
#include "rhythmic-head.hh"
+#include "separation-item.hh"
#include "side-position-interface.hh"
+#include "stem.hh"
#include "stream-event.hh"
-#include "note-column.hh"
-#include "item.hh"
#include "translator.icc"
void acknowledge_stem (Grob_info);
void acknowledge_rhythmic_head (Grob_info);
+ void acknowledge_note_column (Grob_info);
+
protected:
void process_music ();
void stop_translation_timestep ();
Side_position_interface::add_support (arpeggio_, info.grob ());
}
+void
+Arpeggio_engraver::acknowledge_note_column (Grob_info info)
+{
+ if (arpeggio_)
+ Separation_item::add_conditional_item (info.grob (), arpeggio_);
+}
+
void
Arpeggio_engraver::process_music ()
{
ADD_ACKNOWLEDGER (Arpeggio_engraver, stem);
ADD_ACKNOWLEDGER (Arpeggio_engraver, rhythmic_head);
+ADD_ACKNOWLEDGER (Arpeggio_engraver, note_column);
ADD_TRANSLATOR (Arpeggio_engraver,
/* doc */
#include "output-def.hh"
#include "paper-column.hh"
#include "pointer-group-interface.hh"
-#include "self-alignment-interface.hh"
#include "side-position-interface.hh"
#include "warn.hh"
= extract_grob_array (me, "dots");
vector<Grob *> main_heads;
- vector<Interval> allowed_y_positions;
Real ss = 0;
Grob *commonx = me;
commonx = stem->common_refpoint (commonx, X_AXIS);
if (Stem::first_head (stem) == n)
- {
- main_heads.push_back (n);
-
- // Get vertical interval of the chord's notehead positions.
- // We widen this interval since dots always sit between staff
- // lines. Be careful to make it work also for unusual
- // overrides of `NoteHead.Y-offset'.
- //
- // Possible solutions to improve this code (namely, to handle
- // the `staff-position' property also) -- in case there is
- // ever the desire or necessity to do so -- can be found in
- // the Rietveld comments at
- //
- // https://codereview.appspot.com/7319049
-
- Interval hp = Stem::head_positions (stem);
-
- int top = int (ceil (hp[UP]));
- if (Staff_symbol_referencer::on_line (stem, top))
- top += 1;
- hp[UP] = top;
-
- int bottom = int (floor (hp[DOWN]));
- if (Staff_symbol_referencer::on_line (stem, bottom))
- bottom -= 1;
- hp[DOWN] = bottom;
-
- allowed_y_positions.push_back (hp);
- }
+ main_heads.push_back (n);
}
}
problem.register_configuration (cfg);
- // If in a chord, remove dots which have vertical positions above or below
- // the topmost or bottommost note, respectively ([Gould], p. 56).
- // Note that a dot configuration can contain more than a single chord or
- // rest (the latter gets ignored).
- //
- // The dot positioning algorithm vertically shifts dots; it thus can
- // happen that, say, a dot of the upper voice's chord is positioned
- // beneath a note head of the lower voice's chord, while the dots of the
- // lower voice's chord are shifted down even more. We thus check all
- // vertical ranges for valid positions and not only the range of the dot's
- // parent chord.
- //
- // Do nothing if there is either no staff line, or no note head, or the
- // `chord-dots' property not set.
- Grob *st = Staff_symbol_referencer::get_staff_symbol (me);
- vsize num_positions = allowed_y_positions.size ();
- bool chord_dots = to_boolean (me->get_property ("chord-dots"));
-
- if (st && num_positions && chord_dots)
- {
- for (Dot_configuration::const_iterator i (cfg.begin ());
- i != cfg.end (); i++)
- {
- vsize j;
-
- for (j = 0; j < num_positions; j++)
- if (allowed_y_positions[j].contains (i->first))
- break;
-
- if (j == num_positions)
- {
- Grob *dot = i->second.dot_;
- Grob *n = dot->get_parent (Y_AXIS);
- if (n && Note_head::has_interface (n))
- dot->suicide ();
- }
- }
- }
-
for (Dot_configuration::const_iterator i (cfg.begin ());
i != cfg.end (); i++)
{
" dots so they do not clash with staff lines.",
/* properties */
- "chord-dots "
- "direction "
"dots "
- "note-collision "
"positioning-done "
+ "direction "
+ "note-collision "
);
along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "directional-element-interface.hh"
#include "grob.hh"
#include "fingering-column.hh"
#include "pointer-group-interface.hh"
#include "item.hh"
#include "paper-column.hh"
+#define EPS 1e-5
+
+struct Fingering_and_offset
+{
+ Grob *fingering_;
+ Real offset_;
+ Fingering_and_offset (Grob *fingering, Real offset);
+};
+
+Fingering_and_offset::Fingering_and_offset (Grob *fingering, Real offset) :
+ fingering_ (fingering), offset_ (offset)
+{
+}
+
+bool
+fingering_and_offset_less (Fingering_and_offset fo0, Fingering_and_offset fo1)
+{
+ return fo0.offset_ < fo1.offset_;
+}
+
MAKE_SCHEME_CALLBACK (Fingering_column, calc_positioning_done, 1);
SCM
Fingering_column::calc_positioning_done (SCM smob)
me->set_property ("positioning-done", SCM_BOOL_T);
+ do_y_positioning (me);
+ do_x_positioning (me);
+
+ return SCM_BOOL_T;
+}
+
+void
+Fingering_column::do_y_positioning (Grob *me)
+{
extract_grob_set (me, "fingerings", const_fingerings);
if (const_fingerings.size () < 2)
{
me->programming_error ("This FingeringColumn should have never been created.");
- return SCM_BOOL_T;
+ return;
}
vector<Grob *> fingerings;
for (vsize i = 0; i < fingerings.size (); i++)
fingerings[i]->translate_axis(shift[i], Y_AXIS);
+}
+
+void
+Fingering_column::do_x_positioning (Grob *me)
+{
+ extract_grob_set (me, "fingerings", fingerings);
+ if (!fingerings.size ())
+ return;
+
+ Grob *common_x = common_refpoint_of_array (fingerings, me, X_AXIS);
+
+ Real snap = robust_scm2double (me->get_property ("snap-radius"), 0.3);
+ vector<Fingering_and_offset> fos;
+
+ for (vsize i = 0; i < fingerings.size (); i++)
+ fos.push_back (Fingering_and_offset (fingerings[i], fingerings[i]->relative_coordinate (common_x, X_AXIS)));
+
+ vector_sort (fos, fingering_and_offset_less);
+ Direction dir = get_grob_direction (fingerings[0]);
+ if (dir == RIGHT)
+ reverse (fos);
+
+ Real prev = infinity_f * dir;
+ for (vsize i = 0; i < fos.size (); i++)
+ {
+ if ((fabs (fos[i].offset_ - prev) < snap)
+ && (fabs (fos[i].offset_ - prev) > EPS))
+ fos[i].offset_ = prev;
+
+ prev = fos[i].offset_;
+ }
- return SCM_BOOL_T;
+ for (vsize i = 0; i < fos.size (); i++)
+ fos[i].fingering_->translate_axis (fos[i].offset_ - fos[i].fingering_->relative_coordinate (common_x, X_AXIS), X_AXIS);
}
void
ADD_INTERFACE (Fingering_column,
"Makes sure that fingerings placed laterally"
- " do not collide.",
+ " do not collide and that they are flush if"
+ " necessary.",
/* properties */
"padding "
"positioning-done "
+ "snap-radius "
);
static void add_fingering (Grob *, Grob *);
DECLARE_SCHEME_CALLBACK (calc_positioning_done, (SCM));
DECLARE_GROB_INTERFACE ();
+ static void do_x_positioning (Grob *me);
+ static void do_y_positioning (Grob *me);
};
#endif /* FINGERING_COLUMN_HH */
static bool shift_less (Grob *const &, Grob *const &);
static Direction dir (Grob *me);
static Grob *accidentals (Grob *me);
- static Grob *arpeggio (Grob *me);
static Slice head_positions_interval (Grob *me);
static Grob *first_head (Grob *me);
static Grob *get_rest (Grob *me);
return 0;
}
-Grob *
-Note_column::arpeggio (Grob *me)
-{
- return unsmob_grob (me->get_object ("arpeggio"));
-}
-
/* If a note-column contains a cross-staff stem then
nc->extent (Y_AXIS, refp) will not consider the extent of the stem.
If you want the extent of the stem to be included (and you are safe
"Stem and noteheads combined.",
/* properties */
- "arpeggio "
"force-hshift "
"horizontal-shift "
"ignore-collision "
: 0.0))
+
(footnote_height
- - (has_footnotes_
- ? breaker_->footnote_padding () + breaker_->footnote_footer_padding ()
+ + (has_footnotes_
+ ? - breaker_->footnote_padding () + breaker_->footnote_footer_padding ()
: 0.0));
}
#include "international.hh"
#include "accidental-placement.hh"
#include "accidental-interface.hh"
+#include "arpeggio.hh"
#include "axis-group-interface.hh"
#include "context.hh"
#include "note-spacing.hh"
if (!unsmob_grob (elem->get_object ("axis-group-parent-X")))
elem->set_object ("axis-group-parent-X", col->self_scm ());
- if (Accidental_placement::has_interface (elem))
+ if (Accidental_placement::has_interface (elem)
+ || Arpeggio::has_interface (elem))
Separation_item::add_conditional_item (col, elem);
else if (!Accidental_interface::has_interface (elem))
Separation_item::add_item (col, elem);
$$ = SCM_UNSPECIFIED;
}
}
- | embedded_scm
+ | music_embedded_backup BACKUP SCM_ARG
+ {
+ $$ = $3;
+ }
+ | music_embedded_backup BACKUP lyric_element_music
+ {
+ $$ = $3;
+ }
+ ;
+
+music_embedded_backup:
+ embedded_scm_closed
{
if (scm_is_eq ($1, SCM_UNSPECIFIED))
- $$ = $1;
+ MYBACKUP (SCM_ARG, $1, @1);
else if (Music *m = unsmob_music ($1)) {
if (m->is_mus_type ("post-event")) {
parser->parser_error
(@1, _ ("unexpected post-event"));
- $$ = SCM_UNSPECIFIED;
+ MYBACKUP (SCM_ARG, SCM_UNSPECIFIED, @1);
} else
- $$ = $1;
- } else {
+ MYBACKUP (SCM_ARG, $1, @1);
+ } else if (parser->lexer_->is_lyric_state ()
+ && Text_interface::is_markup ($1))
+ MYBACKUP (LYRIC_ELEMENT, $1, @1);
+ else {
@$.warning (_ ("Ignoring non-music expression"));
- $$ = SCM_UNSPECIFIED;
+ MYBACKUP (SCM_ARG, SCM_UNSPECIFIED, @1);
}
}
;
// \revert Accidental.color
revert_arg:
+ revert_arg_backup BACKUP symbol_list_arg
+ {
+ $$ = $3;
+ }
+ ;
+
+revert_arg_backup:
revert_arg_part
{
if (scm_is_null ($1)
else
MYBACKUP (SYMBOL_LIST, scm_reverse_x ($1, SCM_EOL), @1);
}
- | revert_arg BACKUP symbol_list_arg
- {
- $$ = $3;
- }
;
// revert_arg_part delivers results in reverse
revert_arg_part:
symbol_list_part
- | revert_arg BACKUP SCM_ARG '.' symbol_list_part
+ | revert_arg_backup BACKUP SCM_ARG '.' symbol_list_part
{
$$ = scm_append_x (scm_list_2 ($5, $3));
}
- | revert_arg BACKUP SCM_ARG symbol_list_part
+ | revert_arg_backup BACKUP SCM_ARG symbol_list_part
{
$$ = scm_append_x (scm_list_2 ($4, $3));
}
simple_markup_list {
$$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
}
- | markup_head_1_list simple_markup {
- $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
+ | markup_head_1_list simple_markup
+ {
+ $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
+ @2, $1, scm_list_1 ($2)));
}
| simple_markup {
$$ = $1;
markup_composed_list {
$$ = $1;
}
- | markup_braced_list {
+ | markup_uncomposed_list
+ ;
+
+markup_uncomposed_list:
+ markup_braced_list {
$$ = $1;
}
| markup_command_list {
;
markup_composed_list:
- markup_head_1_list markup_braced_list {
- $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
-
+ markup_head_1_list markup_uncomposed_list {
+ $$ = MAKE_SYNTAX ("composed-markup-list",
+ @2, $1, $2);
}
;
;
markup:
- markup_head_1_list simple_markup {
- SCM mapper = ly_lily_module_constant ("map-markup-command-list");
- $$ = scm_car (scm_call_2 (mapper, $1, scm_list_1 ($2)));
+ markup_head_1_list simple_markup
+ {
+ $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
+ @2, $1, scm_list_1 ($2)));
}
| simple_markup {
$$ = $1;
Grob *stem_;
Grob *flag_;
Grob *note_column_;
- Grob *arpeggio_;
TRANSLATOR_DECLARATIONS (Rhythmic_column_engraver);
protected:
DECLARE_ACKNOWLEDGER (stem);
DECLARE_ACKNOWLEDGER (flag);
DECLARE_ACKNOWLEDGER (rhythmic_head);
- DECLARE_ACKNOWLEDGER (arpeggio);
void process_acknowledged ();
void stop_translation_timestep ();
};
stem_ = 0;
flag_ = 0;
note_column_ = 0;
- arpeggio_ = 0;
}
void
stem_ = 0;
}
- if (arpeggio_)
+ if (flag_)
{
- Pointer_group_interface::add_grob (note_column_, ly_symbol2scm ("elements"), arpeggio_);
- note_column_->set_object ("arpeggio", arpeggio_->self_scm ());
+ Pointer_group_interface::add_grob (note_column_, ly_symbol2scm ("elements"), flag_);
+ flag_ = 0;
}
- if (flag_)
- Pointer_group_interface::add_grob (note_column_, ly_symbol2scm ("elements"), flag_);
}
}
rheads_.push_back (i.grob ());
}
-void
-Rhythmic_column_engraver::acknowledge_arpeggio (Grob_info i)
-{
- arpeggio_ = i.grob ();
-}
-
void
Rhythmic_column_engraver::stop_translation_timestep ()
{
note_column_ = 0;
stem_ = 0;
- arpeggio_ = 0;
flag_ = 0;
}
ADD_ACKNOWLEDGER (Rhythmic_column_engraver, stem);
ADD_ACKNOWLEDGER (Rhythmic_column_engraver, flag);
ADD_ACKNOWLEDGER (Rhythmic_column_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Rhythmic_column_engraver, arpeggio);
ADD_TRANSLATOR (Rhythmic_column_engraver,
/* doc */
if (scm_is_number (align))
{
Interval ext (me->maybe_pure_extent (me, a, pure, start, end));
+ // Empty extent doesn't mean an error - we simply don't align such grobs.
+ // However, empty extent and non-empty stencil would be suspicious.
if (!ext.is_empty ())
return scm_from_double (- ext.linear_combination (scm_to_double (align)));
+ else if (me->get_stencil ())
+ warning (me->name () + " has empty extent and non-empty stencil.");
}
return scm_from_double (0.0);
}
Real align = scm_to_double (align_prop);
Interval ext (me->extent (me, a));
- if (ext.is_empty ())
- programming_error ("cannot align on self: empty element");
- else
+
+ // Empty extent doesn't mean an error - we simply don't align such grobs.
+ // However, empty extent and non-empty stencil would be suspicious.
+ if (!ext.is_empty ())
x -= ext.linear_combination (align);
+ else if (me->get_stencil ())
+ warning (me->name () + " has empty extent and non-empty stencil.");
+ // See comment above.
if (!he.is_empty ())
x += he.linear_combination (align);
+ else if (him->get_stencil ())
+ warning (him->name () + " has empty extent and non-empty stencil.");
return scm_from_double (x);
}
return sp.smobbed_copy ();
}
-/* if left is non-NULL, get the boxes corresponding to the
- conditional-elements (conditioned on the grob LEFT). This
- sounds more general than it is: conditional-elements are
- always accidentals attached to a tied note.
+/*
+ If left is non-NULL, get the boxes corresponding to the
+ conditional-elements (conditioned on the grob LEFT).
+ Conditional elements are, for now, arpeggios and accidental
+ placements. Based on the left grob, the accidentals will
+ be printed or not, so we filter using
+ Accidental_placement::get_relevant_accidentals.
*/
vector<Box>
Separation_item::boxes (Grob *me, Grob *left)
vector<Grob *> elts;
if (left)
- elts = Accidental_placement::get_relevant_accidentals (read_only_elts, left);
+ {
+ vector<Grob *> accidental_elts;
+ vector<Grob *> other_elts; // for now only arpeggios
+ for (vsize i = 0; i < read_only_elts.size (); i++)
+ {
+ if (Accidental_placement::has_interface (read_only_elts[i]))
+ accidental_elts.push_back (read_only_elts[i]);
+ else
+ other_elts.push_back (read_only_elts[i]);
+ }
+ elts = Accidental_placement::get_relevant_accidentals (accidental_elts, left);
+ elts.insert (elts.end (), other_elts.begin (), other_elts.end ());
+ }
else
elts = read_only_elts;
dim.set_minimum_height (staff_extents[dir]);
}
- // this seems kinda kludgy, as there is no apparent logic to it
- // however, it is a holdover from the previous code and
- // necessary for the InstrumentName grob
- // TODO: find a better way to deal with this...
+ // Sometimes, we want to side position for grobs but they
+ // don't position against anything. Some cases where this is true:
+ // - StanzaNumber if the supporting lyrics are hara-kiri'd
+ // SystemStartBracket
+ // InstrumentName
+ // In all these cases, we set the height of the support to 0.
+ // This becomes then like the self-alignment-interface with the
+ // caveat that there is padding added.
+ // TODO: if there is a grob that never has side-support-elements
+ // (like InstrumentName), why are we using this function? Isn't it
+ // overkill? A function like self-alignment-interface with padding
+ // works just fine.
+ // One could even imagine the two interfaces merged, as the only
+ // difference is that in self-alignment-interface we align on the parent
+ // where as here we align on a group of grobs.
if (dim.is_empty ())
{
dim = Skyline (dim.direction ());
if (cols[j] == other)
description.rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s))));
else /* it must end at the LEFT prebroken_piece */
+ /* see Spanner::set_spacing_rods for more comments on how
+ to deal with situations where we don't know if we're
+ ending yet on the left prebroken piece */
description.end_rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s))));
}
}
This means that the merging routine doesn't need to be aware of direction,
but the distance routine does.
- Be careful about numerical accuracy. When dealing with extremely small values,
- computation errors may arise due to the use of floating point arithmetic.
- For example, if left and right have equal values to start with, in C++
- they may not receive the same value after
-
- left = left*factor + offset;
- right = right*factor + offset;
-
- Which is very unfortunate. Maybe using GCC compiler options to disallow
- extended precision for intermediate results and/or the choice to store
- intermediates with less than full precision would retain some kind of
- deterministic behavior that way.
-
- Anyway, it seems that accepting extremely narrow building in skylines
- doesn't cause accuracy problems to us, so we allow arbitrarily small buildings.
- However, as Keith pointed out, problems may appear if more than one operation
- is done before storing the result, and/or there are different code paths
- for doing the operations to the different ends of an interval.
+ From 2007 through 2012, buildings of width less than EPS were discarded,
+ citing numerical accuracy concerns. We remember that floating point
+ comparisons of nearly-equal values can be affected by rounding error.
+ Also, some target machines use the x87 floating point unit, which provides
+ extended precision for intermediate results held in registers. On this type
+ of hardware comparisons such as
+ double c = 1.0/3.0; boolean compare = (c == 1.0/3.0)
+ could go either way because the 1.0/3.0 is allowed to be kept
+ higher precision than the variable 'c'.
+ Alert to these considerations, we now accept buildings of zero-width.
*/
static void
continue;
}
- if (x1 >= last_end)
+ // Insert empty Buildings into any gaps. (TODO: is this needed? -KOH)
+ if (x1 > last_end)
result.push_back (Building (last_end, -infinity_f, -infinity_f, x1));
result.push_back (*i);
#include "engraver.hh"
#include "arpeggio.hh"
+#include "item.hh"
#include "pointer-group-interface.hh"
+#include "separation-item.hh"
#include "side-position-interface.hh"
#include "staff-symbol-referencer.hh"
-#include "item.hh"
/**
Make arpeggios that span multiple staves. Catch arpeggios, and span a
public:
TRANSLATOR_DECLARATIONS (Span_arpeggio_engraver);
DECLARE_ACKNOWLEDGER (arpeggio);
+ DECLARE_ACKNOWLEDGER (note_column);
protected:
void process_acknowledged ();
private:
Item *span_arpeggio_;
vector<Grob *> arpeggios_;
+ vector<Grob *> note_columns_;
};
Span_arpeggio_engraver::Span_arpeggio_engraver ()
arpeggios_.push_back (info.grob ());
}
+void
+Span_arpeggio_engraver::acknowledge_note_column (Grob_info info)
+{
+ note_columns_.push_back (info.grob ());
+}
+
void
Span_arpeggio_engraver::process_acknowledged ()
{
span_arpeggio_ = make_item ("Arpeggio", SCM_EOL);
span_arpeggio_->set_property ("cross-staff", SCM_BOOL_T);
}
+ if (span_arpeggio_)
+ {
+ for (vsize i = 0; i < note_columns_.size (); i++)
+ Separation_item::add_conditional_item (note_columns_[i], span_arpeggio_);
+ note_columns_.clear ();
+ }
}
void
span_arpeggio_ = 0;
}
arpeggios_.clear ();
+ note_columns_.clear ();
}
#include "translator.icc"
ADD_ACKNOWLEDGER (Span_arpeggio_engraver, arpeggio);
+ADD_ACKNOWLEDGER (Span_arpeggio_engraver, note_column);
ADD_TRANSLATOR (Span_arpeggio_engraver,
/* doc */
"Make arpeggios that span multiple staves.",
r.item_drul_[LEFT] = sp->get_bound (LEFT);
r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
r.add_to_cols ();
+
+ /*
+ We do not know yet if the spanner is going to have a bound that is
+ broken. To account for this uncertainty, we add the rod twice:
+ once for the central column (see above) and once for the left column
+ (see below). As end_rods_ are never used when rods_ are used and vice
+ versa, this rod will only be accessed once for each spacing
+ configuraiton before line breaking. Then, as a grob never exists in
+ both unbroken and broken forms after line breaking, only one of these
+ two rods will be in the column vector used for spacing in
+ simple-spacer.cc get_line_confugration.
+ */
+ if (Item *left_pbp = sp->get_bound (RIGHT)->find_prebroken_piece (LEFT))
+ {
+ r.item_drul_[RIGHT] = left_pbp;
+ r.add_to_cols ();
+ }
}
return SCM_UNSPECIFIED;
{
if (scm_is_string (markup))
return interpret_string (layout_smob, props, markup);
- else if (scm_is_pair (markup))
+ else if (is_markup (markup))
{
SCM func = scm_car (markup);
SCM args = scm_cdr (markup);
- if (!is_markup (markup))
- programming_error ("markup head has no markup signature");
/* 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
bool
Text_interface::is_markup (SCM x)
{
- return (scm_is_string (x)
- || (scm_is_pair (x)
- && SCM_BOOL_F
- != scm_object_property (scm_car (x),
- ly_symbol2scm ("markup-signature"))));
+ return scm_is_string (x)
+ || (scm_is_pair (x)
+ && scm_is_true
+ (scm_object_property (scm_car (x),
+ ly_symbol2scm ("markup-signature")))
+ && scm_is_false
+ (scm_object_property (scm_car (x),
+ ly_symbol2scm ("markup-list-command"))));
}
bool
#(define default-fret-table (make-hash-table 101))
#(define chord-shape-table (make-hash-table 29))
+#(call-after-session
+ (lambda ()
+ (hash-clear! default-fret-table)
+ (hash-clear! chord-shape-table)))
% declarations for standard directions
left = #-1
%% MAKE-HASH-TABLE in GUILE 1.6 takes mandatory size parameter.
#(define musicQuotes (make-hash-table 29))
+#(call-after-session
+ (lambda ()
+ (hash-clear! musicQuotes)))
#(define toplevel-book-handler print-book-with-defaults)
#(define toplevel-bookpart-handler collect-bookpart-for-book)
\consists "Note_heads_engraver"
\consists "Dots_engraver"
\consists "Rest_engraver"
- \consists "Tweak_engraver"
%% switch on to make stem directions interpolate for the
%% center line.
\consists "Text_spanner_engraver"
\consists "Font_size_engraver"
\consists "Axis_group_engraver"
- \consists "Tweak_engraver"
pedalSustainStrings = #'("Ped." "*Ped." "*")
pedalUnaCordaStrings = #'("una corda" "" "tre corde")
(padding . 0.5))
\override TextScript.font-shape = #'italic
\override DynamicLineSpanner.Y-offset = #0
+ \override DynamicLineSpanner.outside-staff-priority = ##f
+ \override DynamicText.outside-staff-priority = ##f
+ \override Hairpin.outside-staff-priority = ##f
\override DynamicText.X-offset =
#(ly:make-simple-closure
`(,+
\consists "Lyric_engraver"
\consists "Extender_engraver"
\consists "Hyphen_engraver"
- \consists "Tweak_engraver"
\consists "Stanza_number_engraver"
\consists "Instrument_name_engraver"
\consists "Font_size_engraver"
\consists "Timing_translator"
\consists "Default_bar_line_engraver"
\consists "Output_property_engraver"
+ \consists "Tweak_engraver"
\consists "System_start_delimiter_engraver"
\consists "Mark_engraver"
\consists "Volta_engraver"
#(define expect-error #f)
#(define output-empty-score-list #f)
#(define output-suffix #f)
-#(hash-clear! default-fret-table)
-#(hash-clear! chord-shape-table)
-#(hash-clear! musicQuotes)
#(use-modules (scm clip-region))
#(use-modules (srfi srfi-1))
%% TODO: using define-music-function in a .scm causes crash.
+absolute =
+#(define-music-function (parser location music)
+ (ly:music?)
+ (_i "Make @var{music} absolute. This does not actually change the
+music itself but rather hides it from surrounding @code{\\relative}
+commands.")
+ (make-music 'RelativeOctaveMusic 'element music))
+
acciaccatura =
#(def-grace-function startAcciaccaturaMusic stopAcciaccaturaMusic
(_i "Create an acciaccatura from the following music expression"))
relative =
#(define-music-function (parser location pitch music)
- (ly:pitch? ly:music?)
- (_i "Make @var{music} relative to @var{pitch}.")
- (ly:make-music-relative! music pitch)
+ ((ly:pitch?) ly:music?)
+ (_i "Make @var{music} relative to @var{pitch}. If @var{pitch} is
+omitted, the first note in @var{music} is given in absolute pitch.")
+ ;; When \relative has no clear decision (can only happen with
+ ;; scales with an even number of steps), it goes down (see
+ ;; pitch.cc). The following formula puts out f for both the normal
+ ;; 7-step scale as well as for a "shortened" scale missing the
+ ;; final b. In either case, a first note of c will end up as c,
+ ;; namely pitch (-1, 0, 0).
+ (ly:make-music-relative! music
+ (or pitch
+ (ly:make-pitch
+ -1
+ (quotient
+ ;; size of current scale:
+ (ly:pitch-steps (ly:make-pitch 1 0))
+ 2))))
(make-music 'RelativeOctaveMusic
'element music))
empty-stencil))
#(define (print-page-number-check-first layout props arg)
- (if (or (not (part-first-page? layout props))
+ (if (or (not (book-first-page? layout props))
(eq? (ly:output-def-lookup layout 'print-first-page-number) #t))
(create-page-number-stencil layout props arg)
empty-stencil))
oddFooterMarkup = \markup {
\column {
\fill-line {
- %% Copyright header field only on first page.
+ %% Copyright header field only on first page in each bookpart.
\on-the-fly #part-first-page \fromproperty #'header:copyright
}
\fill-line {
- %% Tagline header field only on last page.
- \on-the-fly #part-last-page \fromproperty #'header:tagline
+ %% Tagline header field only on last page in the book.
+ \on-the-fly #last-page \fromproperty #'header:tagline
}
}
}
#f)
#(let ((toc-item-list (list)))
+ (call-after-session (lambda () (set! toc-item-list '())))
(set! add-toc-item!
(lambda (markup-symbol text)
(let ((label (gensym "toc")))
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: lilypond 2.17.14\n"
+"Project-Id-Version: lilypond 2.17.16\n"
"Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu."
"lilypond.bugs\n"
-"POT-Creation-Date: 2013-03-10 16:43+0000\n"
+"POT-Creation-Date: 2013-04-13 14:20+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "Running texi2pdf on file %s to detect default page settings.\n"
msgstr ""
-#: convertrules.py:12
+#: convertrules.py:13
#, python-format
msgid "Not smart enough to convert %s."
msgstr ""
-#: convertrules.py:13
+#: convertrules.py:14
msgid "Please refer to the manual for details, and update manually."
msgstr ""
-#: convertrules.py:14
+#: convertrules.py:15
#, python-format
msgid "%s has been replaced by %s"
msgstr ""
-#: convertrules.py:24 lilylib.py:136 warn.cc:223
+#: convertrules.py:25 lilylib.py:136 warn.cc:223
#, c-format, python-format
msgid "warning: %s"
msgstr ""
-#: convertrules.py:49 convertrules.py:94
+#: convertrules.py:50 convertrules.py:95
msgid "\\header { key = concat + with + operator }"
msgstr ""
-#: convertrules.py:56
+#: convertrules.py:57
#, python-format
msgid "deprecated %s"
msgstr ""
-#: convertrules.py:65
+#: convertrules.py:66
msgid "deprecated \\textstyle, new \\key syntax"
msgstr ""
-#: convertrules.py:81 convertrules.py:1855 convertrules.py:2031
-#: convertrules.py:2174 convertrules.py:2505 convertrules.py:2800
-#: convertrules.py:3150 convertrules.py:3384
+#: convertrules.py:82 convertrules.py:1856 convertrules.py:2032
+#: convertrules.py:2175 convertrules.py:2506 convertrules.py:2801
+#: convertrules.py:3151 convertrules.py:3385
msgid "bump version for release"
msgstr ""
-#: convertrules.py:97
+#: convertrules.py:98
msgid "new \\header format"
msgstr ""
-#: convertrules.py:124
+#: convertrules.py:125
msgid "\\translator syntax"
msgstr ""
-#: convertrules.py:175
+#: convertrules.py:176
msgid "\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative"
msgstr ""
-#: convertrules.py:205 convertrules.py:678 convertrules.py:1350
-#: convertrules.py:2317
+#: convertrules.py:206 convertrules.py:679 convertrules.py:1351
+#: convertrules.py:2318
#, python-format
msgid "deprecate %s"
msgstr ""
-#: convertrules.py:279
+#: convertrules.py:280
#, python-format
msgid "deprecate %s "
msgstr ""
-#: convertrules.py:305
+#: convertrules.py:306
msgid "new \\notenames format"
msgstr ""
-#: convertrules.py:321
+#: convertrules.py:322
msgid "new tremolo format"
msgstr ""
-#: convertrules.py:325
+#: convertrules.py:326
msgid "Staff_margin_engraver deprecated, use Instrument_name_engraver"
msgstr ""
-#: convertrules.py:376
+#: convertrules.py:377
msgid "change property definition case (eg. onevoice -> oneVoice)"
msgstr ""
-#: convertrules.py:437
+#: convertrules.py:438
msgid "new \\textscript markup text"
msgstr ""
-#: convertrules.py:509
+#: convertrules.py:510
#, python-format
msgid "identifier names: %s"
msgstr ""
-#: convertrules.py:548
+#: convertrules.py:549
msgid "point-and-click argument changed to procedure."
msgstr ""
-#: convertrules.py:590
+#: convertrules.py:591
msgid "semicolons removed"
msgstr ""
#. 40 ?
-#: convertrules.py:633
+#: convertrules.py:634
#, python-format
msgid "%s property names"
msgstr ""
-#: convertrules.py:703
+#: convertrules.py:704
msgid "automaticMelismata turned on by default"
msgstr ""
-#: convertrules.py:708
+#: convertrules.py:709
msgid "automaticMelismata is turned on by default since 1.5.67."
msgstr ""
-#: convertrules.py:942 convertrules.py:1635 convertrules.py:1889
-#: convertrules.py:2134
+#: convertrules.py:943 convertrules.py:1636 convertrules.py:1890
+#: convertrules.py:2135
#, python-format
msgid "remove %s"
msgstr ""
-#: convertrules.py:977 convertrules.py:980
+#: convertrules.py:978 convertrules.py:981
msgid "cluster syntax"
msgstr ""
-#: convertrules.py:987
+#: convertrules.py:988
msgid "new Pedal style syntax"
msgstr ""
-#: convertrules.py:1246
+#: convertrules.py:1247
msgid ""
"New relative mode,\n"
"Postfix articulations, new text markup syntax, new chord syntax."
msgstr ""
-#: convertrules.py:1259
+#: convertrules.py:1260
msgid "Remove - before articulation"
msgstr ""
-#: convertrules.py:1294
+#: convertrules.py:1295
#, python-format
msgid "%s misspelling"
msgstr ""
-#: convertrules.py:1313
+#: convertrules.py:1314
msgid "Swap < > and << >>"
msgstr ""
-#: convertrules.py:1316
+#: convertrules.py:1317
msgid "attempting automatic \\figures conversion. Check results!"
msgstr ""
-#: convertrules.py:1362
+#: convertrules.py:1363
msgid "Use Scheme code to construct arbitrary note events."
msgstr ""
-#: convertrules.py:1369
+#: convertrules.py:1370
msgid ""
"use symbolic constants for alterations,\n"
"remove \\outputproperty, move ly:verbose into ly:get-option"
msgstr ""
-#: convertrules.py:1394
+#: convertrules.py:1395
#, python-format
msgid ""
"\\outputproperty found,\n"
"as a substitution text."
msgstr ""
-#: convertrules.py:1406
+#: convertrules.py:1407
msgid ""
"The alteration field of Scheme pitches was multiplied by 2\n"
"to support quarter tone accidentals. You must update the following "
"* keySignature settings made with \\property\n"
msgstr ""
-#: convertrules.py:1449
+#: convertrules.py:1450
msgid "removal of automaticMelismata; use melismaBusyProperties instead."
msgstr ""
-#: convertrules.py:1556
+#: convertrules.py:1557
msgid "\\partcombine syntax change to \\newpartcombine"
msgstr ""
-#: convertrules.py:1581
+#: convertrules.py:1582
msgid ""
"Drum notation changes, Removing \\chordmodifiers, \\notenames.\n"
"Harmonic notes. Thread context removed. Lyrics context removed."
msgstr ""
-#: convertrules.py:1585
+#: convertrules.py:1586
msgid "Drums found. Enclose drum notes in \\drummode"
msgstr ""
-#: convertrules.py:1596 convertrules.py:1603 convertrules.py:1614
+#: convertrules.py:1597 convertrules.py:1604 convertrules.py:1615
#, python-format
msgid ""
"\n"
"%s found. Check file manually!\n"
msgstr ""
-#: convertrules.py:1596
+#: convertrules.py:1597
msgid "Drum notation"
msgstr ""
-#: convertrules.py:1655
+#: convertrules.py:1656
msgid "new syntax for property settings:"
msgstr ""
-#: convertrules.py:1681
+#: convertrules.py:1682
msgid "Property setting syntax in \\translator{ }"
msgstr ""
-#: convertrules.py:1720
+#: convertrules.py:1721
msgid "Scheme grob function renaming"
msgstr ""
-#: convertrules.py:1731 convertrules.py:2138 convertrules.py:2142
-#: convertrules.py:2708
+#: convertrules.py:1732 convertrules.py:2139 convertrules.py:2143
+#: convertrules.py:2709
#, python-format
msgid "Use %s\n"
msgstr ""
-#: convertrules.py:1747
+#: convertrules.py:1748
msgid "More Scheme function renaming"
msgstr ""
-#: convertrules.py:1871
+#: convertrules.py:1872
msgid ""
"Page layout has been changed, using paper size and margins.\n"
"textheight is no longer used.\n"
msgstr ""
-#: convertrules.py:1957
+#: convertrules.py:1958
msgid ""
"\\foo -> \\foomode (for chords, notes, etc.)\n"
"fold \\new FooContext \\foomode into \\foo."
msgstr ""
-#: convertrules.py:1995
+#: convertrules.py:1996
msgid ""
"staff size should be changed at top-level\n"
"with\n"
"\n"
msgstr ""
-#: convertrules.py:2015
+#: convertrules.py:2016
msgid "regularize other identifiers"
msgstr ""
-#: convertrules.py:2083
+#: convertrules.py:2084
msgid "\\encoding: smart recode latin1..utf-8. Remove ly:point-and-click"
msgstr ""
-#: convertrules.py:2094
+#: convertrules.py:2095
msgid "LilyPond source must be UTF-8"
msgstr ""
-#: convertrules.py:2097
+#: convertrules.py:2098
msgid "Try the texstrings backend"
msgstr ""
-#: convertrules.py:2100
+#: convertrules.py:2101
#, python-format
msgid "Do something like: %s"
msgstr ""
-#: convertrules.py:2103
+#: convertrules.py:2104
msgid "Or save as UTF-8 in your editor"
msgstr ""
-#: convertrules.py:2153
+#: convertrules.py:2154
msgid "warn about auto beam settings"
msgstr ""
-#: convertrules.py:2157
+#: convertrules.py:2158
msgid "auto beam settings"
msgstr ""
-#: convertrules.py:2158
+#: convertrules.py:2159
msgid ""
"\n"
"Auto beam settings must now specify each interesting moment in a measure\n"
"explicitly; 1/4 is no longer multiplied to cover moments 1/2 and 3/4 too.\n"
msgstr ""
-#: convertrules.py:2271
+#: convertrules.py:2272
msgid "verticalAlignmentChildCallback has been deprecated"
msgstr ""
-#: convertrules.py:2276
+#: convertrules.py:2277
msgid "Remove callbacks property, deprecate XY-extent-callback."
msgstr ""
-#: convertrules.py:2297
+#: convertrules.py:2298
msgid "Use grob closures iso. XY-offset-callbacks."
msgstr ""
-#: convertrules.py:2359
+#: convertrules.py:2360
msgid "foobar -> foo-bar for \\paper, \\layout"
msgstr ""
-#: convertrules.py:2469
+#: convertrules.py:2470
msgid "deprecate \\tempo in \\midi"
msgstr ""
-#: convertrules.py:2522
+#: convertrules.py:2523
msgid "deprecate cautionary-style. Use AccidentalCautionary properties"
msgstr ""
-#: convertrules.py:2535
+#: convertrules.py:2536
msgid "Rename accidental glyphs, use glyph-name-alist."
msgstr ""
-#: convertrules.py:2590
+#: convertrules.py:2591
msgid "edge-text settings for TextSpanner"
msgstr ""
-#: convertrules.py:2591
+#: convertrules.py:2592
#, python-format
msgid ""
"Use\n"
"%s"
msgstr ""
-#: convertrules.py:2624
+#: convertrules.py:2625
msgid "Use the `alignment-offsets' sub-property of\n"
msgstr ""
-#: convertrules.py:2625
+#: convertrules.py:2626
msgid "NonMusicalPaperColumn #'line-break-system-details\n"
msgstr ""
-#: convertrules.py:2626
+#: convertrules.py:2627
msgid "to set fixed distances between staves.\n"
msgstr ""
-#: convertrules.py:2638
+#: convertrules.py:2639
msgid "Use #'style not #'dash-fraction to select solid/dashed lines."
msgstr ""
-#: convertrules.py:2644
+#: convertrules.py:2645
msgid "all settings related to dashed lines"
msgstr ""
-#: convertrules.py:2645
+#: convertrules.py:2646
msgid "Use \\override ... #'style = #'line for solid lines and\n"
msgstr ""
-#: convertrules.py:2646
+#: convertrules.py:2647
msgid "\t\\override ... #'style = #'dashed-line for dashed lines."
msgstr ""
-#: convertrules.py:2682
+#: convertrules.py:2683
msgid ""
"metronomeMarkFormatter uses text markup as second argument,\n"
"fret diagram properties moved to fret-diagram-details."
msgstr ""
-#: convertrules.py:2688
+#: convertrules.py:2689
msgid "metronomeMarkFormatter got an additional text argument.\n"
msgstr ""
-#: convertrules.py:2689
+#: convertrules.py:2690
#, python-format
msgid ""
"The function assigned to Score.metronomeMarkFunction now uses the signature\n"
"%s"
msgstr ""
-#: convertrules.py:2707
+#: convertrules.py:2708
#, python-format
msgid "%s in fret-diagram properties"
msgstr ""
-#: convertrules.py:2751
+#: convertrules.py:2752
msgid "\\put-adjacent argument order"
msgstr ""
-#: convertrules.py:2752
+#: convertrules.py:2753
msgid "Axis and direction now come before markups:\n"
msgstr ""
-#: convertrules.py:2753
+#: convertrules.py:2754
msgid "\\put-adjacent axis dir markup markup."
msgstr ""
-#: convertrules.py:2784
+#: convertrules.py:2785
msgid "re-definition of InnerStaffGroup"
msgstr ""
-#: convertrules.py:2789
+#: convertrules.py:2790
msgid "re-definition of InnerChoirStaff"
msgstr ""
-#: convertrules.py:2799
+#: convertrules.py:2800
msgid "Syntax changes for \\addChordShape and \\chord-shape"
msgstr ""
-#: convertrules.py:2804
+#: convertrules.py:2805
msgid "stringTuning must be added to addChordShape call.\n"
msgstr ""
-#: convertrules.py:2809
+#: convertrules.py:2810
msgid "stringTuning must be added to chord-shape call.\n"
msgstr ""
-#: convertrules.py:2815
+#: convertrules.py:2816
msgid "Remove oldaddlyrics"
msgstr ""
-#: convertrules.py:2819
+#: convertrules.py:2820
msgid ""
"oldaddlyrics is no longer supported. \n"
" Use addlyrics or lyrsicsto instead.\n"
msgstr ""
-#: convertrules.py:2825
+#: convertrules.py:2826
msgid ""
"keySignature property not reversed any more\n"
"MIDI 47: orchestral strings -> orchestral harp"
msgstr ""
-#: convertrules.py:2830
+#: convertrules.py:2831
msgid "The alist for Staff.keySignature is no longer in reversed order.\n"
msgstr ""
-#: convertrules.py:2836
+#: convertrules.py:2837
msgid ""
"\\bar \".\" now produces a thick barline\n"
"ly:hairpin::after-line-breaking -> ly:spanner::kill-zero-spanned-time\n"
"Dash parameters for slurs and ties are now in dash-definition"
msgstr ""
-#: convertrules.py:2842
+#: convertrules.py:2843
msgid "\\bar \".\" now produces a thick barline.\n"
msgstr ""
-#: convertrules.py:2848
+#: convertrules.py:2849
msgid "Dash parameters for slurs and ties are now in 'dash-details.\n"
msgstr ""
-#: convertrules.py:2853
+#: convertrules.py:2854
msgid ""
"Autobeaming rules have changed. override-auto-beam-setting and\n"
"revert-auto-beam-setting have been eliminated.\n"
"template replaced by new `Dynamics' context."
msgstr ""
-#: convertrules.py:2867
+#: convertrules.py:2868
msgid " Autobeam settings are now overriden with \\overrideBeamSettings.\n"
msgstr ""
-#: convertrules.py:2872
+#: convertrules.py:2873
msgid " Autobeam settings are now reverted with \\revertBeamSettings.\n"
msgstr ""
-#: convertrules.py:2878
+#: convertrules.py:2879
msgid ""
" beatGrouping with a specified context must now be accomplished with\n"
" \\overrideBeamSettings.\n"
msgstr ""
-#: convertrules.py:2884
+#: convertrules.py:2885
msgid ""
"alignment-offsets has been changed to alignment-distances: you must now "
"specify the distances between staves rather than the offset of staves.\n"
msgstr ""
-#: convertrules.py:2895
+#: convertrules.py:2896
msgid ""
"Remove obsolete engravers/translators: Note_swallow_translator,\n"
"Rest_swallow_translator, Skip_event_swallow_translator, Swallow_engraver,\n"
"New vertical spacing variables."
msgstr ""
-#: convertrules.py:2926
+#: convertrules.py:2927
msgid ""
"Vertical spacing no longer depends on the Y-extent of a VerticalAxisGroup.\n"
msgstr ""
-#: convertrules.py:2932
+#: convertrules.py:2933
msgid "Unify fetaNumber and fetaDynamic encodings"
msgstr ""
-#: convertrules.py:2937
+#: convertrules.py:2938
msgid "\\RemoveEmpty*StaffContext -> \\*Staff \\RemoveEmptyStaves"
msgstr ""
-#: convertrules.py:2948
+#: convertrules.py:2949
msgid "\\cresc etc. are now postfix operators"
msgstr ""
-#: convertrules.py:2960
+#: convertrules.py:2961
msgid ""
"Eliminate beamSettings, beatLength, \\setBeatGrouping, "
"\\overrideBeamSettings and \\revertBeamSettings.\n"
"\"accordion.accEtcbase\" -> \"accordion.etcbass\""
msgstr ""
-#: convertrules.py:2978
+#: convertrules.py:2979
msgid "Use \\set beamExceptions or \\overrideTimeSignatureSettings.\n"
msgstr ""
-#: convertrules.py:2982
+#: convertrules.py:2983
msgid "Use \\set beamExceptions or \\revertTimeSignatureSettings.\n"
msgstr ""
-#: convertrules.py:2986
+#: convertrules.py:2987
msgid "Use baseMoment, beatStructure, and beamExceptions.\n"
msgstr ""
-#: convertrules.py:2990 convertrules.py:2994
+#: convertrules.py:2991 convertrules.py:2995
msgid "Use baseMoment and beatStructure.\n"
msgstr ""
-#: convertrules.py:2999
+#: convertrules.py:3000
msgid ""
"Woodwind diagrams: Move size, thickness, and graphic from argument list to "
"properties.\n"
"instead."
msgstr ""
-#: convertrules.py:3004
+#: convertrules.py:3005
msgid ""
"Move size, thickness, and graphic to properties. Argument should be just "
"the key list.\n"
msgstr ""
-#: convertrules.py:3012
+#: convertrules.py:3013
msgid ""
"Rename vertical spacing variables.\n"
"Add fretboard-table argument to savePredefinedFretboard."
msgstr ""
-#: convertrules.py:3030
+#: convertrules.py:3031
msgid "Rename vertical spacing grob properties."
msgstr ""
-#: convertrules.py:3046
+#: convertrules.py:3047
msgid "Remove \\paper variables head-separation and foot-separation."
msgstr ""
-#: convertrules.py:3050
+#: convertrules.py:3051
msgid "Adjust settings for top-system-spacing instead.\n"
msgstr ""
-#: convertrules.py:3054
+#: convertrules.py:3055
msgid "Adjust settings for last-bottom-spacing instead.\n"
msgstr ""
-#: convertrules.py:3060
+#: convertrules.py:3061
msgid ""
"Rename space to basic-distance in various spacing alists.\n"
"Remove HarmonicParenthesesItem grob."
msgstr ""
-#: convertrules.py:3067
+#: convertrules.py:3068
msgid "HarmonicParenthesesItem has been eliminated.\n"
msgstr ""
-#: convertrules.py:3068
+#: convertrules.py:3069
msgid "Harmonic parentheses are part of the TabNoteHead grob.\n"
msgstr ""
-#: convertrules.py:3073
+#: convertrules.py:3074
msgid ""
"Remove context from overrideTimeSignatureSettings and "
"revertTimeSignatureSettings.\n"
msgstr ""
-#: convertrules.py:3080
+#: convertrules.py:3081
msgid ""
"Change stringTunings from a list of semitones to a list of pitches.\n"
"Change tenor and baritone ukulele names in string tunings.\n"
"Generate messages for manual conversion of vertical spacing if required."
msgstr ""
-#: convertrules.py:3123
+#: convertrules.py:3124
msgid "Vertical spacing changes might affect user-defined contexts."
msgstr ""
-#: convertrules.py:3129
+#: convertrules.py:3130
msgid "Replace bar-size with bar-extent."
msgstr ""
-#: convertrules.py:3141
+#: convertrules.py:3142
msgid "Woodwind diagrams: Changes to the clarinet diagram."
msgstr ""
-#: convertrules.py:3145
+#: convertrules.py:3146
msgid "Clarinet fingering changed to reflect actual anatomy of instrument.\n"
msgstr ""
-#: convertrules.py:3155
+#: convertrules.py:3156
msgid "Handling of non-automatic footnotes."
msgstr ""
-#: convertrules.py:3159
+#: convertrules.py:3160
msgid ""
"If you are using non-automatic footnotes, make sure to set footnote-auto-"
"numbering = ##f in the paper block.\n"
msgstr ""
-#: convertrules.py:3164
+#: convertrules.py:3165
msgid "Change in internal property for MultiMeasureRest"
msgstr ""
-#: convertrules.py:3168
+#: convertrules.py:3169
msgid ""
"This internal property has been replaced by round-up-to-longer-rest, round-"
"up-exceptions and usable-duration-logs.\n"
msgstr ""
-#: convertrules.py:3173
+#: convertrules.py:3174
msgid ""
"Creation of a Flag grob and moving of certain Stem properties to this grob"
msgstr ""
-#: convertrules.py:3209
+#: convertrules.py:3210
msgid ""
"consistent-broken-slope is now handled through the positions callback.\n"
msgstr ""
-#: convertrules.py:3210
+#: convertrules.py:3211
msgid ""
"input/regression/beam-broken-classic.ly shows how broken beams are now "
"handled.\n"
msgstr ""
-#: convertrules.py:3368
+#: convertrules.py:3369
msgid "beamExceptions controls whole-measure beaming."
msgstr ""
"defaulting to hairpin."
msgstr ""
-#: new-dynamic-engraver.cc:233 slur-proto-engraver.cc:119
+#: new-dynamic-engraver.cc:233 slur-proto-engraver.cc:135
#, c-format
msgid "unterminated %s"
msgstr ""
msgid "cannot find start of piano pedal bracket: `%s'"
msgstr ""
-#: program-option-scheme.cc:235
+#: program-option-scheme.cc:223
#, c-format
msgid "no such internal option: %s"
msgstr ""
msgid "direction of %s invalid: %d"
msgstr ""
+#: slur-proto-engraver.cc:67
+msgid "cannot set break slur with two directions"
+msgstr ""
+
#. We already have an old slur, so give a warning
#. and completely ignore the new slur.
-#: slur-proto-engraver.cc:166
+#: slur-proto-engraver.cc:186
#, c-format
msgid "already have %s"
msgstr ""
-#: slur-proto-engraver.cc:183
+#: slur-proto-engraver.cc:203
#, c-format
msgid "%s without a cause"
msgstr ""
-#: slur-proto-engraver.cc:244
+#: slur-proto-engraver.cc:299
#, c-format
msgid "cannot end %s"
msgstr ""
-#: slur.cc:434
+#: slur.cc:441
#, c-format
msgid "Ignoring grob for slur: %s. avoid-slur not set?"
msgstr ""
msgstr ""
#. TODO: Also print the arguments of the markup!
-#: text-interface.cc:131
+#: text-interface.cc:129
#, c-format
msgid "Cyclic markup detected: %s"
msgstr ""
#. TODO: Also print the arguments of the markup!
-#: text-interface.cc:144
+#: text-interface.cc:142
#, c-format
msgid "Markup depth exceeds maximal value of %d; Markup: %s"
msgstr ""
msgid "Too much lookahead"
msgstr ""
-#: parser.yy:466 parser.yy:734 parser.yy:801
+#: parser.yy:466 parser.yy:755 parser.yy:822
msgid "bad expression type"
msgstr ""
-#: parser.yy:630 parser.yy:1115
+#: parser.yy:651 parser.yy:1150
msgid "not a context mod"
msgstr ""
-#: parser.yy:836
+#: parser.yy:857
msgid "score expected"
msgstr ""
-#: parser.yy:852
+#: parser.yy:873
msgid "\\paper cannot be used in \\score, use \\layout instead"
msgstr ""
-#: parser.yy:876
+#: parser.yy:897
msgid "need \\paper for paper block"
msgstr ""
-#: parser.yy:1024 parser.yy:1035
+#: parser.yy:1045 parser.yy:1067
msgid "unexpected post-event"
msgstr ""
-#: parser.yy:1040
+#: parser.yy:1075
msgid "Ignoring non-music expression"
msgstr ""
-#: parser.yy:1051 parser.yy:2306
+#: parser.yy:1086 parser.yy:2344
msgid "music expected"
msgstr ""
-#: parser.yy:1319
+#: parser.yy:1354
msgid "not a symbol"
msgstr ""
-#: parser.yy:2010 parser.yy:2121 parser.yy:2134 parser.yy:2143
+#: parser.yy:2045 parser.yy:2159 parser.yy:2172 parser.yy:2181
msgid "bad grob property path"
msgstr ""
-#: parser.yy:2101
+#: parser.yy:2139
msgid "only \\consists and \\remove take non-string argument."
msgstr ""
-#: parser.yy:2162
+#: parser.yy:2200
msgid "bad context property path"
msgstr ""
-#: parser.yy:2255 parser.yy:2259 parser.yy:2274
+#: parser.yy:2293 parser.yy:2297 parser.yy:2312
msgid "simple string expected"
msgstr ""
-#: parser.yy:2415
+#: parser.yy:2453
msgid "not a rhythmic event"
msgstr ""
-#: parser.yy:2511 parser.yy:2516 parser.yy:3059
+#: parser.yy:2557
+msgid "post-event expected"
+msgstr ""
+
+#: parser.yy:2566 parser.yy:2571 parser.yy:3114
msgid "have to be in Lyric mode for lyrics"
msgstr ""
-#: parser.yy:2631
+#: parser.yy:2686
msgid "expecting string as script definition"
msgstr ""
-#: parser.yy:2726
+#: parser.yy:2781
msgid "not an articulation"
msgstr ""
-#: parser.yy:2798 parser.yy:2844
+#: parser.yy:2853 parser.yy:2899
#, c-format
msgid "not a duration: %d"
msgstr ""
-#: parser.yy:2861
+#: parser.yy:2916
msgid "bass number expected"
msgstr ""
-#: parser.yy:2975
+#: parser.yy:3030
msgid "have to be in Note mode for notes"
msgstr ""
-#: parser.yy:3034
+#: parser.yy:3089
msgid "have to be in Chord mode for chords"
msgstr ""
-#: parser.yy:3258
+#: parser.yy:3315
msgid "not a markup"
msgstr ""
msgid "invalid character: `%s'"
msgstr ""
-#: lexer.ll:931
+#: lexer.ll:936
#, c-format
msgid "unknown escaped string: `\\%s'"
msgstr ""
-#: lexer.ll:1214
+#: lexer.ll:1232
msgid "non-UTF-8 input"
msgstr ""
-#: lexer.ll:1258
+#: lexer.ll:1276
#, c-format
msgid "file too old: %s (oldest supported: %s)"
msgstr ""
-#: lexer.ll:1259
+#: lexer.ll:1277
msgid "consider updating the input with the convert-ly script"
msgstr ""
-#: lexer.ll:1265
+#: lexer.ll:1283
#, c-format
msgid "program too old: %s (file requires: %s)"
msgstr ""
msgid "missing stencil expression `~S'"
msgstr ""
-#: bar-line.scm:140
+#: bar-line.scm:133
#, scheme-format
msgid "Bar glyph ~a not known. Ignoring."
msgstr ""
-#: bar-line.scm:168
+#: bar-line.scm:161
#, scheme-format
msgid ""
"Annotation '~a' is allowed in the first argument of a bar line definition "
"only."
msgstr ""
-#: bar-line.scm:176
+#: bar-line.scm:169
#, scheme-format
msgid ""
"Replacement '~a' is allowed in the last argument of a bar line definition "
"only."
msgstr ""
-#: bar-line.scm:237
+#: bar-line.scm:230
#, scheme-format
msgid ""
"add-bar-glyph-print-procedure: glyph '~a' has to be a single ASCII character."
msgstr ""
-#: bar-line.scm:802
+#: bar-line.scm:795
#, scheme-format
msgid "No span bar glyph defined for bar glyph '~a'; ignoring."
msgstr ""
msgid "symbol ~S redefined"
msgstr ""
-#: define-event-classes.scm:69
+#: define-event-classes.scm:70
#, scheme-format
msgid "unknown parent class `~a'"
msgstr ""
msgid "no systems found in \\score markup, does it have a \\layout block?"
msgstr ""
-#: define-markup-commands.scm:2768
+#: define-markup-commands.scm:2772
#, scheme-format
msgid "Cannot find glyph ~a"
msgstr ""
-#: define-markup-commands.scm:3194
+#: define-markup-commands.scm:3198
#, scheme-format
msgid "no brace found for point size ~S "
msgstr ""
-#: define-markup-commands.scm:3195
+#: define-markup-commands.scm:3199
#, scheme-format
msgid "defaulting to ~S pt"
msgstr ""
-#: define-markup-commands.scm:3439
+#: define-markup-commands.scm:3443
#, scheme-format
msgid "not a valid duration string: ~a"
msgstr ""
-#: define-markup-commands.scm:3650
+#: define-markup-commands.scm:3654
#, scheme-format
msgid "not a valid duration string: ~a - ignoring"
msgstr ""
-#: define-music-types.scm:772
+#: define-music-types.scm:788
#, scheme-format
msgid "symbol expected: ~S"
msgstr ""
-#: define-music-types.scm:775
+#: define-music-types.scm:791
#, scheme-format
msgid "cannot find music object: ~S"
msgstr ""
-#: define-music-types.scm:794
+#: define-music-types.scm:810
#, scheme-format
msgid "unknown repeat type `~S'"
msgstr ""
-#: define-music-types.scm:795
+#: define-music-types.scm:811
msgid "See define-music-types.scm for supported repeats"
msgstr ""
msgid "Error in beam quanting. Expected ~S 0, found ~S."
msgstr ""
-#: lily-library.scm:331
+#: lily-library.scm:333
msgid "Music unsuitable for context-mod"
msgstr ""
-#: lily-library.scm:386
+#: lily-library.scm:388
#, scheme-format
msgid "Cannot find context-def \\~a"
msgstr ""
-#: lily-library.scm:402
+#: lily-library.scm:404
msgid "Music unsuitable for output-def"
msgstr ""
-#: lily-library.scm:901
+#: lily-library.scm:903
msgid ""
"Find the index between @var{start} and @var{end} (an integer)\n"
"which produces the closest match to @var{target-val} if\n"
"applied to function @var{getter}."
msgstr ""
-#: lily-library.scm:975
+#: lily-library.scm:977
#, scheme-format
msgid "unknown unit: ~S"
msgstr ""
-#: lily-library.scm:1000
+#: lily-library.scm:1002
#, scheme-format
msgid "no \\version statement found, please add~afor future compatibility"
msgstr ""
-#: lily-library.scm:1006
-msgid "old relative compatibility not used"
+#: lily.scm:75
+msgid "call-after-session used after session start"
msgstr ""
-#: lily.scm:63
+#: lily.scm:93
msgid "define-session used after session start"
msgstr ""
-#: lily.scm:311
+#: lily.scm:346
msgid "Using (ice-9 curried-definitions) module\n"
msgstr ""
-#: lily.scm:314
+#: lily.scm:349
msgid "Guile 1.8\n"
msgstr ""
-#: lily.scm:373
+#: lily.scm:408
#, scheme-format
msgid "cannot find: ~A"
msgstr ""
-#: lily.scm:796
+#: lily.scm:831
msgid "Success: compilation successfully completed"
msgstr ""
-#: lily.scm:797
+#: lily.scm:832
msgid "Compilation completed with warnings or errors"
msgstr ""
-#: lily.scm:859
+#: lily.scm:894
#, scheme-format
msgid "job ~a terminated with signal: ~a"
msgstr ""
-#: lily.scm:862
+#: lily.scm:897
#, scheme-format
msgid ""
"logfile ~a (exit ~a):\n"
"~a"
msgstr ""
-#: lily.scm:884 lily.scm:973
+#: lily.scm:919 lily.scm:1008
#, scheme-format
msgid "failed files: ~S"
msgstr ""
-#: lily.scm:964
+#: lily.scm:999
#, scheme-format
msgid "Redirecting output to ~a..."
msgstr ""
-#: lily.scm:983 ps-to-png.scm:66
+#: lily.scm:1018 ps-to-png.scm:66
#, scheme-format
msgid "Invoking `~a'...\n"
msgstr ""
msgid "wrong type for argument ~a. Expecting ~a, found ~s"
msgstr ""
-#: ly-syntax-constructors.scm:180
+#: ly-syntax-constructors.scm:207
#, scheme-format
msgid "Invalid property operation ~a"
msgstr ""
#. TODO: should raise (generic) exception with throw, and catch
#. that in parse-scm.cc
-#: paper.scm:343
+#: paper.scm:347
msgid "Must use #(set-paper-size .. ) within \\paper { ... }"
msgstr ""
blot-diameter))
-(define (layout-line-thickness grob)
- "Get the line thickness of the @var{grob}'s corresponding layout."
- (let* ((layout (ly:grob-layout grob))
- (line-thickness (ly:output-def-lookup layout 'line-thickness)))
-
- line-thickness))
-
(define (staff-symbol-line-count staff)
"Get or compute the number of lines of staff @var{staff}."
(let ((line-count 0))
;;
(c0-position ,integer? "An integer indicating the position of
middle@tie{}C.")
- (chord-dots ,boolean? "If set, remove dots which the
-@code{DotColumn} algorithm would vertically position too far away from
-note heads.")
(circled-tip ,boolean? "Put a circle at start/@/end of
hairpins (al/@/del niente).")
(clip-edges ,boolean? "Allow outward pointing beamlets at the
elements closer together.")
(slope ,number? "The slope of this object.")
(slur-padding ,number? "Extra distance between slur and script.")
+ (snap-radius ,number? "The maximum distance between two objects that
+will cause them to snap to alignment along an axis.")
(space-alist ,list? "A table that specifies distances between
prefatory items, like clef and time-signature. The format is an alist
of spacing tuples: @code{(@var{break-align-symbol} @var{type}
dynamic spanners.")
(all-elements ,ly:grob-array? "An array of all grobs in this line. Its
function is to protect objects from being garbage collected.")
- (arpeggio ,ly:grob? "A pointer to an @code{Arpeggio} object.")
(axis-group-parent-X ,ly:grob? "Containing X@tie{}axis group.")
(axis-group-parent-Y ,ly:grob? "Containing Y@tie{}axis group.")
clef
key-cancellation
key-signature
- staff-bar
time-signature
+ staff-bar
cue-clef
custos)))
(non-musical . #t)
(DotColumn
. (
(axes . (,X))
- (chord-dots . #t)
(direction . ,RIGHT)
(positioning-done . ,ly:dot-column::calc-positioning-done)
(X-extent . ,ly:axis-group-interface::width)
. (
(padding . 0.2)
(positioning-done . ,ly:fingering-column::calc-positioning-done)
+ (snap-radius . 0.3)
(meta . ((class . Item)
(interfaces . (fingering-column-interface))))))
(cue-clef . (extra-space . 1.5))
(first-note . (fixed-space . 2.0))
(right-edge . (extra-space . 0.5))
- (staff-bar . (minimum-space . 2.0))))
+ (staff-bar . (extra-space . 1.0))))
(stencil . ,ly:time-signature::print)
(Y-extent . ,grob::always-Y-extent-from-stencil)
(style . C)
(interpret-markup layout
(prepend-alist-chain 'word-space 0 props)
- (make-line-markup (if (markup-command-list? args)
- args
- (concat-string-args args)))))
+ (make-line-markup
+ (make-override-lines-markup-list
+ (cons 'word-space
+ (chain-assoc-get 'word-space props))
+ (if (markup-command-list? args)
+ args
+ (concat-string-args args))))))
(define (wordwrap-stencils stencils
justify base-space line-width text-dir)
(pair? markup-list?)
"Like @code{\\override}, for markup lists."
(interpret-markup-list layout (cons (list new-prop) props) args))
+
+(define-markup-list-command (map-markup-commands layout props compose args)
+ (procedure? markup-list?)
+ "This applies the function @var{compose} to every markup in
+@var{args} (including elements of markup list command calls) in order
+to produce a new markup list. Since the return value from a markup
+list command call is not a markup list but rather a list of stencils,
+this requires passing those stencils off as the results of individual
+markup calls. That way, the results should work out as long as no
+markups rely on side effects."
+ (let ((key (make-symbol "key")))
+ (catch
+ key
+ (lambda ()
+ ;; if `compose' does not actually interpret its markup
+ ;; argument, we still need to return a list of stencils,
+ ;; created from the single returned stencil
+ (list
+ (interpret-markup layout props
+ (compose
+ (make-on-the-fly-markup
+ (lambda (layout props m)
+ ;; here all effects of `compose' on the
+ ;; properties should be visible, so we
+ ;; call interpret-markup-list at this
+ ;; point of time and harvest its
+ ;; stencils
+ (throw key
+ (interpret-markup-list
+ layout props args)))
+ (make-null-markup))))))
+ (lambda (key stencils)
+ (map
+ (lambda (sten)
+ (interpret-markup layout props
+ (compose (make-stencil-markup sten))))
+ stencils)))))
(string-downcase
(car (string-tokenize (utsname:sysname (uname)))))))
+;;
+;; Session-handling variables and procedures.
+;;
+;; A "session" corresponds to one .ly file processed on a LilyPond
+;; command line. Every session gets to see a reasonably fresh state
+;; of LilyPond and should work independently from previous files.
+;;
+;; Session management relies on cooperation, namely the user not
+;; trying to change variables and data structures internal to
+;; LilyPond. It is not proof against in-place modification of data
+;; structures (as they are just reinitialized with the original
+;; identities), and it is not proof against tampering with internals.
+;;
+;; As a consequence, session management is not sufficient for
+;; separating multiple independent .ly files in "-dsafe" mode: you
+;; should give each its own LilyPond process when reliable separation
+;; is mandatory.
+;;
+;; For standard tasks and programming practices, multiple sessions in
+;; the same LilyPond job should work reasonably independently and
+;; without "bleed-over" while still loading and compiling the
+;; relevant .scm and .ly files only once.
+;;
+
(define lilypond-declarations '())
+(define after-session-hook (make-hook))
+
+(define-public (call-after-session thunk)
+ (if (ly:undead? lilypond-declarations)
+ (ly:error (_ "call-after-session used after session start")))
+ (add-hook! after-session-hook thunk #t))
(defmacro-public define-session (name value)
"This defines a variable @var{name} with the starting value
(define (session-terminate)
(if (ly:undead? lilypond-declarations)
- (for-each
- (lambda (p) (variable-set! (cadr p) (cddr p)))
- (ly:get-undead lilypond-declarations))))
+ (begin
+ (for-each
+ (lambda (p) (variable-set! (cadr p) (cddr p)))
+ (ly:get-undead lilypond-declarations))
+ (run-hook after-session-hook))))
+
+(define lilypond-interfaces #f)
(define-public (session-initialize thunk)
"Initialize this session. The first session in a LilyPond run is
(if (ly:undead? lilypond-declarations)
(begin
+ (module-use-interfaces! (current-module) (reverse lilypond-interfaces))
(for-each
(lambda (p)
(let ((var (cadr p))
(ly:get-undead lilypond-declarations)))
(begin
(thunk)
+ (set! lilypond-interfaces
+ (filter (lambda (m) (eq? 'interface (module-kind m)))
+ (module-uses (current-module))))
(let ((decl (map! (lambda (v)
(cons* #f v (variable-ref v)))
lilypond-declarations)))
;; TODO: use separate module for syntax
;; constructors. Also create wrapper around the constructor?
(defmacro define-ly-syntax (args . body)
- `(define-public ,args ,(cons 'begin body)))
+ `(define-public ,args ,@body))
;; A ly-syntax constructor takes two extra parameters, parser and
;; location. These are mainly used for reporting errors and
(if create-new (set! (ly:music-property csm 'create-new) #t))
csm))
+(define-ly-syntax (composed-markup-list parser location commands markups)
+;; `markups' being a list of markups, eg (markup1 markup2 markup3),
+;; and `commands' a list of commands with their scheme arguments, in reverse order,
+;; eg: ((italic) (raise 4) (bold)), maps the commands on each markup argument, eg:
+;; ((bold (raise 4 (italic markup1)))
+;; (bold (raise 4 (italic markup2)))
+;; (bold (raise 4 (italic markup3))))
+
+ (define (compose arg)
+ (fold
+ (lambda (cmd prev) (append cmd (list prev)))
+ arg
+ commands))
+ (let loop ((markups markups) (completed '()))
+ (cond ((null? markups) (reverse! completed))
+ ((markup? (car markups))
+ (loop (cdr markups)
+ (cons (compose (car markups)) completed)))
+ (else
+ (call-with-values
+ (lambda () (break! markup? markups))
+ (lambda (complex rest)
+ (loop rest
+ (reverse!
+ (make-map-markup-commands-markup-list
+ compose complex) completed))))))))
+
(define-ly-syntax (property-operation parser location ctx music-type symbol . args)
(let* ((props (case music-type
((PropertySet) (list 'value (car args)))
(string->symbol (format #f "~a-markup-list" code)))))
(and proc (markup-list-function? proc)
(cons proc (markup-command-signature proc)))))
-
-;;;;;;;;;;;;;;;;;;;;;;
-;;; used in parser.yy to map a list of markup commands on markup arguments
-(define-public (map-markup-command-list commands markups)
- "`markups' being a list of markups, eg (markup1 markup2 markup3),
-and `commands' a list of commands with their scheme arguments, in reverse order,
-eg: ((italic) (raise 4) (bold)), maps the commands on each markup argument, eg:
- ((bold (raise 4 (italic markup1)))
- (bold (raise 4 (italic markup2)))
- (bold (raise 4 (italic markup3))))
-"
- (map-in-order (lambda (arg)
- (let ((result arg))
- (for-each (lambda (cmd)
- (set! result (append cmd (list result))))
- commands)
- result))
- markups))
(define-public interpret-markup ly:text-interface::interpret-markup)
(define-public (interpret-markup-list layout props markup-list)
- (let ((stencils (list)))
- (for-each (lambda (m)
- (set! stencils
- (if (markup-command-list? m)
- (append! (reverse! (apply (car m) layout props (cdr m)))
- stencils)
- (cons (interpret-markup layout props m) stencils))))
- markup-list)
- (reverse! stencils)))
+ ;; This relies on the markup list returned by a markup list command
+ ;; to be modifiable
+ (reverse!
+ (fold
+ (lambda (m prev)
+ (if (markup-command-list? m)
+ (reverse! (apply (car m) layout props (cdr m)) prev)
+ (cons (interpret-markup layout props m) prev)))
+ '()
+ markup-list)))
(define-public (prepend-alist-chain key val chain)
(cons (acons key val (car chain)) (cdr chain)))
(define-public grob::always-Y-extent-from-stencil
(ly:make-unpure-pure-container ly:grob::stencil-height))
+(define-public (layout-line-thickness grob)
+ "Get the line thickness of the @var{grob}'s corresponding layout."
+ (let* ((layout (ly:grob-layout grob))
+ (line-thickness (ly:output-def-lookup layout 'line-thickness)))
+
+ line-thickness))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; beam slope
'(bound-details left padding)
(+ my-padding script-padding)))))))
+(define-public ((elbowed-hairpin coords mirrored?) grob)
+ "Create hairpin based on a list of @var{coords} in @code{(cons x y)}
+form. @code{x} is the portion of the width consumed for a given line
+and @code{y} is the portion of the height. For example,
+@code{'((0.3 . 0.7) (0.8 . 0.9) (1.0 . 1.0))} means that at the point
+where the hairpin has consumed 30% of its width, it must
+be at 70% of its height. Once it is to 80% width, it
+must be at 90% height. It finishes at
+100% width and 100% height. @var{mirrored?} indicates if the hairpin
+is mirrored over the Y-axis or if just the upper part is drawn.
+Returns a function that accepts a hairpin grob as an argument
+and draws the stencil based on its coordinates.
+@lilypond[verbatim,quote]
+#(define simple-hairpin
+ (elbowed-hairpin '((1.0 . 1.0)) #t))
+
+\\relative c' {
+ \\override Hairpin #'stencil = #simple-hairpin
+ a\\p\\< a a a\\f
+}
+@end lilypond
+"
+ (define (pair-to-list pair)
+ (list (car pair) (cdr pair)))
+ (define (normalize-coords goods x y)
+ (map
+ (lambda (coord)
+ (cons (* x (car coord)) (* y (cdr coord))))
+ goods))
+ (define (my-c-p-s points thick decresc?)
+ (make-connected-path-stencil
+ points
+ thick
+ (if decresc? -1.0 1.0)
+ 1.0
+ #f
+ #f))
+ ; outer let to trigger suicide
+ (let ((sten (ly:hairpin::print grob)))
+ (if (grob::is-live? grob)
+ (let* ((decresc? (eq? (ly:grob-property grob 'grow-direction) LEFT))
+ (thick (ly:grob-property grob 'thickness 0.1))
+ (thick (* thick (layout-line-thickness grob)))
+ (xex (ly:stencil-extent sten X))
+ (lenx (interval-length xex))
+ (yex (ly:stencil-extent sten Y))
+ (leny (interval-length yex))
+ (xtrans (+ (car xex) (if decresc? lenx 0)))
+ (ytrans (car yex))
+ (uplist (map pair-to-list
+ (normalize-coords coords lenx (/ leny 2))))
+ (downlist (map pair-to-list
+ (normalize-coords coords lenx (/ leny -2)))))
+ (ly:stencil-translate
+ (ly:stencil-add
+ (my-c-p-s uplist thick decresc?)
+ (if mirrored? (my-c-p-s downlist thick decresc?) empty-stencil))
+ (cons xtrans ytrans)))
+ '())))
+
+(define-public flared-hairpin
+ (elbowed-hairpin '((0.95 . 0.4) (1.0 . 1.0)) #t))
+
+(define-public constante-hairpin
+ (elbowed-hairpin '((1.0 . 0.0) (1.0 . 1.0)) #f))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; lyrics
+\version "2.16.0"
+
\paper {
#(set-paper-size "A4")
}
#
# -n means build a new regtest set - the PNGs go in the new-regtest-results
# directory
+#
+# -p uses PDF and the poppler library via pdftocairo for generating bitmaps,
+# simulating the output for Evince and other previewers using poppler.
+# pdftocairo may be contained in the poppler-utils package.
+#
+# -r can be used for specifying a rendering resolution. This
+# defaults to 101 for poppler and 300 for Ghostscript from PDF.
+#
+# -g uses Ghostscript for rendering a bitmap version from the PDF,
+# simulating the output from printing PDF files on a GNU system, so
+# use a resolution appropriate for print. Antialiasing is not enabled.
+#
+# -d changes the Ghostscript device used for creating PNG files
+# (usually png16m, but with -g you might prefer fewer colors for size
+# reasons, like png16).
+
+cpu_count=${CPU_COUNT:-1}
+backend_opt='--png ${resolution:+=-dresolution=$resolution} ${gsdevice:+=-dpixmap-format=$gsdevice}'
+resolution=
+gsdevice=
+
+png_generate()
+{
+ :
+}
-cpu_count=1
+while getopts "j:onpr:g" opts; do
+ case $opts in j)
+ cpu_count=$OPTARG;;
+
+ o)
+ file_loc="old-regtest-results";;
-while getopts "j:on" opts; do
- if [ "$opts" = "j" ]; then
- cpu_count=$OPTARG
- fi
+ p)
+ backend_opt="--pdf"
+ png_generate()
+ {
+ for i
+ do pdftocairo -png -r ${resolution:-101} -q "$i" &&
+ rm "$i"
+ done
+ };;
- if [ "$opts" = "o" ]; then
- file_loc="old-regtest-results"
- fi
+ n)
+ file_loc="new-regtest-results"
+ do_compare="y";;
- if [ "$opts" = "n" ]; then
- file_loc="new-regtest-results"
- do_compare="y"
- fi
+ r)
+ resolution=$OPTARG;;
+ g)
+ backend_opt="--pdf"
+ png_generate()
+ {
+ for i
+ do
+ gs -sDEVICE=${gsdevice:-png16m} -q -dNOPAUSE \
+ -r${resolution:-300} -dNOPLATFONTS \
+ -dTextAlphaBits=1 -dGraphicsAlphaBits=1 \
+ -sOutputFile="${i%.pdf}-%d.png" "$i" -c quit &&
+ rm "$i"
+ done
+ };;
+ esac
done
if [ -z "$file_loc" ]; then
mkdir -p $LILYPOND_BUILD_DIR/out-png-check/$file_loc
cd $LILYPOND_BUILD_DIR/out-png-check/$file_loc
ls $LILYPOND_GIT/input/regression/*.ly > dir.txt
-$LILYPOND_BUILD_DIR/out/bin/lilypond --png --relocate \
+$LILYPOND_BUILD_DIR/out/bin/lilypond $(eval echo $backend_opt) --relocate \
-dinclude-settings=$LILYPOND_GIT/scripts/auxiliar/NoTagline.ly \
-djob-count=$cpu_count -dread-file-list "dir.txt"
+png_generate *.pdf
rm -rf dir.txt
rm -rf *.log
return str (val2) # TODO
class key_signature_formatter (formatter):
def format_vals (self, val1, val2):
- return str (val2) # TODO
+ key_names = ['F', 'C', 'G', 'D', 'A', 'E', 'B']
+ key = (((ord(val2[0])+128)%256)-128) + ord(val2[1])*3 + 1;
+ return (key_names[key%7] + (key/7) * "is" + (-(key/7)) * "es"
+ + " " + ['major','minor'][ord(val2[1])])
class channel_formatter (formatter):
def __init__ (self, txt, ch):
formatter.__init__ (self, txt)