ifeq ($(out),www)
INFO_IMAGES_DIR = lilypond
-DEST_INFO_IMAGES_SUBDIR = Documentation/
+DEST_INFO_IMAGES_SUBDIR = Documentation
endif
include $(depth)/make/stepmake.make
@end ignore
+@item
+Black mensural notation has minimal support.
+
+@item
+Support for obliqua shapes within white mensural ligatures enhanced.
+@lilypond
+\context MensuralStaff
+{
+ \clef "petrucci-c3"
+ \[
+ \override NoteHead #'style = #'semipetrucci
+ c'\maxima
+ \override NoteHead #'style = #'blackpetrucci
+ a\breve
+ \revert NoteHead #'style
+ \override NoteHead #'ligature-flexa = ##t
+ \override NoteHead #'flexa-width = #3
+ g
+ g'
+ \override NoteHead #'flexa-width = #5
+ c'
+ d'
+ \revert NoteHead #'style
+ c'\longa
+ \]
+}
+@end lilypond
+
@item
Compound time signatures are now supported by the @code{\compoundMeter} command,
which can be used instead of @code{\time}:
Guide, node Updating translation committishes.
@end ignore
-@c \version "2.13.36"
+@c \version "2.13.48"
@c Translators: Till Paala
\override Staff.StaffSymbol #'line-positions = #'(-2 3)
% This is necessary; if not entered, the barline would be too short!
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
}
\new DrumStaff {
@end lilypond
In diesem Spezialfalls muss die Länge der Taktlinie mit
-@code{\override Staff.BarLine #'bar-size #number} angepasst werden.
+@code{\override Staff.BarLine #'bar-extent #'(von . zu)} angepasst werden.
Andernfalls wäre sie zu kurz. Die Position der beiden Linien muss
auch definiert werden.
tambustaff = {
\override Staff.StaffSymbol #'line-positions = #'( 0 )
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Tambourine"
}
tamtamstaff = {
\override Staff.StaffSymbol #'line-positions = #'( 0 )
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Tamtam"
}
bellstaff = {
\override DrumStaff.StaffSymbol #'line-positions = #'(-2 3)
\set DrumStaff.drumStyleTable = #(alist->hash-table mydrums)
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Different Bells"
}
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.13.36"
+@c \version "2.13.48"
@node Percusión
@section Percusión
\override Staff.StaffSymbol #'line-positions = #'(-2 3)
% This is necessary; if not entered, the barline would be too short!
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
}
\new DrumStaff {
@end lilypond
Observe que en este caso especial se debe alterar la longitud de la
-línea divisoria con @code{\override Staff.BarLine #'bar-size #number}.
+línea divisoria con @code{\override Staff.BarLine #'bar-extent #'(de . a)}.
En caso contrario resulta demasiado corta. También debe definir las
posiciones de las dos líneas del pentagrama. Para más información
sobre estos delicados asuntos, consulte @ref{El símbolo del pentagrama}.
tambustaff = {
\override Staff.StaffSymbol #'line-positions = #'( 0 )
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Tambourine"
}
tamtamstaff = {
\override Staff.StaffSymbol #'line-positions = #'( 0 )
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Tamtam"
}
bellstaff = {
\override DrumStaff.StaffSymbol #'line-positions = #'(-2 3)
\set DrumStaff.drumStyleTable = #(alist->hash-table mydrums)
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Different Bells"
}
@set FDL
@include macros.itexi
-@afourpaper
@c don't remove this comment.
@ignore
@omfcreator Han-Wen Nienhuys, Jan Nieuwenhuizen
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.13.36"
+@c \version "2.13.48"
@c Translators: Valentin Villenave
@c Translation checkers: Jean-Charles Malahieude, John Mandereau
@lilypond[ragged-right,verbatim]
\new ChordNames \with {
- \override BarLine #'bar-size = #4
+ \override BarLine #'bar-extent = #'(-2 . 2)
\consists Bar_engraver
\consists "Volta_engraver"
}
@end lilypond
@item
-petrucci style F clef
+petrucci style F clefs, for use on different staff lines
+(the example shows the 3rd staff line F clef)
@tab
-@code{petrucci-f}
+@code{petrucci-f3}, @code{petrucci-f4},@*
+@code{petrucci-f5}
@tab
@lilypond[fragment,relative=1,notime]
- \clef "petrucci-f"
+ \clef "petrucci-f3"
\override NoteHead #'style = #'mensural
c
@end lilypond
@ref{Time signature}.
@knownissues
-Ratios of note durations do not change with the time signature. For
+Ratios of note durations cannot change with the time signature,
+as those are not constant. For
example, the ratio of 1@tie{}breve = 3@tie{}semibreves
-(@emph{tempus perfectum}) must be made by hand, by setting
+(@emph{tempus perfectum}) can be made by hand, by setting
@example
breveTP = #(ly:make-duration -1 0 3 2)
@code{default} style may be chosen. This is accomplished by setting
the @code{style} property of the @code{NoteHead} object to
@code{baroque}, @code{neomensural}, @code{mensural} or
-@code{petrucci}.
+@code{petrucci}, @code{blackpetrucci}, @code{semipetrucci}.
The @code{baroque} style differs from the @code{default} style by:
@itemize
-@item Providing a @code{maxima} notehead, and
+@item Providing a @code{maxima} note head, and
@item Using a square shape for @code{\breve} note heads.
@end itemize
@item Centering the stems on the note heads.
@end itemize
+The @code{blackpetrucci} style produces note heads usable in black
+mensural notation or coloratio sections in white mensural notation.
+Because note head style does not influence flag count, in
+this style a semiminima should be notated as @code{a8*2}, not
+@code{a4}, otherwise it will look like a minima.
+The multiplyer can be different if coloratio is used e.g. to notate
+triplets.
+
+Use @code{semipetrucci} style to draw half-colored
+note heads (breves, longas and maximas).
+
The following example demonstrates the @code{petrucci} style:
\autoBeamOff
\override NoteHead #'style = #'petrucci
a'\maxima a'\longa a'\breve a'1 a'2 a'4 a'8 a'16 a'
-
+\override NoteHead #'style = #'semipetrucci
+a'\breve*5/6
+\override NoteHead #'style = #'blackpetrucci
+a'8*4/3 a'
+\override NoteHead #'style = #'petrucci
+a'\longa
@end lilypond
@rlsr{Ancient notation}.
+@knownissues
+The glyph for the maxima rest in mensural style is actually a perfect
+longa rest; use two (or three) longa rests to print a maxima rest.
+Longa rests are not grouped automatically, so have to be done manually by
+using pitched rests.
+
+
@node Mensural accidentals and key signatures
@unnumberedsubsubsec Mensural accidentals and key signatures
This is not only required for correct MIDI output, but also allows for
automatic transcription of the ligatures.
+At certain places two consecutive notes can be represented either as
+two squares or as an oblique parallelogram (flexa shape). In such
+cases the default is the two squares, but a flexa can be required by
+setting the @code{ligature-flexa} property of the @emph{second} note
+head. The length of a flexa can be set by the note head property
+@code{flexa-width}.
+
For example,
@c @example
\transpose c c' {
\set Score.timing = ##f
\set Score.defaultBarType = "empty"
- \override NoteHead #'style = #'neomensural
- \override Staff.TimeSignature #'style = #'neomensural
+ \override NoteHead #'style = #'petrucci
+ \override Staff.TimeSignature #'style = #'mensural
\clef "petrucci-g"
\[ c'\maxima g \]
- \[ d\longa c\breve f e d \]
+ \[ d\longa
+ \override NoteHead #'ligature-flexa = ##t
+ \once \override NoteHead #'flexa-width = #3.2
+ c\breve f e d \]
\[ c'\maxima d'\longa \]
\[ e'1 a g\breve \]
}
\transpose c c' {
\set Score.timing = ##f
\set Score.defaultBarType = "empty"
- \override NoteHead #'style = #'neomensural
- \override Staff.TimeSignature #'style = #'neomensural
+ \override NoteHead #'style = #'petrucci
+ \override Staff.TimeSignature #'style = #'mensural
\clef "petrucci-g"
\[ c'\maxima g \]
- \[ d\longa c\breve f e d \]
+ \[ d\longa
+ \override NoteHead #'ligature-flexa = ##t
+ \once \override NoteHead #'flexa-width = #3.2
+ c\breve f e d \]
\[ c'\maxima d'\longa \]
\[ e'1 a g\breve \]
}
@knownissues
Horizontal spacing of ligatures is poor.
-
+Accidentals may collide with previous notes.
@node Typesetting Gregorian chant
@subsection Typesetting Gregorian chant
@c Add example of white note heads:
@c In the french baroque some composers used white note heads in slow pieces,
@c mainly in 3/2-time. A quarter looks there like a eighth with a white
-@c notehead. (Franz-Rudolf Kuhnen)
+@c note head. (Franz-Rudolf Kuhnen)
@c TODO Add example of this:
@c I was referring to e.g. notated a8. a16, which should, if I
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.13.36"
+@c \version "2.13.48"
@node Percussion
@section Percussion
\override Staff.StaffSymbol #'line-positions = #'(-2 3)
% This is necessary; if not entered, the barline would be too short!
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
}
\new DrumStaff {
@end lilypond
Note that in this special case the length of the barline must
-altered with @code{\override Staff.BarLine #'bar-size #number}.
+altered with @code{\override Staff.BarLine #'bar-extent #'(from . to)}.
Otherwise it would be too short. And you have also to define the
positions of the two stafflines. For more information about these
delicate things have a look at @ref{Staff symbol}.
tambustaff = {
\override Staff.StaffSymbol #'line-positions = #'( 0 )
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Tambourine"
}
tamtamstaff = {
\override Staff.StaffSymbol #'line-positions = #'( 0 )
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Tamtam"
}
bellstaff = {
\override DrumStaff.StaffSymbol #'line-positions = #'(-2 3)
\set DrumStaff.drumStyleTable = #(alist->hash-table mydrums)
- \override Staff.BarLine #'bar-size = #3
+ \override Staff.BarLine #'bar-extent = #'(-1.5 . 1.5)
\set DrumStaff.instrumentName = #"Different Bells"
}
-depth = ../../../
+depth = ../../..
PDF_FILES = $(call src-wildcard,*.pdf)
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "keyboards"
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.12.2"
+\version "2.13.48"
\header {
lsrtags = "chords"
} % begin verbatim
\new ChordNames \with {
- \override BarLine #'bar-size = #4
+ \override BarLine #'bar-extent = #'(-2 . 2)
\consists "Bar_engraver"
}
\chordmode {
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.12.2"
+\version "2.13.48"
\header {
lsrtags = "rhythms, percussion"
\new DrumStaff \with {
drumStyleTable = #timbales-style
\override StaffSymbol #'line-count = #2
- \override BarLine #'bar-size = #2
+ \override BarLine #'bar-extent = #'(-1 . 1)
} <<
\set Staff.instrumentName = #"timbales"
\timb
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "staff-notation, vocal-music"
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.12.2"
+\version "2.13.48"
\header {
lsrtags = "ancient-notation"
\override NoteHead #'style = #'vaticana.vupes
g f
\override NoteHead #'style = #'vaticana.linea.punctum
- \once \override Staff.BarLine #'bar-size = #2.0 \bar "|"
+ \once \override Staff.BarLine #'bar-extent = #'(-1 . 1) \bar "|"
% \break % 3 (8*1)
es d
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "fretted-strings, tweaks-and-overrides"
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "midi"
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "expressive-marks"
"
doctitlees = "Plantilla para himnos"
+
%% Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
texidocde = "
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "keyboards, percussion, fretted-strings, template"
"
doctitlees = "Partcombine y autoBeamOff"
+
%% Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
texidocde = "
"
doctitlede = "Partcombine und autoBeamOff"
+
%% Translation of GIT committish: e1a149d0cc60b02e86209387958f4028567dd366
texidocfr = "
Le fonction @code{@bs{}autoBeamOff} dans le cadre d'un
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "vocal-music, keyboards, template"
%% Do not edit this file; it is automatically
%% generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
-\version "2.13.46"
+\version "2.13.48"
\header {
lsrtags = "staff-notation, tweaks-and-overrides, breaks"
@include macros.itexi
@include weblinks.itexi
-@afourpaper
@c don't remove this comment.
@ignore
dist-toplevel-txt-files: top-doc
-mkdir -p $(distdir)
- ln $(TOPDOC_TXT_FILES) $(distdir)/
- ln $(top-src-dir)/stepmake/aclocal.m4 $(distdir)/
+ ln $(TOPDOC_TXT_FILES) $(distdir)
+ ln $(top-src-dir)/stepmake/aclocal.m4 $(distdir)
info:
$(foreach d, $(INFO_DIRECTORIES),$(MAKE) -C $(d) out=www info && ) true
# installed in non-recursing target from TOP-SRC-DIR
install-WWW:
-$(INSTALL) -m 755 -d $(DESTDIR)$(webdir)
- rsync -rl --exclude='*.signature' $(outdir)/offline-root/ $(DESTDIR)$(webdir)
+ rsync -rl --exclude='*.signature' $(outdir)/offline-root $(DESTDIR)$(webdir)
$(MAKE) -C Documentation omf-local-install
install-info-WWW:
rm -f $(tree-share-prefix)/fonts/type1/* && \
cd $(tree-share-prefix)/fonts/otf && \
ln -s ../../../../../../mf/$(outconfbase)/*.otf .
- -cd $(tree-share-prefix)/fonts/ && \
+ -cd $(tree-share-prefix)/fonts && \
ln -s ../../../../../mf/$(outconfbase)/fonts.conf .
-cd $(tree-share-prefix)/fonts/svg && \
ln -s ../../../../../../mf/$(outconfbase)/*.svg .
@echo
@echo ' grep sourcefilename `grep -L systems.texi out/lybook-testdb/*/*log|sed s/log/ly/g`'
@echo
- $(MAKE) -C input/regression/ out=test local-test
+ $(MAKE) -C input/regression out=test local-test
$(MAKE) -C input/regression/musicxml out=test local-test
$(MAKE) -C input/regression/abc2ly out=test local-test
$(MAKE) -C input/regression/lilypond-book out=test local-test
fi
$(MAKE)
$(MAKE) test
- $(MAKE) out=test -C input/regression/ local-test-baseline
+ $(MAKE) out=test -C input/regression local-test-baseline
$(MAKE) out=test -C input/regression/musicxml local-test-baseline
$(MAKE) out=test -C input/regression/abc2ly local-test-baseline
$(MAKE) out=test -C input/regression/lilypond-book local-test-baseline
local-check: test
rm -rf $(RESULT_DIR)
mkdir -p $(RESULT_DIR)
- $(buildscript-dir)/output-distance --create-images --output-dir $(RESULT_DIR) input/regression/out-test-baseline input/regression/out-test/
+ $(buildscript-dir)/output-distance --create-images --output-dir $(RESULT_DIR) input/regression/out-test-baseline input/regression/out-test
@find input ly -name '*.ly' -print |grep -v 'out.*/' | xargs grep '\\version' -L | grep -v "standard input" |sed 's/^/**** Missing version: /g'
$(MAKE) check
test-clean: test-snippets-clean
- $(MAKE) -C input/regression/ out=test clean
+ $(MAKE) -C input/regression out=test clean
snippets-clean:
rm -rf out/lybook-db
at (RIGHT) = max (at (RIGHT), p);
}
T length () const;
+
+ // Returns RIGHT - LEFT, even if the interval is empty.
T delta () const;
void set_empty ();
void set_full ();
--- /dev/null
+\header {
+ texidoc = "Bar line extent can be customised and the customised value
+ must be respected when staff symbol is changed temporarily (e.g. to
+ simulate ledger lines of renaissance prints and manuscripts);
+ moreover, span bars should not enter the staves."
+}
+
+
+\version "2.13.48"
+
+ledgerUp =
+{
+ s2
+ \stopStaff
+ \override Staff.StaffSymbol #'line-positions = #'(-4 -2 0 2 4 6)
+ \startStaff
+ s2
+ \noBreak
+ s2
+ \stopStaff
+ \revert Staff.StaffSymbol #'line-positions
+ \startStaff
+ s2
+}
+
+ledgerDown =
+{
+ s2
+ \stopStaff
+ \override Staff.StaffSymbol #'line-positions = #'(-6 -4 -2 0 2 4)
+ \startStaff
+ s1
+ \stopStaff
+ \revert Staff.StaffSymbol #'line-positions
+ \startStaff
+ s2
+}
+
+\new StaffGroup
+<<
+ \new Staff \with
+ {
+ \override BarLine #'bar-extent = #'(-1 . 1.5)
+ }
+ {
+ \ledgerUp \ledgerDown
+ s1*4
+ s1*4
+ \ledgerUp \ledgerDown
+ \ledgerUp \ledgerDown
+ \ledgerUp \ledgerDown
+ \ledgerUp \ledgerDown
+ s1*4
+ s1*4
+ }
+
+ \new Staff \with
+ {
+ \override BarLine #'bar-extent = #'(0 . 0)
+ }
+ {
+ s1*4
+ s1*4
+ \ledgerUp \ledgerDown
+ \ledgerUp \ledgerDown
+ \ledgerDown \ledgerUp
+ s1*4
+ s1*4
+ \ledgerUp \ledgerDown
+ \ledgerUp \ledgerDown
+ }
+
+ \new Staff \with
+ {
+ \override BarLine #'bar-extent = #'(-2 . 0)
+ }
+ {
+ s1*4
+ \ledgerUp \ledgerDown
+ s1*4
+ s1*4
+ s1*4
+ \ledgerUp \ledgerDown
+ \ledgerDown \ledgerUp
+ \ledgerUp \ledgerDown
+ \ledgerDown \ledgerUp
+ }
+>>
}
-\version "2.12.0"
+\version "2.13.48"
drh = \drummode { cymc4.^"crash" hhc16^"h.h." hh \repeat "unfold" 5 {hhc8 hho hhc8 hh16 hh} hhc4 r4 r2 }
drl = \drummode {\repeat "unfold" 3 {bd4 sn8 bd bd4 << bd ss >> } bd8 tommh tommh bd toml toml bd tomfh16 tomfh }
\new DrumStaff \with {
drumStyleTable = #timbales-style
\override StaffSymbol #'line-count = #2
- \override BarLine #'bar-size = #2
+ \override BarLine #'bar-extent = #'(-1 . 1)
} <<
\set Staff.instrumentName = "timbales"
\timb
staves synchronized with the notes."
}
-\version "2.12.0"
+\version "2.13.48"
skips =
{
\consists "Grid_point_engraver"
\override VerticalAxisGroup #'minimum-Y-extent = #'(-4 . 4)
gridInterval = #(ly:make-moment 1 8)
- \override BarLine #'bar-size = #0.05
+ \override BarLine #'bar-extent = #'(-0.025 . 0.025)
}
\context {
\StaffGroup
--- /dev/null
+\header {
+
+ texidoc = "Key signatures get the required amount of horizontal space."
+
+}
+\version "2.13.47"
+<<
+ \new Staff {
+ \voiceOne
+ \key f\minor
+ f'4 f' f' f'
+ \key b\major
+ e''8 e'' e''4 e''2
+ }
+ \new Staff {
+ R1 \bar "||"
+ R1
+ }
+>>
-\version "2.12.0"
+\version "2.13.48"
\header{
texidoc="
\context Lyrics \with {
\consists "Bar_engraver"
\consists "Separating_line_group_engraver"
- \override BarLine #'bar-size = #4
+ \override BarLine #'bar-extent = #'(-2 . 2)
} \lyricmode {
looooooooooooooooooooooooooooooooooong1 syllable
}
\version "2.12.0"
\header
{
- texidoc = "Melismata are triggered by manual beams."
+ texidoc = "Melismata are triggered by manual beams. Notes in a
+ melisma take their natural spacing over a long syllable."
}
\layout { ragged-right = ##t }
\new Staff
\relative c'' {
\set Staff.autoBeaming = ##f
- c8 c8[ c8 c8] c8 }
-
- \lyricsto "" \new Lyrics \lyricmode { bla bla bla }
+ g4 d8[ b8 d8 g8] g4
+ }
+ \lyricsto "" \new Lyrics \lyricmode { bla blaa -- bla }
>>
-\version "2.12.0"
+\version "2.13.47"
\header {
texidoc = "Mensural ligatures show different shapes, depending on the
#(set-accidental-style 'forget)
\textLengthOn
- % ligaturae binaria
+% ligaturae binaria
\[
b\breve^\markup { \column { { \bold "ligaturae binaria" } "BL" } }
\bar "|" \break
- % ligaturae ternariae, quaternariae, etc. (sicut in Apel[1])
+% ligaturae ternariae, quaternariae, etc. (sicut in Apel[1])
\[
b\breve^\markup {
\bar "|" \break
- % examples from "dtv-Atlas zur Musik" [2]
+% examples from "dtv-Atlas zur Musik" [2]
\[
d'\breve^\markup { \column { { \bold "dtv-Atlas" } "BBL" } }
\bar "|" \break
- % some ligatures from Ockeghem: Missa De plus en plus
+% some ligatures from Ockeghem: Missa De plus en plus
\[
c'\maxima^\markup {
\]
\[
- b\longa^\markup { "LBBBBB" }
+ \override NoteHead #'style = #'blackpetrucci
+ b\longa^\markup { "LBBBBB." }
c'\breve
d'
g
+ \once \override NoteHead #'ligature-flexa = ##t
f
- g
+ \revert NoteHead #'style
+ g\breve.
\]
\[
\]
\[
+ \override NoteHead #'style = #'blackpetrucci
e'1^\markup { "SSB" }
a
g\breve
+ \revert NoteHead #'style
\]
\[
e'
\]
+ \[
+ \override NoteHead #'style = #'blackpetrucci
+ e'\longa^\markup { "LBB" }
+ f'\breve
+ \revert NoteHead #'style
+ e'
+ \]
+
+ \[
+ \override NoteHead #'style = #'blackpetrucci
+ b\breve^\markup { "BBBBBBL" }
+ g
+ \override NoteHead #'ligature-flexa = ##t
+ \override NoteHead #'flexa-width = #3
+ f
+ f'
+ \override NoteHead #'flexa-width = #5
+ b
+ c'
+ \revert NoteHead #'style
+ % though ligature-flexa is still ##t, this pair must be drawn as recta
+ b\longa
+ \revert NoteHead #'flexa-width
+ \revert NoteHead #'ligature-flexa
+ \]
+
\bar "|" \break
- % some from the Requiem
+% some from the Requiem
\[
a1^\markup { \column { { \bold "Ockeghem: Requiem" } "SSBBBBBBBL" } }
\]
\bar "|" \break
+}
- % crazy ligatures
+\context Staff \with
+{
+ \override StaffSymbol #'line-count = #4
+}
+{
+ \clef "petrucci-c5"
+ \set Staff.printKeyCancellation = ##f
+ \cadenzaOn % turn off bar lines
+ #(set-accidental-style 'forget)
+ \textLengthOn
\[
c\breve^\markup { \column { { \bold "crazy ligatures" } "BBBBB" } }
\[
b^\markup { "B.B." }
a
- \] % TODO: dots within ligatures must be placed above heads
+ \] % TODO the first dot is too high to avoid a non-existent (ledger) line
\bar "|" \break
- % invalid ligatures (those commented out are rejected with explanation)
+% invalid ligatures (those commented out are rejected with explanation)
- % \[
- % a1^\markup { \column { { \bold "invalid ligatures" } "SS" } }
- % as
- % \]
+% \[
+% a1^\markup { \column { { \bold "invalid ligatures" } "SS" } }
+% as
+% \]
\[
a\breve^\markup { "BBB" }
as
\]
- % \[
- % f\longa^\markup { "LLB" }
- % g
- % f\breve
- % \]
+% \[
+% f\longa^\markup { "LLB" }
+% g
+% f\breve
+% \]
- % \[
- % f\breve^\markup { "BSLB" }
- % a1
- % g\longa
- % a\breve
- % \]
+% \[
+% f\breve^\markup { "BSLB" }
+% a1
+% g\longa
+% a\breve
+% \]
}
% Litterae:
%
% [1] Willi Apel: The Notation of Polyphonic Music. 900-1600.
-% [2] Ulrich Michels: dtv-Altlas zur Musik, 1977.
+% [2] Ulrich Michels: dtv-Atlas zur Musik, 1977.
%
<score-partwise>
<identification>
<miscellaneous>
- <miscellaneous-field name="description">Some tablature staves, with
- explicit fingering information and different string tunings given
+ <miscellaneous-field name="description">Some tablature staves, with
+ explicit fingering information and different string tunings given
in the MusicXML file.</miscellaneous-field>
</miscellaneous>
</identification>
<note>
<pitch>
<step>D</step>
- <octave>2</octave>
+ <octave>3</octave>
</pitch>
<duration>1</duration>
<voice>1</voice>
<notations>
<technical>
<string>5</string>
- <fret>-7</fret>
+ <fret>5</fret>
</technical>
</notations>
</note>
--- /dev/null
+\version "2.12.0"
+
+\markuplines \wordwrap-lines {
+ This regtest does not contain any header and paper blocks. Its purpose is to
+ test whether anything breaks if these blocks are absent.
+}
--- /dev/null
+\version "2.13.47"
+
+\header {
+ texidoc = "The PDF backend uses several header fields to store metadata
+in the resulting PDF file. Header fields with the prefix pdf override
+those without the prefix for PDF creation (not for visual display on the page).
+"
+
+ title = \markup { \italic "Title of " \bold \concat {"the" " " \abs-fontsize #27 "piece"} }
+ subtitle = \markup { \concat { "Subtitle" " of" " the" " " \natural "piece" }}
+ composer = \markup { \bold \concat {"The" " " "Genius" " " "Composer"}}
+ pdfcomposer = "Composer used for PDF"
+ arranger = \markup { The Arranger \circle f \draw-circle #3 #0.5 ##t }
+ copyright = "The Copyright"
+ keywords = "pdfmark, metadata, DOCINFO, lilypond"
+}
+\layout { ragged-right= ##t }
+
+\relative c' { g4 }
--- /dev/null
+\version "2.13.48"
+
+\header {
+
+ texidoc = "
+Negative fret numbers calculated due to assigning a string number
+can be displayed, ignored, or recalculated. Here we should have
+all three cases demonstrated.
+"
+
+}
+
+myMusic = \relative c' {
+ <c\1>1 ^\markup { recalculate }
+ \set TabStaff.handleNegativeFrets = #'include
+ <c\1>1 ^ \markup { include }
+ \set TabStaff.handleNegativeFrets = #'ignore
+ <c\1>1 ^ \markup { ignore }
+}
+
+\score {
+ <<
+ \new Staff {
+ \clef "treble_8"
+ \textLengthOn
+ \myMusic
+ }
+ \new TabStaff {
+ \myMusic
+ }
+ >>
+}
$(outdir)/libstdc++.a:
rm -f $@
- ln -s `$(CXX) -print-file-name=libstdc++.a` $(outdir)/
+ ln -s `$(CXX) -print-file-name=libstdc++.a` $(outdir)
ifeq ($(LINK_GXX_STATICALLY),yes)
$(outdir)/lilypond: $(outdir)/libstdc++.a
SCM
Bar_line::calc_bar_extent (SCM smob)
{
+ Interval result;
Grob *me = unsmob_grob (smob);
+ if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me))
+ result = staff->extent (staff, Y_AXIS);
- SCM size = me->get_property ("bar-size");
-
- if (!scm_is_number (size)
- || !Staff_symbol_referencer::get_staff_symbol (me))
- return ly_interval2scm (Interval ());
-
- Real h = scm_to_double (size);
- return ly_interval2scm (Interval (-h / 2, h / 2));
+ return ly_interval2scm (result);
}
Interval
Grob *me = unsmob_grob (smob);
SCM s = me->get_property ("glyph-name");
- SCM barsize = me->get_property ("bar-size");
+ SCM extent = me->get_property ("bar-extent");
- if (scm_is_string (s) && scm_is_number (barsize))
+ if (scm_is_string (s) && is_number_pair (extent))
{
string str = ly_scm2string (s);
- Real sz = robust_scm2double (barsize, 0);
- if (sz <= 0)
- return SCM_EOL;
+ Interval ex = ly_scm2interval (extent);
+ if (ex.length () > 0)
+ {
+ Stencil result = compound_barline (me, str, ex, false);
- return compound_barline (me, str, sz, false).smobbed_copy ();
+ return result.smobbed_copy ();
+ }
}
return SCM_EOL;
}
Stencil
-Bar_line::compound_barline (Grob *me, string str, Real h,
+Bar_line::compound_barline (Grob *me, string str, Interval const &extent,
bool rounded)
{
Real kern = robust_scm2double (me->get_property ("kern"), 1);
hair *= staffline;
fatline *= staffline;
- Stencil thin = simple_barline (me, hair, h, rounded);
- Stencil thick = simple_barline (me, fatline, h, rounded);
+ Stencil thin = simple_barline (me, hair, extent, rounded);
+ Stencil thick = simple_barline (me, fatline, extent, rounded);
Stencil dot = Font_interface::get_default_font (me)->find_by_name ("dots.dot");
int lines = Staff_symbol_referencer::line_count (me);
colon.add_stencil (dot);
colon.translate_axis (-dist / 2, Y_AXIS);
+ Real const h = extent.length ();
Stencil m;
- Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
- Real center = 0;
- if (staff)
- {
- Interval staff_extent = staff->extent (staff, Y_AXIS);
- center = staff_extent.center ();
- }
if (str == "||:")
str = "|:";
if (str == "")
{
- Stencil empty = Lookup::blank (Box (Interval (0, 0), Interval (-h / 2, h / 2)));
- empty.translate_axis (center, Y_AXIS);
+ Stencil empty = Lookup::blank (Box (Interval (0, 0), extent));
return empty;
}
else if (str == "|")
- {
- thin.translate_axis (center, Y_AXIS);
- return thin;
- }
+ return thin;
else if (str == ".")
- {
- thick.translate_axis (center, Y_AXIS);
- return thick;
- }
+ return thick;
else if (str == "|." || (h == 0 && str == ":|"))
{
m.add_at_edge (X_AXIS, LEFT, thick, 0);
}
else if (str == ":")
{
- int c = (Staff_symbol_referencer::line_count (me));
-
- for (int i = 0; i < c - 1; i++)
+ if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me))
{
- Real y = (- (c - 1.0) / 2 + 0.5 + i) * staff_space;
- Stencil d (dot);
-
- d.translate_axis (y, Y_AXIS);
- m.add_stencil (d);
+ Interval staff_extent = staff->extent (staff, Y_AXIS);
+
+ /*
+ assume staff lines are disposed equally at unit space;
+ put a dot into each space within extent (may extend staff_extent).
+
+ staff_extent is an interval of two integers or two half-integers;
+ in the former case dots are to be placed at half-integers,
+ in the latter at integers.
+
+ these integers are not exact due to staff line thickness.
+ */
+ int const pos = int (rint (staff_extent.at (UP) * 2));
+ Real const correction = pos & 1 ? 0.0 : 0.5;
+
+ for (int i = int (rint (extent.at (DOWN) + (0.5 - correction))),
+ e = int (rint (extent.at (UP) + (0.5 - correction)));
+ i < e;
+ ++i)
+ {
+ Stencil d (dot);
+
+ d.translate_axis (i + correction, Y_AXIS);
+ m.add_stencil (d);
+ }
}
}
else if (str == "dashed")
- m = dashed_bar_line (me, h, hair);
+ m = dashed_bar_line (me, extent, hair);
else if (str == "'")
- m = tick_bar_line (me, h, rounded);
+ m = tick_bar_line (me, extent.at (UP), rounded);
- m.translate_axis (center, Y_AXIS);
return m;
}
Stencil
Bar_line::simple_barline (Grob *me,
Real w,
- Real h,
+ Interval const &extent,
bool rounded)
{
Real blot
? me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"))
: 0.0;
- return Lookup::round_filled_box (Box (Interval (0, w),
- Interval (-h / 2, h / 2)), blot);
+ return Lookup::round_filled_box (Box (Interval (0, w), extent), blot);
}
Stencil
: 0.0;
return Lookup::round_filled_box (Box (Interval (0, line_thick),
- Interval (h / 2 - th, h / 2 + th)), blot);
-}
-
-MAKE_SCHEME_CALLBACK (Bar_line, calc_bar_size, 1);
-SCM
-Bar_line::calc_bar_size (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
- if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me))
- {
- Interval staff_y = staff->extent (staff, Y_AXIS);
- return scm_from_double (staff_y.is_empty () ? 0.0 : staff_y.length ());
- }
- return scm_from_int (0);
+ Interval (h - th, h + th)), blot);
}
Stencil
-Bar_line::dashed_bar_line (Grob *me, Real h, Real thick)
+Bar_line::dashed_bar_line (Grob *me, Interval const &extent, Real thick)
{
Real dash_size
= 1.0 - robust_scm2double (me->get_property ("gap"), 0.3);
connections.
*/
Real ss = Staff_symbol_referencer::staff_space (me);
- int count = Staff_symbol_referencer::line_count (me);
- Real line_thick = Staff_symbol_referencer::line_thickness (me);
+ Real const h = extent.length ();
+ int dashes = int (rint (h / ss));
- if (fabs (line_thick + (count -1) * ss - h) < 0.1) // ugh.
+ /*
+ there are two concerns:
+ 1. one dash plus one space should be one staff space
+ 2. the line should begin and end with half a dash
+
+ both can be satisfied, if the extent is (roughly) an integer
+ multiple of staff space.
+ */
+ if (fabs (h / ss - dashes) < 0.1)
{
Real blot
= me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
- Real half_space = ss / 2;
+ Real const half_dash = dash_size / 2;
Stencil bar;
- for (int i = (count - 1); i >= -(count - 1); i -= 2)
+ for (int i = 0; i <= dashes; ++i)
{
- Real top_y = min ((i + dash_size) * half_space,
- (count - 1) * half_space + line_thick / 2);
- Real bot_y = max ((i - dash_size) * half_space,
- -(count - 1) * half_space - line_thick / 2);
+ Real top_y = extent.at (DOWN)
+ + (i == dashes ? h : (i + half_dash) * ss);
+ Real bot_y = extent.at (DOWN) + (i ? (i - half_dash) * ss : 0.0);
bar.add_stencil (Lookup::round_filled_box (Box (Interval (0, thick),
Interval (bot_y, top_y)),
We have to scale the dashing so it starts and ends with half a
dash exactly.
*/
- int dashes = int (rint (h / ss));
Real total_dash_size = h / dashes;
Real factor = (dash_size - thick) / ss;
box.add_point (Offset (0, h));
Stencil s (box, at);
- s.translate (Offset (thick / 2, -h / 2));
+ s.translate (Offset (thick / 2, extent.at (DOWN)));
return s;
}
return Stencil ();
"thick-thickness "
"glyph "
"glyph-name "
- "bar-size "
"bar-extent "
);
along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "beam.hh"
+#include "beam-scoring-problem.hh"
+#include <queue>
#include <algorithm>
using namespace std;
-#include "grob.hh"
#include "align-interface.hh"
+#include "beam.hh"
+#include "grob.hh"
#include "international.hh"
+#include "main.hh"
#include "output-def.hh"
#include "pointer-group-interface.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
#include "warn.hh"
-#include "main.hh"
Real
get_detail (SCM alist, SCM sym, Real def)
return fabs (x) * ((x < 0) ? fac : 1.0);
}
-struct Quant_score
+/****************************************************************/
+
+Beam_configuration::Beam_configuration ()
{
- Real yl;
- Real yr;
- Real demerits;
+ y = Interval (0.0, 0.0);
+ demerits = 0.0;
+ next_scorer_todo = ORIGINAL_DISTANCE;
+}
+
+bool Beam_configuration::done () const
+{
+ return next_scorer_todo >= NUM_SCORERS;
+}
+
+void Beam_configuration::add (Real demerit, const string &reason)
+{
+ demerits += demerit;
#if DEBUG_BEAM_SCORING
- string score_card_;
+ if (demerit)
+ score_card_ += to_string (" %s %.2f", reason.c_str (), demerit);
#endif
-};
+}
+
+Beam_configuration* Beam_configuration::new_config (Interval start,
+ Interval offset)
+{
+ Beam_configuration* qs = new Beam_configuration;
+ qs->y = Interval (int (start[LEFT]) + offset[LEFT],
+ int (start[RIGHT]) + offset[RIGHT]);
+
+ // This orders the sequence so we try combinations closest to the
+ // the ideal offset first.
+ Real start_score = abs (offset[RIGHT]) + abs (offset[LEFT]);
+ qs->demerits = start_score / 1000.0;
+ qs->next_scorer_todo = ORIGINAL_DISTANCE + 1;
+
+ return qs;
+}
+
+/****************************************************************/
/*
TODO:
- Add demerits for quants per se, as to forbid a specific quant
entirely
*/
-
int
-best_quant_score_idx (vector<Quant_score> const &qscores)
+best_quant_score_idx (vector<Beam_configuration*> const &configs)
{
Real best = 1e6;
int best_idx = -1;
- for (vsize i = qscores.size (); i--;)
+ for (vsize i = configs.size (); i--;)
{
- if (qscores[i].demerits < best)
+ if (configs[i]->demerits < best)
{
- best = qscores [i].demerits;
+ best = configs [i]->demerits;
best_idx = i;
}
}
return best_idx;
}
-MAKE_SCHEME_CALLBACK (Beam, quanting, 2);
-SCM
-Beam::quanting (SCM smob, SCM posns)
-{
- Grob *me = unsmob_grob (smob);
-
- Beam_quant_parameters parameters;
- parameters.fill (me);
-
- Real yl = scm_to_double (scm_car (posns));
- Real yr = scm_to_double (scm_cdr (posns));
-
- /*
- Calculations are relative to a unit-scaled staff, i.e. the quants are
- divided by the current staff_space.
- */
- Real ss = Staff_symbol_referencer::staff_space (me);
- Real beam_thickness = Beam::get_beam_thickness (me) / ss;
- Real slt = Staff_symbol_referencer::line_thickness (me) / ss;
-
- Real dy_mus = robust_scm2double (me->get_property ("least-squares-dy"), 0);
- Real straddle = 0.0;
- Real sit = (beam_thickness - slt) / 2;
- Real inter = 0.5;
- Real hang = 1.0 - (beam_thickness - slt) / 2;
- Real quants [] = {straddle, sit, inter, hang };
-
- int num_quants = int (sizeof (quants) / sizeof (Real));
- vector<Real> quantsl;
- vector<Real> quantsr;
-
- /*
- going to REGION_SIZE == 2, yields another 0.6 second with
- wtk1-fugue2.
-
- (result indexes between 70 and 575) ? --hwn.
-
- */
-
- /*
- Do stem computations. These depend on YL and YR linearly, so we can
- precompute for every stem 2 factors.
- */
- vector<Grob*> stems
- = extract_grob_array (me, "stems");
- vector<Stem_info> stem_infos;
- vector<Real> base_lengths;
- vector<Real> stem_xposns;
+// This is a temporary hack to see how much we can gain by using a
+// priority queue on the beams to score.
+static int score_count = 0;
+LY_DEFINE (ly_beam_score_count, "ly:beam-score-count", 0, 0, 0,
+ (),
+ "count number of beam scores.") {
+ return scm_from_int (score_count);
+}
- Drul_array<bool> dirs_found (0, 0);
- Grob *common[2];
+void Beam_scoring_problem::init_stems ()
+{
+ extract_grob_set (beam, "stems", stems);
for (int a = 2; a--;)
- common[a] = common_refpoint_of_array (stems, me, Axis (a));
+ common[a] = common_refpoint_of_array (stems, beam, Axis (a));
- Grob *fvs = first_normal_stem (me);
- Grob *lvs = last_normal_stem (me);
- Real xl = fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0;
- Real xr = fvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0;
-
- /*
- We store some info to quickly interpolate. The stemlength are
- affine linear in YL and YR. If YL == YR == 0, then we might have
- stem_y != 0.0, when we're cross staff.
+ Grob *fvs = Beam::first_normal_stem (beam);
+ Grob *lvs = Beam::last_normal_stem (beam);
+
+ x_span = Interval (fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0,
+ lvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0);
- */
+ Drul_array<bool> dirs_found (0, 0);
for (vsize i = 0; i < stems.size (); i++)
{
Grob *s = stems[i];
-
+ if (!Stem::is_normal_stem (s))
+ continue;
+
Stem_info si (Stem::get_stem_info (s));
- si.scale (1 / ss);
+ si.scale (1 / staff_space);
stem_infos.push_back (si);
- dirs_found[stem_infos.back ().dir_] = true;
+ dirs_found[si.dir_] = true;
bool f = to_boolean (s->get_property ("french-beaming"))
- && s != lvs && s != fvs;
+ && s != lvs && s != fvs;
- if (Stem::is_normal_stem (s))
- {
- base_lengths.push_back (calc_stem_y (me, s, common, xl, xr, CENTER,
- Interval (0, 0), f) / ss);
- }
- else
- {
- base_lengths.push_back (0);
- }
-
- stem_xposns.push_back (s->relative_coordinate (common[X_AXIS], X_AXIS));
+ Real y = Beam::calc_stem_y (beam, s, common, x_span[LEFT], x_span[RIGHT], CENTER,
+ Interval (0, 0), f);
+ base_lengths.push_back (y / staff_space);
+ stem_xpositions.push_back (s->relative_coordinate (common[X_AXIS], X_AXIS));
+ }
+
+ edge_dirs = Drul_array<Direction> (CENTER, CENTER);
+ if (stem_infos.size ())
+ {
+ edge_dirs = Drul_array<Direction> (stem_infos[0].dir_,
+ stem_infos.back().dir_);
}
- bool xstaff = Align_interface::has_interface (common[Y_AXIS]);
- Direction ldir = Direction (stem_infos[0].dir_);
- Direction rdir = Direction (stem_infos.back ().dir_);
- bool is_knee = dirs_found[LEFT] && dirs_found[RIGHT];
+ is_xstaff = Align_interface::has_interface (common[Y_AXIS]);
+ is_knee = dirs_found[LEFT] && dirs_found[RIGHT];
+
+ staff_radius = Staff_symbol_referencer::staff_radius (beam);
+ edge_beam_counts = Drul_array<int>
+ (Stem::beam_multiplicity (stems[0]).length () + 1,
+ Stem::beam_multiplicity (stems.back ()).length () + 1);
+
+ beam_translation = Beam::get_beam_translation (beam) / staff_space;
+}
+
+Beam_scoring_problem::Beam_scoring_problem (Grob *me, Drul_array<Real> ys)
+{
+ beam = me;
+ unquanted_y = ys;
+
+ /*
+ Calculations are relative to a unit-scaled staff, i.e. the quants are
+ divided by the current staff_space.
+ */
+ staff_space = Staff_symbol_referencer::staff_space (me);
+ beam_thickness = Beam::get_beam_thickness (me) / staff_space;
+ line_thickness = Staff_symbol_referencer::line_thickness (me) / staff_space;
+
+ // This is the least-squares DY, corrected for concave beams.
+ musical_dy = robust_scm2double (me->get_property ("least-squares-dy"), 0);
+ parameters.fill (me);
+ init_stems ();
+}
+
+void
+Beam_scoring_problem::generate_quants (vector<Beam_configuration*> *scores) const
+{
int region_size = (int) parameters.REGION_SIZE;
/*
Knees are harder, lets try some more possibilities for knees.
- */
+ */
if (is_knee)
region_size += 2;
+
+ Real straddle = 0.0;
+ Real sit = (beam_thickness - line_thickness) / 2;
+ Real inter = 0.5;
+ Real hang = 1.0 - (beam_thickness - line_thickness) / 2;
+ Real base_quants [] = {straddle, sit, inter, hang};
+ int num_base_quants = int (sizeof (base_quants) / sizeof (Real));
/*
Asymetry ? should run to <= region_size ?
*/
+ vector<Real> unshifted_quants;
for (int i = -region_size; i < region_size; i++)
- for (int j = 0; j < num_quants; j++)
+ for (int j = 0; j < num_base_quants; j++)
{
- quantsl.push_back (i + quants[j] + int (yl));
- quantsr.push_back (i + quants[j] + int (yr));
+ unshifted_quants.push_back (i + base_quants[j]);
}
- vector<Quant_score> qscores;
-
- for (vsize l = 0; l < quantsl.size (); l++)
- for (vsize r = 0; r < quantsr.size (); r++)
- {
- Quant_score qs;
- qs.yl = quantsl[l];
- qs.yr = quantsr[r];
- qs.demerits = 0.0;
+ for (vsize i = 0; i < unshifted_quants.size (); i++)
+ for (vsize j = 0; j < unshifted_quants.size (); j++)
+ scores->push_back (Beam_configuration::new_config (unquanted_y,
+ Interval (unshifted_quants[i],
+ unshifted_quants[j])));
+}
- qscores.push_back (qs);
- }
- /* This is a longish function, but we don't separate this out into
- neat modular separate subfunctions, as the subfunctions would be
- called for many values of YL, YR. By precomputing various
- parameters outside of the loop, we can save a lot of time. */
- for (vsize i = qscores.size (); i--;)
+void Beam_scoring_problem::one_scorer (Beam_configuration* config) const
+{
+ score_count ++;
+ switch (config->next_scorer_todo) {
+ case SLOPES:
+ score_slopes_dy (config);
+ break;
+ case FORBIDDEN:
+ score_forbidden_quants (config);
+ break;
+ case STEM_LENGTHS:
+ score_stem_lengths (config);
+ break;
+
+ case NUM_SCORERS:
+ case ORIGINAL_DISTANCE:
+ default:
+ assert (false);
+ }
+ config->next_scorer_todo++;
+}
+
+
+Beam_configuration *
+Beam_scoring_problem::force_score (SCM inspect_quants, const vector<Beam_configuration*> &configs) const
+{
+ Drul_array<Real> ins = ly_scm2interval (inspect_quants);
+ Real mindist = 1e6;
+ Beam_configuration *best = NULL;
+ for (vsize i = 0; i < configs.size (); i++)
{
- Real d = score_slopes_dy (qscores[i].yl, qscores[i].yr,
- dy_mus, yr- yl,
- xr - xl,
- xstaff, ¶meters);
- qscores[i].demerits += d;
-
-#if DEBUG_BEAM_SCORING
- qscores[i].score_card_ += to_string ("S%.2f", d);
-#endif
+ Real d = fabs (configs[i]->y[LEFT]- ins[LEFT]) + fabs (configs[i]->y[RIGHT] - ins[RIGHT]);
+ if (d < mindist)
+ {
+ best = configs[i];
+ mindist = d;
+ }
}
+ if (mindist > 1e5)
+ programming_error ("cannot find quant");
- Real rad = Staff_symbol_referencer::staff_radius (me);
- Drul_array<int> edge_beam_counts
- (Stem::beam_multiplicity (stems[0]).length () + 1,
- Stem::beam_multiplicity (stems.back ()).length () + 1);
-
- Real beam_translation = get_beam_translation (me) / ss;
-
- Real reasonable_score = (is_knee) ? 200000 : 100;
- for (vsize i = qscores.size (); i--;)
- if (qscores[i].demerits < reasonable_score)
- {
- Real d = score_forbidden_quants (qscores[i].yl, qscores[i].yr,
- rad, slt, beam_thickness, beam_translation,
- edge_beam_counts, ldir, rdir, ¶meters);
- qscores[i].demerits += d;
-
-#if DEBUG_BEAM_SCORING
- qscores[i].score_card_ += to_string (" F %.2f", d);
-#endif
- }
-
- for (vsize i = qscores.size (); i--;)
- if (qscores[i].demerits < reasonable_score)
- {
- Real d = score_stem_lengths (stems, stem_infos,
- base_lengths, stem_xposns,
- xl, xr,
- is_knee,
- qscores[i].yl, qscores[i].yr, ¶meters);
- qscores[i].demerits += d;
+ return best;
+}
-#if DEBUG_BEAM_SCORING
- qscores[i].score_card_ += to_string (" L %.2f", d);
-#endif
- }
+Drul_array<Real>
+Beam_scoring_problem::solve () const {
+ vector<Beam_configuration*> configs;
+ generate_quants (&configs);
- int best_idx = best_quant_score_idx (qscores);
+ Beam_configuration *best = NULL;
-#if DEBUG_BEAM_SCORING
- SCM inspect_quants = me->get_property ("inspect-quants");
- if (to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring")))
+ SCM inspect_quants = beam->get_property ("inspect-quants");
+ if (to_boolean (beam->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring")))
&& scm_is_pair (inspect_quants))
{
- Drul_array<Real> ins = ly_scm2interval (inspect_quants);
-
- Real mindist = 1e6;
- for (vsize i = 0; i < qscores.size (); i++)
- {
- Real d = fabs (qscores[i].yl- ins[LEFT]) + fabs (qscores[i].yr - ins[RIGHT]);
- if (d < mindist)
- {
- best_idx = i;
- mindist = d;
- }
- }
- if (mindist > 1e5)
- programming_error ("cannot find quant");
- }
-#endif
-
- Interval final_positions;
- if (best_idx < 0)
- {
- warning (_ ("no feasible beam position"));
- final_positions = Interval (0, 0);
+ best = force_score (inspect_quants, configs);
}
else
{
- final_positions = Drul_array<Real> (qscores[best_idx].yl,
- qscores[best_idx].yr);
+ std::priority_queue<Beam_configuration*, std::vector<Beam_configuration*>,
+ Beam_configuration_less> queue;
+ for (vsize i = 0; i < configs.size(); i++)
+ queue.push(configs[i]);
+
+
+ /*
+ TODO
+
+ It would be neat if we generated new configurations on the
+ fly, depending on the best complete score so far, eg.
+
+ if (best->done()) {
+ if (best->demerits < sqrt(queue.size())
+ break;
+ while (best->demerits > sqrt(queue.size()) {
+ generate and insert new configuration
+ }
+ }
+
+ that would allow us to do away with region_size altogether.
+ */
+ while (true) {
+ best = queue.top ();
+ if (best->done ())
+ break;
+
+ queue.pop ();
+ one_scorer (best);
+ queue.push (best);
+ }
}
-
+
+ Interval final_positions = best->y;
+
#if DEBUG_BEAM_SCORING
- if (best_idx >= 0
- && to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring"))))
+ if (to_boolean (beam->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring"))))
{
- qscores[best_idx].score_card_ += to_string ("i%d", best_idx);
-
// debug quanting
- me->set_property ("quant-score",
- ly_string2scm (qscores[best_idx].score_card_));
+ int completed = 0;
+ for (vsize i = 0; i < configs.size (); i++)
+ {
+ if (configs[i]->done ())
+ completed++;
+ }
+
+ string card = best->score_card_ + to_string (" c%d/%d", completed, configs.size());
+ beam->set_property ("quant-score", ly_string2scm (card));
}
#endif
- return ly_interval2scm (final_positions);
+ junk_pointers (configs);
+ return final_positions;
}
-Real
-Beam::score_stem_lengths (vector<Grob*> const &stems,
- vector<Stem_info> const &stem_infos,
- vector<Real> const &base_stem_ys,
- vector<Real> const &stem_xs,
- Real xl, Real xr,
- bool knee,
- Real yl, Real yr,
-
- Beam_quant_parameters const *parameters)
+void
+Beam_scoring_problem::score_stem_lengths (Beam_configuration* config) const
{
- Real limit_penalty = parameters->STEM_LENGTH_LIMIT_PENALTY;
+ Real limit_penalty = parameters.STEM_LENGTH_LIMIT_PENALTY;
Drul_array<Real> score (0, 0);
Drul_array<int> count (0, 0);
- for (vsize i = 0; i < stems.size (); i++)
+ for (vsize i = 0; i < stem_xpositions.size (); i++)
{
- Grob *s = stems[i];
- if (!Stem::is_normal_stem (s))
- continue;
-
- Real x = stem_xs[i];
- Real dx = xr - xl;
- Real beam_y = dx ? yr * (x - xl) / dx + yl * (xr - x) / dx : (yr + yl) / 2;
- Real current_y = beam_y + base_stem_ys[i];
- Real length_pen = parameters->STEM_LENGTH_DEMERIT_FACTOR;
+ Real x = stem_xpositions[i];
+ Real dx = x_span.delta ();
+ Real beam_y = dx
+ ? config->y[RIGHT] * (x - x_span[LEFT]) / dx + config->y[LEFT] * (x_span[RIGHT] - x) / dx
+ : (config->y[RIGHT] + config->y[LEFT]) / 2;
+ Real current_y = beam_y + base_lengths[i];
+ Real length_pen = parameters.STEM_LENGTH_DEMERIT_FACTOR;
Stem_info info = stem_infos[i];
Direction d = info.dir_;
/* We introduce a power, to make the scoring strictly
convex. Otherwise a symmetric knee beam (up/down/up/down)
does not have an optimum in the middle. */
- if (knee)
+ if (is_knee)
ideal_score = pow (ideal_score, 1.1);
score[d] += length_pen * ideal_score;
-
count[d]++;
}
+ /* Divide by number of stems, to make the measure scale-free. */
Direction d = DOWN;
do
score[d] /= max (count[d], 1);
while (flip (&d) != DOWN);
- return score[LEFT] + score[RIGHT];
+ config->add (score[LEFT] + score[RIGHT], "L");
}
-Real
-Beam::score_slopes_dy (Real yl, Real yr,
- Real dy_mus, Real dy_damp,
- Real dx,
- bool xstaff,
-
- Beam_quant_parameters const *parameters)
+void
+Beam_scoring_problem::score_slopes_dy (Beam_configuration *config) const
{
- Real dy = yr - yl;
+ Real dy = config->y.delta ();
+ Real damped_dy = unquanted_y.delta();
Real dem = 0.0;
-
+
/*
DAMPING_DIRECTION_PENALTY is a very harsh measure, while for
complex beaming patterns, horizontal is often a good choice.
TODO: find a way to incorporate the complexity of the beam in this
penalty.
*/
- if (sign (dy_damp) != sign (dy))
+ if (sign (damped_dy) != sign (dy))
{
if (!dy)
{
- if (fabs (dy_damp / dx) > parameters->ROUND_TO_ZERO_SLOPE)
- dem += parameters->DAMPING_DIRECTION_PENALTY;
+ if (fabs (damped_dy / x_span.delta ()) > parameters.ROUND_TO_ZERO_SLOPE)
+ dem += parameters.DAMPING_DIRECTION_PENALTY;
else
- dem += parameters->HINT_DIRECTION_PENALTY;
+ dem += parameters.HINT_DIRECTION_PENALTY;
}
else
- dem += parameters->DAMPING_DIRECTION_PENALTY;
+ dem += parameters.DAMPING_DIRECTION_PENALTY;
}
- dem += parameters->MUSICAL_DIRECTION_FACTOR
- * max (0.0, (fabs (dy) - fabs (dy_mus)));
+ dem += parameters.MUSICAL_DIRECTION_FACTOR
+ * max (0.0, (fabs (dy) - fabs (musical_dy)));
- Real slope_penalty = parameters->IDEAL_SLOPE_FACTOR;
+ Real slope_penalty = parameters.IDEAL_SLOPE_FACTOR;
/* Xstaff beams tend to use extreme slopes to get short stems. We
put in a penalty here. */
- if (xstaff)
+ if (is_xstaff)
slope_penalty *= 10;
/* Huh, why would a too steep beam be better than a too flat one ? */
- dem += shrink_extra_weight (fabs (dy_damp) - fabs (dy), 1.5)
+ dem += shrink_extra_weight (fabs (damped_dy) - fabs (dy), 1.5)
* slope_penalty;
- return dem;
+ config->add (dem, "S");
}
static Real
because for 32nd and 64th beams the forbidden quants are relatively
more important than stem lengths.
*/
-Real
-Beam::score_forbidden_quants (Real yl, Real yr,
- Real radius,
- Real slt,
- Real beam_thickness, Real beam_translation,
- Drul_array<int> beam_counts,
- Direction ldir, Direction rdir,
-
- Beam_quant_parameters const *parameters)
+void
+Beam_scoring_problem::score_forbidden_quants (Beam_configuration *config) const
{
- Real dy = yr - yl;
- Drul_array<Real> y (yl, yr);
- Drul_array<Direction> dirs (ldir, rdir);
+ Real dy = config->y.delta ();
- Real extra_demerit = parameters->SECONDARY_BEAM_DEMERIT / (max (beam_counts[LEFT], beam_counts[RIGHT]));
+ Real extra_demerit = parameters.SECONDARY_BEAM_DEMERIT /
+ max (edge_beam_counts[LEFT], edge_beam_counts[RIGHT]);
Direction d = LEFT;
Real dem = 0.0;
- Real eps = parameters->BEAM_EPS;
+ Real eps = parameters.BEAM_EPS;
do
{
- for (int j = 1; j <= beam_counts[d]; j++)
+ for (int j = 1; j <= edge_beam_counts[d]; j++)
{
- Direction stem_dir = dirs[d];
+ Direction stem_dir = edge_dirs[d];
/*
The 2.2 factor is to provide a little leniency for
will be in the gap of the (2, sit) quant, leading to a
false demerit.
*/
- Real gap1 = y[d] - stem_dir * ((j - 1) * beam_translation + beam_thickness / 2 - slt / 2.2);
- Real gap2 = y[d] - stem_dir * (j * beam_translation - beam_thickness / 2 + slt / 2.2);
+ Real gap1 = config->y[d] - stem_dir * ((j - 1) * beam_translation + beam_thickness / 2 - line_thickness / 2.2);
+ Real gap2 = config->y[d] - stem_dir * (j * beam_translation - beam_thickness / 2 + line_thickness / 2.2);
Interval gap;
gap.add_point (gap1);
gap.add_point (gap2);
- for (Real k = -radius;
- k <= radius + eps; k += 1.0)
+ for (Real k = -staff_radius;
+ k <= staff_radius + eps; k += 1.0)
if (gap.contains (k))
{
Real dist = min (fabs (gap[UP] - k), fabs (gap[DOWN] - k));
}
while ((flip (&d)) != LEFT);
- if (max (beam_counts[LEFT], beam_counts[RIGHT]) >= 2)
+ if (max (edge_beam_counts[LEFT], edge_beam_counts[RIGHT]) >= 2)
{
Real straddle = 0.0;
- Real sit = (beam_thickness - slt) / 2;
+ Real sit = (beam_thickness - line_thickness) / 2;
Real inter = 0.5;
- Real hang = 1.0 - (beam_thickness - slt) / 2;
+ Real hang = 1.0 - (beam_thickness - line_thickness) / 2;
Direction d = LEFT;
do
{
- if (beam_counts[d] >= 2
- && fabs (y[d] - dirs[d] * beam_translation) < radius + inter)
+ if (edge_beam_counts[d] >= 2
+ && fabs (config->y[d] - edge_dirs[d] * beam_translation) < staff_radius + inter)
{
- if (dirs[d] == UP && dy <= eps
- && fabs (my_modf (y[d]) - sit) < eps)
+ // TODO up/down symmetry.
+ if (edge_dirs[d] == UP && dy <= eps
+ && fabs (my_modf (config->y[d]) - sit) < eps)
dem += extra_demerit;
- if (dirs[d] == DOWN && dy >= eps
- && fabs (my_modf (y[d]) - hang) < eps)
+ if (edge_dirs[d] == DOWN && dy >= eps
+ && fabs (my_modf (config->y[d]) - hang) < eps)
dem += extra_demerit;
}
- if (beam_counts[d] >= 3
- && fabs (y[d] - 2 * dirs[d] * beam_translation) < radius + inter)
+ if (edge_beam_counts[d] >= 3
+ && fabs (config->y[d] - 2 * edge_dirs[d] * beam_translation) < staff_radius + inter)
{
- if (dirs[d] == UP && dy <= eps
- && fabs (my_modf (y[d]) - straddle) < eps)
+ // TODO up/down symmetry.
+ if (edge_dirs[d] == UP && dy <= eps
+ && fabs (my_modf (config->y[d]) - straddle) < eps)
dem += extra_demerit;
- if (dirs[d] == DOWN && dy >= eps
- && fabs (my_modf (y[d]) - straddle) < eps)
+ if (edge_dirs[d] == DOWN && dy >= eps
+ && fabs (my_modf (config->y[d]) - straddle) < eps)
dem += extra_demerit;
}
}
while (flip (&d) != LEFT);
}
- return dem;
+ config->add (dem, "F");
}
#include "beam.hh"
+#include "beam-scoring-problem.hh"
#include "beaming-pattern.hh"
#include "directional-element-interface.hh"
-#include "main.hh"
+#include "grob-array.hh"
#include "international.hh"
#include "interval-set.hh"
#include "item.hh"
#include "least-squares.hh"
#include "lookup.hh"
+#include "main.hh"
#include "misc.hh"
#include "output-def.hh"
#include "pointer-group-interface.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
#include "warn.hh"
-#include "grob-array.hh"
#if DEBUG_BEAM_SCORING
#include "text-interface.hh" // debug output.
if (normal_stem_count (me) <= 1)
return posns;
-
SCM s = me->get_property ("damping");
Real damping = scm_to_double (s);
Real concaveness = robust_scm2double (me->get_property ("concaveness"), 0.0);
return ly_interval2scm (pos);
}
+
+MAKE_SCHEME_CALLBACK (Beam, quanting, 2);
+SCM
+Beam::quanting (SCM smob, SCM posns)
+{
+ Grob *me = unsmob_grob (smob);
+ Drul_array<Real> ys(0, 0);
+ ys = robust_scm2drul (posns, ys);
+ Beam_scoring_problem problem (me, ys);
+
+ ys = problem.solve ();
+ return ly_interval2scm (ys);
+}
+
+
/*
Report slice containing the numbers that are both in (car BEAMING)
and (cdr BEAMING)
return b->paper_ ? b->paper_->self_scm () : SCM_BOOL_F;
}
+LY_DEFINE (ly_book_header, "ly:book-header",
+ 1, 0, 0, (SCM book),
+ "Return header in @var{book}.")
+{
+ LY_ASSERT_SMOB (Book, book, 1);
+ Book *b = unsmob_book (book);
+ return b->header_ ? b->header_ : SCM_BOOL_F;
+}
+
LY_DEFINE (ly_book_scores, "ly:book-scores",
1, 0, 0, (SCM book),
"Return scores in @var{book}.")
public:
DECLARE_GROB_INTERFACE();
- static Stencil dashed_bar_line (Grob *me, Real h, Real thick);
+ static Stencil dashed_bar_line (Grob *me, Interval const &extent, Real thick);
static Stencil tick_bar_line (Grob *me, Real h, bool rounded);
- static Stencil compound_barline (Grob *, string, Real height, bool rounded);
- static Stencil simple_barline (Grob *, Real wid, Real height, bool rounded);
+ static Stencil compound_barline (Grob *, string, Interval const &extent,
+ bool rounded);
+ static Stencil simple_barline (Grob *, Real wid, Interval const &extent,
+ bool rounded);
static Interval bar_y_extent (Grob *, Grob *);
static bool non_empty_barline (Grob *me);
DECLARE_SCHEME_CALLBACK (calc_bar_extent, (SCM));
- DECLARE_SCHEME_CALLBACK (calc_bar_size, (SCM));
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (calc_anchor, (SCM));
};
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Jan Nieuwenhuizen <janneke@gnu.org>
+
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef BEAM_SCORING_PROBLEM_HH
+#define BEAM_SCORING_PROBLEM_HH
+
+#include "interval.hh"
+#include "lily-proto.hh"
+#include "lily-guile.hh"
+#include "std-vector.hh"
+#include "stem-info.hh"
+#include "main.hh" // DEBUG_BEAM_SCORING
+
+enum Scorers {
+ // Should be ordered by increasing expensiveness.
+ ORIGINAL_DISTANCE,
+ SLOPES,
+ FORBIDDEN,
+ STEM_LENGTHS,
+ NUM_SCORERS,
+};
+
+struct Beam_configuration
+{
+ Interval y;
+ Real demerits;
+#if DEBUG_BEAM_SCORING
+ string score_card_;
+#endif
+
+ int next_scorer_todo;
+
+ Beam_configuration ();
+ bool done () const;
+ void add (Real demerit, const string &reason);
+ static Beam_configuration* new_config(Interval start,
+ Interval offset);
+};
+
+// Comparator for a queue of Beam_configuration*.
+class Beam_configuration_less
+{
+public:
+ bool operator() (Beam_configuration* const& l, Beam_configuration* const& r)
+ {
+ // Invert
+ return l->demerits > r->demerits;
+ }
+};
+
+
+struct Beam_quant_parameters
+{
+ Real SECONDARY_BEAM_DEMERIT;
+ Real STEM_LENGTH_DEMERIT_FACTOR;
+ Real REGION_SIZE;
+
+ /*
+ threshold to combat rounding errors.
+ */
+ Real BEAM_EPS;
+
+ // possibly ridiculous, but too short stems just won't do
+ Real STEM_LENGTH_LIMIT_PENALTY;
+ Real DAMPING_DIRECTION_PENALTY;
+ Real MUSICAL_DIRECTION_FACTOR;
+ Real HINT_DIRECTION_PENALTY;
+ Real IDEAL_SLOPE_FACTOR;
+ Real ROUND_TO_ZERO_SLOPE;
+
+ void fill (Grob *him);
+};
+
+
+
+/*
+ Parameters for a single beam. Precomputed to save time in
+ scoring individual configurations.
+
+ TODO - use trailing _ on data members.
+
+ */
+class Beam_scoring_problem
+{
+public:
+ Beam_scoring_problem (Grob *me, Drul_array<Real> ys);
+ Drul_array<Real> solve() const;
+
+private:
+ Grob *beam;
+
+ Interval unquanted_y;
+
+ Real staff_space;
+ Real beam_thickness;
+ Real line_thickness;
+ Real musical_dy;
+
+ Interval x_span;
+
+ vector<Stem_info> stem_infos;
+
+ /*
+ Do stem computations. These depend on YL and YR linearly, so we can
+ precompute for every stem 2 factors.
+
+ We store some info to quickly interpolate. The stemlengths are
+ affine linear in YL and YR. If YL == YR == 0, then we might have
+ stem_y != 0.0, when we're cross staff.
+ */
+ vector<Real> base_lengths;
+ vector<Real> stem_xpositions;
+
+ Grob *common[2];
+ bool is_xstaff;
+ bool is_knee;
+
+ Beam_quant_parameters parameters;
+
+ Real staff_radius;
+ Drul_array<int> edge_beam_counts;
+ Drul_array<Direction> edge_dirs;
+ Real beam_translation;
+
+ void init_stems ();
+
+ void one_scorer (Beam_configuration* config) const;
+ Beam_configuration *force_score (SCM inspect_quants,
+ const vector<Beam_configuration*> &configs) const;
+
+ // Scoring functions:
+ void score_forbidden_quants (Beam_configuration *config) const;
+ void score_slopes_dy (Beam_configuration *config) const;
+ void score_stem_lengths (Beam_configuration* config) const;
+ void generate_quants(vector<Beam_configuration*>* scores) const;
+};
+
+#endif /* BEAM_SCORING_PROBLEM_HH */
#include "lily-proto.hh"
#include "stem-info.hh"
-/*
- TODO: move quanting in separate file.
-*/
-struct Beam_quant_parameters
-{
- Real SECONDARY_BEAM_DEMERIT;
- Real STEM_LENGTH_DEMERIT_FACTOR;
- Real REGION_SIZE;
-
- /*
- threshold to combat rounding errors.
- */
- Real BEAM_EPS;
-
- // possibly ridiculous, but too short stems just won't do
- Real STEM_LENGTH_LIMIT_PENALTY;
- Real DAMPING_DIRECTION_PENALTY;
- Real MUSICAL_DIRECTION_FACTOR;
- Real HINT_DIRECTION_PENALTY;
- Real IDEAL_SLOPE_FACTOR;
- Real ROUND_TO_ZERO_SLOPE;
-
- void fill (Grob *him);
-};
-
struct Beam_segment
{
int vertical_count_;
bool gapped_;
Direction dir_;
int max_connect_;
-
};
DECLARE_SCHEME_CALLBACK (slope_damping, (SCM, SCM));
DECLARE_SCHEME_CALLBACK (quanting, (SCM, SCM));
-static Real score_slopes_dy (Real, Real, Real, Real, Real, bool, Beam_quant_parameters const *);
-
- static Real score_stem_lengths (vector<Grob*> const &stems,
- vector<Stem_info> const &stem_infos,
- vector<Real> const &base_stem_ys,
- vector<Real> const &stem_xs,
- Real xl, Real xr,
- bool knee,
- Real yl, Real yr, Beam_quant_parameters const *);
- static Real score_forbidden_quants (Real, Real,
- Real, Real, Real, Real,
- Drul_array<int>, Direction, Direction,
- Beam_quant_parameters const *);
-
static int get_direction_beam_count (Grob *me, Direction d);
+
private:
+ friend class Beam_scoring_problem;
+
static Direction get_default_dir (Grob *);
static void set_stem_directions (Grob *, Direction);
static void consider_auto_knees (Grob *);
static void set_stem_shorten (Grob *);
+ static int forced_stem_count (Grob *);
static Real calc_stem_y (Grob *, Grob *s, Grob **c,
Real, Real, Direction,
Drul_array<Real> pos, bool french);
- static int forced_stem_count (Grob *);
};
#include "lily-proto.hh"
#include "std-vector.hh"
-
-enum Configuration_tag
- {
- SLUR_STEM = 0x01,
- SLUR_HEAD = 0x02,
- SLUR_FREE = 0x04,
- SLUR_FREE_HEAD = 0x08,
- SLUR_FREE_STEM = 0x10,
- SLUR_STEM_TIP = 0x10,
- };
-
class Slur_configuration
{
Real score_;
Drul_array<Offset> attachment_;
Bezier curve_;
Real height_;
- unsigned tags_;
int index_;
+ enum Slur_scorers
+ {
+ INITIAL_SCORE,
+ SLOPE,
+ EDGES,
+ EXTRA_ENCOMPASS,
+ ENCOMPASS,
+ NUM_SCORERS,
+ };
+
+ int next_scorer_todo;
+
Slur_configuration ();
Real score () const { return score_; }
void generate_curve (Slur_score_state const &state, Real r0, Real h_inf,
vector<Offset> const &);
- void calculate_score (Slur_score_state const &);
+ void run_next_scorer (Slur_score_state const &);
+ bool done () const;
+ static Slur_configuration *new_config (Drul_array<Offset> const &offs, int idx);
+
protected:
void score_extra_encompass (Slur_score_state const &);
void score_slopes (Slur_score_state const &);
void score_edges (Slur_score_state const &);
void score_encompass (Slur_score_state const &);
+
+ friend class Slur_configuration_less;
+};
+
+// Comparator for a queue of Beam_configuration*.
+class Slur_configuration_less
+{
+public:
+ bool operator () (Slur_configuration* const& l, Slur_configuration* const& r)
+ {
+ // Invert
+ return l->score_ > r->score_;
+ }
};
#endif /* SLUR_CONFIGURATION_HH */
Extra_collision_info (Grob *g, Real idx, Interval x, Interval y, Real p);
Extra_collision_info ();
-
};
struct Encompass_info
Slur_score_state ();
~Slur_score_state ();
- Bezier get_best_curve ();
+ Slur_configuration *get_forced_configuration (Interval ys) const;
+ Slur_configuration *get_best_curve () const;
void fill (Grob *);
Direction slur_direction () const;
Encompass_info get_encompass_info (Grob *col) const;
vector<Extra_collision_info> get_extra_encompass_infos () const;
Real move_away_from_staffline (Real y, Grob *on_staff) const;
- int get_closest_index (SCM inspect_quants) const;
Grob *breakable_bound_item (Direction) const;
};
static void add_bar (Grob *, Grob *);
static void evaluate_glyph (Grob *);
DECLARE_SCHEME_CALLBACK (width, (SCM smob));
- DECLARE_SCHEME_CALLBACK (calc_bar_size, (SCM));
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (calc_glyph_name, (SCM));
DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM));
"%{" {
yy_push_state (longcomment);
}
- %[^{\n\r].*[\n\r] {
+ %[^{\n\r][^\n\r]*[\n\r] {
}
%[^{\n\r] { // backup rule
}
%[\n\r] {
}
- %[^{\n\r].* {
+ %[^{\n\r][^\n\r]* {
}
{WHITE}+ {
Paper_book *pbook = unsmob_paper_book (pb);
return pbook->paper_->self_scm ();
}
+
+LY_DEFINE (ly_paper_book_header, "ly:paper-book-header",
+ 1, 0, 0, (SCM pb),
+ "Return the header definition (@code{\\header})"
+ " in @code{Paper_book} object @var{pb}.")
+{
+ LY_ASSERT_SMOB (Paper_book, pb, 1);
+ Paper_book *pbook = unsmob_paper_book (pb);
+ return pbook->header_;
+}
split_list_ = SCM_EOL;
state_ = APART;
playing_state_ = APART;
+
+ busy_ = false;
+ notice_busy_ = false;
}
void
Separation_item::conditional_skyline (Grob *me, Grob *left)
{
vector<Box> bs = boxes (me, left);
- return Skyline (bs, 0.0, Y_AXIS, LEFT);
+ Real horizon_padding = robust_scm2double (me->get_property ("skyline-vertical-padding"), 0.0);
+ return Skyline (bs, horizon_padding, Y_AXIS, LEFT);
}
{
Item *me = unsmob_item (smob);
vector<Box> bs = boxes (me, 0);
- /* todo: the horizon_padding is somewhat arbitrary */
- return Skyline_pair (bs, 0.0, Y_AXIS).smobbed_copy ();
+ Real horizon_padding = robust_scm2double (me->get_property ("skyline-vertical-padding"), 0.0);
+ return Skyline_pair (bs, horizon_padding, Y_AXIS).smobbed_copy ();
}
/* if left is non-NULL, get the boxes corresponding to the
"elements "
"padding "
"horizontal-skylines "
+ "skyline-vertical-padding "
);
Slur_configuration::Slur_configuration ()
{
- tags_ = 0x0;
score_ = 0.0;
index_ = -1;
};
-
void
Slur_configuration::add_score (Real s, string desc)
{
Real demerit = factor * dy;
if (state.extremes_[d].stem_
&& state.extremes_[d].stem_dir_ == state.dir_
+ // TODO - Stem::get_beaming() should be precomputed.
&& !Stem::get_beaming (state.extremes_[d].stem_, -d))
demerit /= 5;
add_score (demerit, "slope");
}
+
+// This is a temporary hack to see how much we can gain by using a
+// priority queue on the beams to score.
+static int score_count = 0;
+LY_DEFINE (ly_slur_score_count, "ly:slur-score-count", 0, 0, 0,
+ (),
+ "count number of slur scores.") {
+ return scm_from_int (score_count);
+}
+
void
-Slur_configuration::calculate_score (Slur_score_state const &state)
+Slur_configuration::run_next_scorer (Slur_score_state const &state)
+{
+ switch (next_scorer_todo) {
+ case EXTRA_ENCOMPASS:
+ score_extra_encompass (state);
+ break;
+ case SLOPE:
+ score_slopes (state);
+ break;
+ case EDGES:
+ score_edges (state);
+ break;
+ case ENCOMPASS:
+ score_encompass (state);
+ break;
+ default:
+ assert (false);
+ }
+ next_scorer_todo++;
+ score_count++;
+}
+
+bool
+Slur_configuration::done () const
+{
+ return next_scorer_todo >= NUM_SCORERS;
+}
+
+Slur_configuration *
+Slur_configuration::new_config (Drul_array<Offset> const &offs, int idx)
{
- score_extra_encompass (state);
- score_slopes (state);
- score_edges (state);
- score_encompass (state);
+ Slur_configuration *conf = new Slur_configuration;
+ conf->attachment_ = offs;
+ conf->index_ = idx;
+ conf->next_scorer_todo = INITIAL_SCORE + 1;
+ return conf;
}
#include "slur-scoring.hh"
+#include <queue>
+
#include "accidental-interface.hh"
#include "beam.hh"
#include "directional-element-interface.hh"
state.generate_curves ();
SCM end_ys = me->get_property ("positions");
- Bezier best;
-
+ SCM inspect_quants = me->get_property ("inspect-quants");
+ if (is_number_pair (inspect_quants))
+ end_ys = inspect_quants;
+
+ Slur_configuration *best = NULL;
if (is_number_pair (end_ys))
- best = state.configurations_[state.get_closest_index (end_ys)]->curve_;
+ best = state.get_forced_configuration (ly_scm2interval(end_ys));
else
best = state.get_best_curve ();
+#if DEBUG_SLUR_SCORING
+ bool debug_slurs = to_boolean (me->layout ()
+ ->lookup_variable (ly_symbol2scm ("debug-slur-scoring")));
+ if (debug_slurs)
+ {
+ string total = best->card ();
+ total += to_string (" TOTAL=%.2f idx=%d", best->score (), best->index_);
+ me->set_property ("quant-score", ly_string2scm (total));
+ }
+#endif
+
SCM controls = SCM_EOL;
for (int i = 4; i--;)
{
- Offset o = best.control_[i]
+ Offset o = best->curve_.control_[i]
- Offset (me->relative_coordinate (state.common_[X_AXIS], X_AXIS),
me->relative_coordinate (state.common_[Y_AXIS], Y_AXIS));
controls = scm_cons (ly_offset2scm (o), controls);
return controls;
}
-Bezier
-Slur_score_state::get_best_curve ()
+Slur_configuration*
+Slur_score_state::get_forced_configuration (Interval ys) const
{
- int opt_idx = -1;
- Real opt = 1e6;
-
-#if DEBUG_SLUR_SCORING
- bool debug_slurs = to_boolean (slur_->layout ()
- ->lookup_variable (ly_symbol2scm ("debug-slur-scoring")));
- SCM inspect_quants = slur_->get_property ("inspect-quants");
- SCM inspect_index = slur_->get_property ("inspect-index");
- if (debug_slurs
- && scm_is_integer (inspect_index))
- {
- opt_idx = scm_to_int (inspect_index);
- configurations_[opt_idx]->calculate_score (*this);
- opt = configurations_[opt_idx]->score ();
- }
- else if (debug_slurs
- && scm_is_pair (inspect_quants))
- {
- opt_idx = get_closest_index (inspect_quants);
- configurations_[opt_idx]->calculate_score (*this);
- opt = configurations_[opt_idx]->score ();
- }
- else
-#endif
+ Slur_configuration *best = NULL;
+ Real mindist = 1e6;
+ for (vsize i = 0; i < configurations_.size (); i++)
{
- for (vsize i = 0; i < configurations_.size (); i++)
- configurations_[i]->calculate_score (*this);
- for (vsize i = 0; i < configurations_.size (); i++)
+ Real d = fabs (configurations_[i]->attachment_[LEFT][Y_AXIS] - ys[LEFT])
+ + fabs (configurations_[i]->attachment_[RIGHT][Y_AXIS] - ys[RIGHT]);
+ if (d < mindist)
{
- if (configurations_[i]->score () < opt)
- {
- opt = configurations_[i]->score ();
- opt_idx = i;
- }
+ best = configurations_[i];
+ mindist = d;
}
}
-#if DEBUG_SLUR_SCORING
- if (debug_slurs)
- {
- string total;
- if (opt_idx >= 0)
- {
- total = configurations_[opt_idx]->card ();
- total += to_string (" TOTAL=%.2f idx=%d", configurations_[opt_idx]->score (), opt_idx);
- }
- else
- {
- total = "no sol?";
- }
+ while (!best->done ())
+ best->run_next_scorer (*this);
- slur_->set_property ("quant-score",
- ly_string2scm (total));
- }
-#endif
+ if (mindist > 1e5)
+ programming_error ("cannot find quant");
- if (opt_idx < 0)
- {
- opt_idx = 0;
- programming_error ("No optimal slur found. Guessing 0.");
- }
-
- return configurations_[opt_idx]->curve_;
+ return best;
+}
+
+
+Slur_configuration *
+Slur_score_state::get_best_curve () const
+{
+ std::priority_queue<Slur_configuration*, std::vector<Slur_configuration*>,
+ Slur_configuration_less> queue;
+ for (vsize i = 0; i < configurations_.size (); i++)
+ queue.push (configurations_[i]);
+
+ Slur_configuration *best = NULL;
+ while (true) {
+ best = queue.top ();
+ if (best->done ())
+ break;
+
+ queue.pop ();
+ best->run_next_scorer (*this);
+ queue.push (best);
+ }
+
+ return best;
}
Grob *
return 0;
}
-int
-Slur_score_state::get_closest_index (SCM inspect_quants) const
-{
- Drul_array<Real> ins = ly_scm2interval (inspect_quants);
-
- int opt_idx = -1;
- Real mindist = 1e6;
- for (vsize i = 0; i < configurations_.size (); i++)
- {
- Real d = fabs (configurations_[i]->attachment_[LEFT][Y_AXIS] - ins[LEFT])
- + fabs (configurations_[i]->attachment_[RIGHT][Y_AXIS] - ins[RIGHT]);
- if (d < mindist)
- {
- opt_idx = i;
- mindist = d;
- }
- }
- if (mindist > 1e5)
- programming_error ("cannot find quant");
- return opt_idx;
-}
-
/*
TODO: should analyse encompasses to determine sensible region, and
should limit slopes available.
os[RIGHT] = base_attachments_[RIGHT];
for (int j = 0; dir_ * os[RIGHT][Y_AXIS] <= dir_ * end_ys[RIGHT]; j++)
{
- Slur_configuration s;
Direction d = LEFT;
Drul_array<bool> attach_to_stem (false, false);
do
}
while (flip (&d) != LEFT);
- s.attachment_ = os;
- s.index_ = scores.size ();
-
- scores.push_back (new Slur_configuration (s));
+ scores.push_back (Slur_configuration::new_config (os, scores.size ()));
os[RIGHT][Y_AXIS] += dir_ * staff_space_ / 2;
}
#include "bar-line.hh"
#include "grob.hh"
#include "pointer-group-interface.hh"
+#include "staff-symbol-referencer.hh"
+
void
Span_bar::add_bar (Grob *me, Grob *b)
{
Grob *bar = elements[i];
Interval ext = Bar_line::bar_y_extent (bar, refp);
+ if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (bar))
+ ext.unite (staff->extent (refp, Y_AXIS));
if (ext.is_empty ())
continue;
{
Stencil interbar = Bar_line::compound_barline (model_bar,
glyph_string,
- l.length (),
+ l,
false);
- interbar.translate_axis (l.center (), Y_AXIS);
span_bar.add_stencil (interbar);
}
}
/*
urg.
*/
- Stencil m = Bar_line::compound_barline (me, gl, 40 PT, false);
+ Stencil m =
+ Bar_line::compound_barline (me, gl, Interval (-20 PT, 20 PT), false);
return ly_interval2scm (m.extent (X_AXIS));
}
return ly_scm2interval (Axis_group_interface::generic_group_extent (me, Y_AXIS));
}
-MAKE_SCHEME_CALLBACK (Span_bar, calc_bar_size, 1);
-SCM
-Span_bar::calc_bar_size (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
- Interval iv (get_spanned_interval (me));
- if (iv.is_empty ())
- {
- /* This happens if the bars are hara-kiried from under us. */
- me->suicide ();
- return scm_from_double (-1);
- }
- return scm_from_double (iv.length ());
-}
-
ADD_INTERFACE (Span_bar,
"A bar line that is spanned between other barlines. This"
" interface is used for bar lines that connect different"
Staff_symbol_engraver::~Staff_symbol_engraver ()
{
- assert (!span_);
+ if (span_)
+ {
+ // Somehow finalize() was not called?
+ programming_error ("Have a pending spanner in destructor.");
+ }
}
Staff_symbol_engraver::Staff_symbol_engraver ()
INI_FILES = $(LY_FILES)
EXTRA_DIST_FILES = $(SCM_FILES)
-INSTALLATION_DIR=$(local_lilypond_datadir)/ly/
+INSTALLATION_DIR=$(local_lilypond_datadir)/ly
INSTALLATION_FILES=$(INI_FILES)
STEPMAKE_TEMPLATES=install
%%%% You should have received a copy of the GNU General Public License
%%%% along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-\version "2.13.42"
+\version "2.13.48"
\context {
\name "Global"
shortInstrumentName = #'()
predefinedDiagramTable = #default-fret-table
+ handleNegativeFrets = #'recalculate
}
\context {
\name RhythmicStaff
\alias "Staff"
- \override BarLine #'bar-size = #4
+ \override BarLine #'bar-extent = #'(-2 . 2)
\override VoltaBracket #'staff-padding = #3
\override StaffSymbol #'line-count = #1
%% make sure that barlines aren't collapsed, when
%% Bar_engraver is there.
- \override BarLine #'bar-size = #0.1
+ \override BarLine #'bar-extent = #'(-0.05 . 0.05)
}
%% Special "TAB" clef
clefGlyph = #"clefs.tab"
clefPosition = #0
+ %% Change string if note results in negative fret number
+ handleNegativeFrets = #'recalculate
}
\context {
# TODO: fix hardcoded out/ ?
LYS_OUTPUT_OPTION= --lily-output-dir $(LYS_OUTPUT_DIR)
-LYS_OUTPUT_DIR=$(top-build-dir)/out/lybook-db/
+LYS_OUTPUT_DIR=$(top-build-dir)/out/lybook-db
LILYPOND_BOOK_FLAGS += $(LYS_OUTPUT_OPTION)
$(outdir)/%.latex: %.doc $(INIT_LY_SOURCES) $(SCHEME_SOURCES)
LILYPOND_VERSION=$(TOPLEVEL_VERSION) $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BOOK_PROCESS) $(LILYPOND_BOOK_LILYPOND_FLAGS)' --output=$(outdir) $(LILYPOND_BOOK_FLAGS) $<
top-htaccess=$(trusted-dir)/lilypond.org.htaccess
dir-htaccess=$(trusted-dir)/website-dir.htaccess
TEXI2HTML_PROGRAM=$(HOME)/usr/bin/texi2html
- EXAMPLES=$(HOME)/lilypond/media/ly-examples/
+ EXAMPLES=$(HOME)/lilypond/media/ly-examples
PICTURES=$(HOME)/lilypond/media/pictures
else
### for normal git
- script-dir=$(top-src-dir)/scripts/build/
+ script-dir=$(top-src-dir)/scripts/build
texi2html-init-file=$(top-src-dir)/Documentation/lilypond-texi2html.init
top-htaccess=$(top-src-dir)/Documentation/web/server/lilypond.org.htaccess
dir-htaccess=$(top-src-dir)/Documentation/web/server/website-dir.htaccess
include $(config_make)
# I assume this is run from top-build-dir
- EXAMPLES=Documentation/web/ly-examples/out-www/
- PICTURES=Documentation/pictures/out-www/
+ EXAMPLES=Documentation/web/ly-examples/out-www
+ PICTURES=Documentation/pictures/out-www
endif
WEB_POST=python $(script-dir)/website_post.py
WEB_BIBS=python $(script-dir)/bib2texi.py
-SERVER_FILES=$(top-src-dir)/Documentation/web/server/
+SERVER_FILES=$(top-src-dir)/Documentation/web/server
# don't include web
MANUALS=$(wildcard $(top-src-dir)/Documentation/*.tely)
website-xrefs: website-version
for l in '' $(WEB_LANGS); do \
$(EXTRACT_TEXI_FILENAMES) \
- -I $(top-src-dir)/Documentation/ \
+ -I $(top-src-dir)/Documentation \
-I $(top-src-dir)/Documentation/"$$l" \
-I $(OUT) -o $(OUT) --split=node \
$(top-src-dir)/Documentation/"$$l"/web.texi ;\
d=`basename "$$b" .tely`; \
if [ -e "$$n" ] ; then \
$(EXTRACT_TEXI_FILENAMES) \
- -I $(top-src-dir)/Documentation/ \
+ -I $(top-src-dir)/Documentation \
-I $(top-src-dir)/Documentation/"$$l" \
- -I $(top-src-dir)/Documentation/"$$l"/"$$d"/ \
+ -I $(top-src-dir)/Documentation/"$$l"/"$$d" \
-I $(OUT) -o $(OUT) "$$n" ; \
fi ; \
done; \
done;
website-bibs: website-version
- BSTINPUTS=$(top-src-dir)/Documentation/web/ \
+ BSTINPUTS=$(top-src-dir)/Documentation/web \
$(WEB_BIBS) -s web \
-o $(OUT)/others-did.itexi \
$(top-src-dir)/Documentation/web/others-did.bib
- BSTINPUTS=$(top-src-dir)/Documentation/web/ \
+ BSTINPUTS=$(top-src-dir)/Documentation/web \
$(WEB_BIBS) -s web \
-o $(OUT)/we-wrote.itexi \
$(top-src-dir)/Documentation/web/we-wrote.bib
$(TEXI2HTML) --prefix=index \
--split=section \
--I=$(top-src-dir)/Documentation/"$$l" \
- --I=$(top-src-dir)/Documentation/ \
+ --I=$(top-src-dir)/Documentation \
--I=$(OUT) \
$$langopt \
--init-file=$(texi2html-init-file) \
website-css:
- cp $(top-src-dir)/Documentation/css/*.css $(OUT)/website/
+ cp $(top-src-dir)/Documentation/css/*.css $(OUT)/website
website-pictures:
- mkdir -p $(OUT)/website/pictures/
- cp $(PICTURES)/* $(OUT)/website/pictures/
+ mkdir -p $(OUT)/website/pictures
+ cp $(PICTURES)/* $(OUT)/website/pictures
ln -sf website/pictures $(OUT)/pictures
website-examples:
cp $(EXAMPLES)/* $(OUT)/website/ly-examples
web-post:
- $(WEB_POST) $(OUT)/website/
+ $(WEB_POST) $(OUT)/website
website: website-texinfo website-css website-pictures website-examples web-post
- cp $(SERVER_FILES)/favicon.ico $(OUT)/website/
- cp $(SERVER_FILES)/robots.txt $(OUT)/website/
+ cp $(SERVER_FILES)/favicon.ico $(OUT)/website
+ cp $(SERVER_FILES)/robots.txt $(OUT)/website
cp $(top-htaccess) $(OUT)/.htaccess
cp $(dir-htaccess) $(OUT)/website/.htaccess
STEPMAKE_TEMPLATES=install
EXTRA_DIST_FILES = $(PS_FILES)
-INSTALLATION_DIR=$(local_lilypond_datadir)/ps/
+INSTALLATION_DIR=$(local_lilypond_datadir)/ps
INSTALLATION_FILES=$(PS_FILES)
include $(depth)/make/stepmake.make
return str
+@rule ((2, 13, 48),
+ _ ("Replace bar-size with bar-extent."))
+
+def conv(str):
+ def size_as_extent (matchobj):
+ half = "%g" % (float (matchobj.group (1)) / 2)
+ return "bar-extent = #'(-" + half + " . " + half + ")"
+
+ str = re.sub (r"bar-size\s*=\s*#([0-9\.]+)", size_as_extent, str)
+
+ return str
+
# Guidelines to write rules (please keep this at the end of this file)
#
# - keep at most one rule per version; if several conversions should be done,
depth = ..
-INSTALLATION_DIR=$(local_lilypond_datadir)/scm/
+INSTALLATION_DIR=$(local_lilypond_datadir)/scm
INSTALLATION_FILES=$(SCM_FILES)
XGETTEXT_FLAGS = --language=Scheme
@code{GridPoint}s.")
+ (handleNegativeFrets ,symbol? "How the automatic fret calculator
+should handle calculated negative frets. Values include @code{'ignore},
+to leave them out of the diagram completely, @code{'include}, to include
+them as calculated, and @code{'recalculate}, to ignore the specified
+string and find a string where they will fit with a positive fret number.")
(harmonicAccidentals ,boolean? "If set, harmonic notes in chords
get accidentals.")
(harmonicDots ,boolean? "If set, harmonic notes in dotted chords get
;;
;; b
;;
- (bar-size ,ly:dimension? "The size of a bar line.")
(base-shortest-duration ,ly:moment? "Spacing is based on the
shortest notes in a piece. Normally, pieces are spaced as if notes at
least as short as this are present.")
configuration which would result in a tight interleaving of grobs from
the top staff and the bottom staff. The larger this parameter is, the
farther apart the staves are placed in such a configuration.")
+ (skyline-vertical-padding ,number? "The amount by which the left
+and right skylines of a column are padded vertically, beyond the
+@code{Y-extent}s and @code{extra-spacing-height}s of the constituent
+grobs in the column. Increase this to prevent interleaving of grobs
+from adjacent columns.")
(slash-negative-kern ,number? "The space to remove between
slashes in percent repeat glyphs. Larger values bring the two
elements closer together.")
. (
(allow-span-bar . #t)
(bar-extent . ,ly:bar-line::calc-bar-extent)
- (bar-size . ,ly:bar-line::calc-bar-size)
(break-align-anchor . ,ly:bar-line::calc-anchor)
(break-align-symbol . staff-bar)
(break-visibility . ,bar-line::calc-break-visibility)
(font-family . sans)
(font-size . 1.5)
(stencil . ,ly:text-interface::print)
+ (extra-spacing-height . (0.2 . -0.2))
(word-space . 0.0)
(meta . ((class . Item)
(interfaces . (chord-name-interface
(next-note . (extra-space . 0.5))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
- (extra-spacing-height . (-0.5 . 0.5))
(Y-offset . ,ly:staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
(next-note . (extra-space . 0.5))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
- (extra-spacing-height . (-0.5 . 0.5))
(Y-offset . ,ly:staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
(next-note . (extra-space . 0.5))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
- (extra-spacing-height . (-0.5 . 0.5))
(Y-offset . ,ly:staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
(after-line-breaking . ,ly:chord-name::after-line-breaking)
(fret-diagram-details . ((finger-code . below-string)))
(stencil . ,fret-board::calc-stencil)
+ (extra-spacing-height . (0.2 . -0.2))
(meta . ((class . Item)
(interfaces . (chord-name-interface
font-interface
(break-align-symbol . left-edge)
(break-visibility . ,center-invisible)
(non-musical . #t)
+ (extra-spacing-height . (+inf.0 . -inf.0))
(space-alist . (
(ambitus . (extra-space . 2.0))
(breathing-sign . (minimum-space . 0.0))
(LyricText
. (
(extra-spacing-width . (0.0 . 0.0))
+ ;; Recede in height for purposes of note spacing,
+ ;; so notes in melismata can be freely spaced above lyrics
+ (extra-spacing-height . (0.2 . -0.2))
(font-series . medium)
(font-size . 1.0)
(self-alignment-X . ,CENTER)
(before-line-breaking . ,ly:paper-column::before-line-breaking)
(full-measure-extra-space . 1.0)
(horizontal-skylines . ,ly:separation-item::calc-skylines)
+ (skyline-vertical-padding . 0.15)
;; (stencil . ,ly:paper-column::print)
(line-break-permission . allow)
. (
(axes . (,X ,Y))
(horizontal-skylines . ,ly:separation-item::calc-skylines)
+ (skyline-vertical-padding . 0.15)
(X-extent . ,ly:axis-group-interface::width)
(Y-extent . ,ly:axis-group-interface::height)
(meta . ((class . Item)
(duration-log . ,note-head::calc-duration-log)
(extra-spacing-height . ,ly:note-head::include-ledger-line-height)
(glyph-name . ,note-head::calc-glyph-name)
- (ligature-flexa . #f)
+ (ligature-flexa . #f)
(stem-attachment . ,ly:note-head::calc-stem-attachment)
(stencil . ,ly:note-head::print)
(X-offset . ,ly:note-head::stem-x-shift)
. (
(allow-span-bar . #t)
(bar-extent . ,ly:axis-group-interface::height)
- (bar-size . ,ly:span-bar::calc-bar-size)
(before-line-breaking . ,ly:span-bar::before-line-breaking)
(break-align-symbol . staff-bar)
(cross-staff . #t)
ly:note-head::print
ly:dots::print
ly:clef::print
+ ly:key-signature-interface::print
ly:percent-repeat-item-interface::beat-slash
ly:text-interface::print
ly:script-interface::print
;; symbols.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(define-markup-command (musicglyph layout props glyph-name)
+ (string?)
+ #:category music
+ "@var{glyph-name} is converted to a musical symbol; for example,
+@code{\\musicglyph #\"accidentals.natural\"} selects the natural sign from
+the music font. See @ruser{The Feta font} for a complete listing of
+the possible glyphs.
+
+@lilypond[verbatim,quote]
+\\markup {
+ \\musicglyph #\"f\"
+ \\musicglyph #\"rests.2\"
+ \\musicglyph #\"clefs.G_change\"
+}
+@end lilypond"
+ (let* ((font (ly:paper-get-font layout
+ (cons '((font-encoding . fetaMusic)
+ (font-name . #f))
+
+ props)))
+ (glyph (ly:font-get-glyph font glyph-name)))
+ (if (null? (ly:stencil-expr glyph))
+ (ly:warning (_ "Cannot find glyph ~a") glyph-name))
+
+ glyph))
+
(define-markup-command (doublesharp layout props)
()
#:category music
props))
name)))
-(define-markup-command (musicglyph layout props glyph-name)
- (string?)
- #:category music
- "@var{glyph-name} is converted to a musical symbol; for example,
-@code{\\musicglyph #\"accidentals.natural\"} selects the natural sign from
-the music font. See @ruser{The Feta font} for a complete listing of
-the possible glyphs.
-
-@lilypond[verbatim,quote]
-\\markup {
- \\musicglyph #\"f\"
- \\musicglyph #\"rests.2\"
- \\musicglyph #\"clefs.G_change\"
-}
-@end lilypond"
- (let* ((font (ly:paper-get-font layout
- (cons '((font-encoding . fetaMusic)
- (font-name . #f))
-
- props)))
- (glyph (ly:font-get-glyph font glyph-name)))
- (if (null? (ly:stencil-expr glyph))
- (ly:warning (_ "Cannot find glyph ~a") glyph-name))
-
- glyph))
-
-
(define-markup-command (lookup layout props glyph-name)
(string?)
#:category other
(set! music-descriptions
(sort music-descriptions alist<?))
-(define-public music-name-to-property-table (make-vector 59 '()))
+(define-public music-name-to-property-table (make-hash-table 59))
;; init hash table,
;; transport description to an object property.
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-13)
#:use-module (srfi srfi-39)
- #:use-module (lily)
- #:use-syntax (srfi srfi-39)
- #:use-syntax (ice-9 optargs))
+ #:use-module (lily))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;;
(define (make-music-type-predicate . music-types)
- (define ((make-music-type-predicate-aux mtypes) expr)
- (if (null? mtypes)
- #f
- (or (eqv? (car mtypes) (ly:music-property expr 'name))
- ((make-music-type-predicate-aux (cdr mtypes)) expr))))
- (make-music-type-predicate-aux music-types))
+ (define make-music-type-predicate-aux
+ (lambda (mtypes)
+ (lambda (expr)
+ (if (null? mtypes)
+ #f
+ (or (eqv? (car mtypes) (ly:music-property expr 'name))
+ ((make-music-type-predicate-aux (cdr mtypes)) expr))))))
+ (make-music-type-predicate-aux music-types))
(load "define-music-display-methods.scm")
\ No newline at end of file
(pfas (map font-loader font-names)))
pfas))
+
(display "%%BeginProlog\n" port)
(format
port
(display "%%EndProlog\n" port)
(display "%%BeginSetup\ninit-lilypond-parameters\n%%EndSetup\n\n" port))
+;;; Create DOCINFO pdfmark containing metadata
+;;; header fields with pdf prefix override those without the prefix
+(define (handle-metadata header port)
+ (define (metadata-lookup-output overridevar fallbackvar field)
+ (let* ((overrideval (ly:modules-lookup (list header) overridevar))
+ (fallbackval (ly:modules-lookup (list header) fallbackvar))
+ (val (if overrideval overrideval fallbackval)))
+ (if val
+ (format port "/~a (~a)\n" field (markup->string val)))))
+ (display "[ " port)
+ (metadata-lookup-output 'pdfcomposer 'composer "Author")
+ (format port "/Creator (LilyPond ~a)\n" (lilypond-version))
+ (metadata-lookup-output 'pdftitle 'title "Title")
+ (metadata-lookup-output 'pdfsubject 'subject "Subject")
+ (metadata-lookup-output 'pdfkeywords 'keywords "Keywords")
+ (metadata-lookup-output 'pdfmodDate 'modDate "ModDate")
+ (metadata-lookup-output 'pdfsubtitle 'subtitle "Subtitle")
+ (metadata-lookup-output 'pdfcomposer 'composer "Composer")
+ (metadata-lookup-output 'pdfarranger 'arranger "Arranger")
+ (metadata-lookup-output 'pdfpoet 'poet "Poet")
+ (metadata-lookup-output 'pdfcopyright 'copyright "Copyright")
+ (display "/DOCINFO pdfmark\n\n" port))
+
+
(define-public (output-framework basename book scopes fields)
(let* ((filename (format "~a.ps" basename))
(outputter (ly:make-paper-outputter
(open-file filename "wb")
'ps))
(paper (ly:paper-book-paper book))
+ (header (ly:paper-book-header book))
(systems (ly:paper-book-systems book))
(page-stencils (map page-stencil (ly:paper-book-pages book)))
(landscape? (eq? (ly:output-def-lookup paper 'landscape) #t))
;; don't do BeginDefaults PageMedia: A4
;; not necessary and wrong
(write-preamble paper #t port)
+ (if (module? header)
+ (handle-metadata header port))
(for-each
(lambda (page)
(set! page-number (1+ page-number))
;;;; You should have received a copy of the GNU General Public License
;;;; along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-(define ((check-beam-quant posl posr) beam posns)
+(define check-beam-quant
+ (lambda (posl posr)
+ (lambda (beam posns)
"Check whether BEAM has POSL and POSR quants. POSL are (POSITION
. QUANT) pairs, where QUANT is -1 (hang), 0 (center), 1 (sit) or -2/ 2 (inter)
want-l want-r posns)
(set! (ly:grob-property beam 'annotation)
(format "(~S,~S)" want-l want-r))))
- posns
- ))
+ posns))))
-
-(define ((check-beam-slope-sign comparison) beam posns)
+(define check-beam-slope-sign
+ (lambda (comparison)
+ (lambda (beam posns)
"Check whether the slope of BEAM is correct wrt. COMPARISON."
(let* ((slope-sign (- (cdr posns) (car posns)))
(correct (comparison slope-sign 0)))
(set! (ly:grob-property beam 'annotation)
(format "~S 0" (procedure-name comparison))))
(set! (ly:grob-property beam 'annotation) ""))
- posns))
+ posns))))
(define-public (check-quant-callbacks l r)
"define-music-properties.scm"
"time-signature-settings.scm"
"auto-beam.scm"
- "chord-name.scm"
"bezier-tools.scm"
"parser-ly-from-scheme.scm"
"ly-syntax-constructors.scm"
"define-context-properties.scm"
+ ;; guile 1.9 wants markups defined before referenced
+ "define-markup-commands.scm"
+
+ "chord-name.scm"
"translation-functions.scm"
"script.scm"
"midi.scm"
"define-woodwind-diagrams.scm"
"display-woodwind-diagrams.scm"
"predefined-fretboards.scm"
- "define-markup-commands.scm"
"define-grob-properties.scm"
"define-grobs.scm"
"define-grob-interfaces.scm"
(car stencils))
(ly:make-stencil '() '(0 . 0) '(0 . 0))))
+
+;;; convert a full markup object to an approximate pure string representation
+
+(define-public (markup->string m)
+ ;; markup commands with one markup argument, formatting ignored
+ (define markups-first-argument '(list
+ bold-markup box-markup caps-markup dynamic-markup finger-markup
+ fontCaps-markup huge-markup italic-markup large-markup larger-markup
+ medium-markup normal-size-sub-markup normal-size-super-markup
+ normal-text-markup normalsize-markup number-markup roman-markup
+ sans-markup simple-markup small-markup smallCaps-markup smaller-markup
+ sub-markup super-markup teeny-markup text-markup tiny-markup
+ typewriter-markup underline-markup upright-markup bracket-markup
+ circle-markup hbracket-markup parenthesize-markup rounded-box-markup
+
+ center-align-markup center-column-markup column-markup dir-column-markup
+ fill-line-markup justify-markup justify-string-markup left-align-markup
+ left-column-markup line-markup right-align-markup right-column-markup
+ vcenter-markup wordwrap-markup wordwrap-string-markup ))
+
+ ;; markup commands with markup as second argument, first argument
+ ;; specifies some formatting and is ignored
+ (define markups-second-argument '(list
+ abs-fontsize-markup fontsize-markup magnify-markup lower-markup
+ pad-around-markup pad-markup-markup pad-x-markup raise-markup
+ halign-markup hcenter-in-markup rotate-markup translate-markup
+ translate-scaled-markup with-url-markup scale-markup ))
+
+ ;; helper functions to handle string cons like string lists
+ (define (markup-cons->string-cons c)
+ (if (not (pair? c)) (markup->string c)
+ (cons (markup->string (car c)) (markup-cons->string-cons (cdr c)))))
+ (define (string-cons-join c)
+ (if (not (pair? c)) c
+ (string-join (list (car c) (string-cons-join (cdr c))) "")))
+
+ (cond
+ ((string? m) m)
+ ((null? m) "")
+
+ ;; handle \concat (string-join without spaces)
+ ((and (pair? m) (equal? (car m) concat-markup))
+ (string-cons-join (markup-cons->string-cons (cadr m))) )
+
+ ;; markup functions with the markup as first arg
+ ((member (car m) (primitive-eval markups-first-argument))
+ (markup->string (cadr m)))
+
+ ;; markup functions with markup as second arg
+ ((member (car m) (primitive-eval markups-second-argument))
+ (markup->string (cddr m)))
+
+ ;; ignore all other markup functions
+ ((markup-function? (car m)) "")
+
+ ;; handle markup lists
+ ((list? m)
+ (string-join (map markup->string m) " "))
+
+ (else "ERROR, unable to extract string from markup")))
(length (filter (lambda (x) (not (null? x)))
art-list)))
+ (define (determine-frets-and-strings
+ notes
+ defined-strings
+ defined-fingers
+ minimum-fret
+ maximum-stretch
+ tuning)
+
+ (define (calc-fret pitch string tuning)
+ (- (ly:pitch-semitones pitch) (ly:pitch-semitones (list-ref tuning (1- string)))))
+
+ (define (note-pitch a)
+ (ly:event-property a 'pitch))
+
+ (define (note-pitch>? a b)
+ (ly:pitch<? (note-pitch b)
+ (note-pitch a)))
+
+ (define (note-finger ev)
+ (let* ((articulations (ly:event-property ev 'articulations))
+ (finger-found #f))
+
+ (map (lambda (art)
+ (let* ((num (ly:event-property art 'digit)))
+
+ (if (and (eq? 'fingering-event (ly:event-property art 'class))
+ (number? num)
+ (> num 0))
+ (set! finger-found num))))
+ articulations)
+
+ finger-found))
+
+ (define (string-number event)
+ (let ((num (ly:event-property event 'string-number)))
+ (if (number? num)
+ num
+ #f)))
+
+ (define (delete-free-string string)
+ (if (number? string)
+ (set! free-strings
+ (delete string free-strings))))
+
+ (define free-strings '())
+ (define unassigned-notes '())
+ (define specified-frets '())
+
+ (define (close-enough fret)
+ (if (null? specified-frets)
+ #t
+ (reduce
+ (lambda (x y)
+ (and x y))
+ #t
+ (map (lambda (specced-fret)
+ (or (eq? 0 specced-fret)
+ (>= maximum-stretch (abs (- fret specced-fret)))))
+ specified-frets))))
+
+ (define (string-qualifies string pitch)
+ (let* ((fret (calc-fret pitch string tuning)))
+ (and (>= fret minimum-fret)
+ (close-enough fret))))
+
+ (define (open-string string pitch)
+ (let* ((fret (calc-fret pitch string tuning)))
+ (eq? fret 0)))
+
+ (define string-fret-fingering-tuples '())
+
+ (define (set-fret note string)
+ (let ((this-fret (calc-fret (ly:event-property note 'pitch)
+ string
+ tuning)))
+ (if (< this-fret 0)
+ (ly:warning (_ "Negative fret for pitch ~a on string ~a")
+ (note-pitch note) string))
+ (set! string-fret-fingering-tuples
+ (cons (list string
+ this-fret
+ (note-finger note))
+ string-fret-fingering-tuples))
+ (delete-free-string string)
+ (set! specified-frets (cons this-fret specified-frets))))
+
+ (define (pad-list target template)
+ (while (< (length target) (length template))
+ (set! target (if (null? target)
+ '(())
+ (append target '(()))))))
+
+ ;;; body of determine-frets-and-strings
+ (set! free-strings (map 1+ (iota (length tuning))))
+
+ ;; get defined-strings same length as notes
+ (pad-list defined-strings notes)
+
+ ;; get defined-fingers same length as notes
+ (pad-list defined-fingers notes)
+
+ ;; handle notes with strings assigned and fingering of 0
+ (for-each
+ (lambda (note string finger)
+ (let ((digit (if (null? finger)
+ #f
+ finger)))
+ (if (and (null? string)
+ (not (eq? digit 0)))
+ (set! unassigned-notes (cons note unassigned-notes))
+ (if (eq? digit 0)
+ (let ((fit-string
+ (find (lambda (string)
+ (open-string string (note-pitch note)))
+ free-strings)))
+ (if fit-string
+ (begin
+ (delete-free-string fit-string)
+ (set-fret note fit-string))
+ (begin
+ (ly:warning (_ "No open string for pitch ~a")
+ (note-pitch note))
+ (set! unassigned-notes (cons note unassigned-notes)))))
+ (let ((this-fret (calc-fret (note-pitch note) string tuning))
+ (handle-negative
+ (ly:context-property context
+ 'handleNegativeFrets
+ 'recalculate)))
+ (cond ((or (>= this-fret 0)
+ (eq? handle-negative 'include))
+ (begin
+ (delete-free-string string)
+ (set-fret note string)))
+ ((eq? handle-negative 'recalculate)
+ (begin
+ (ly:warning (_ "Requested string for pitch requires negative fret: string ~a pitch ~a") string (note-pitch note))
+ (ly:warning (_ "Ignoring string request."))
+ (set! unassigned-notes (cons note unassigned-notes))))))))))
+ notes defined-strings defined-fingers)
+
+ ;; handle notes without strings assigned
+ (for-each
+ (lambda (note)
+ (let ((fit-string
+ (find (lambda (string)
+ (string-qualifies string (note-pitch note)))
+ free-strings)))
+ (if fit-string
+ (set-fret note fit-string)
+ (ly:warning (_ "No string for pitch ~a (given frets ~a)")
+ (note-pitch note)
+ specified-frets))))
+ (sort unassigned-notes note-pitch>?))
+
+ string-fret-fingering-tuples) ;; end of determine-frets-and-strings
+
(define (get-predefined-fretboard predefined-fret-table tuning pitches)
"Search through @var{predefined-fret-table} looking for a predefined
fretboard with a key of @var{(tuning . pitches)}. The search will check
(cdr hash-handle) ; return table entry
'())))
+
+
;; body of get-predefined-fretboard
(let ((test-fretboard (get-fretboard (cons tuning pitches))))
(if (not (null? test-fretboard))
(create-fretboard context grob predefined-fretboard)))))
-(define (determine-frets-and-strings
- notes
- defined-strings
- defined-fingers
- minimum-fret
- maximum-stretch
- tuning)
-
- (define (calc-fret pitch string tuning)
- (- (ly:pitch-semitones pitch) (ly:pitch-semitones (list-ref tuning (1- string)))))
-
- (define (note-pitch a)
- (ly:event-property a 'pitch))
-
- (define (note-pitch>? a b)
- (ly:pitch<? (note-pitch b)
- (note-pitch a)))
-
- (define (note-finger ev)
- (let* ((articulations (ly:event-property ev 'articulations))
- (finger-found #f))
-
- (map (lambda (art)
- (let* ((num (ly:event-property art 'digit)))
-
- (if (and (eq? 'fingering-event (ly:event-property art 'class))
- (number? num)
- (> num 0))
- (set! finger-found num))))
- articulations)
-
- finger-found))
-
- (define (string-number event)
- (let ((num (ly:event-property event 'string-number)))
- (if (number? num)
- num
- #f)))
-
- (define (delete-free-string string)
- (if (number? string)
- (set! free-strings
- (delete string free-strings))))
-
- (define free-strings '())
- (define unassigned-notes '())
- (define specified-frets '())
-
- (define (close-enough fret)
- (if (null? specified-frets)
- #t
- (reduce
- (lambda (x y)
- (and x y))
- #t
- (map (lambda (specced-fret)
- (or (eq? 0 specced-fret)
- (>= maximum-stretch (abs (- fret specced-fret)))))
- specified-frets))))
-
- (define (string-qualifies string pitch)
- (let* ((fret (calc-fret pitch string tuning)))
- (and (>= fret minimum-fret)
- (close-enough fret))))
-
- (define (open-string string pitch)
- (let* ((fret (calc-fret pitch string tuning)))
- (eq? fret 0)))
-
- (define string-fret-fingering-tuples '())
-
- (define (set-fret note string)
- (let ((this-fret (calc-fret (ly:event-property note 'pitch)
- string
- tuning)))
- (if (< this-fret 0)
- (ly:warning (_ "Negative fret for pitch ~a on string ~a")
- (note-pitch note) string))
- (set! string-fret-fingering-tuples
- (cons (list string
- this-fret
- (note-finger note))
- string-fret-fingering-tuples))
- (delete-free-string string)
- (set! specified-frets (cons this-fret specified-frets))))
-
- (define (pad-list target template)
- (while (< (length target) (length template))
- (set! target (if (null? target)
- '(())
- (append target '(()))))))
-
- ;;; body of determine-frets-and-strings
- (set! free-strings (map 1+ (iota (length tuning))))
-
- ;; get defined-strings same length as notes
- (pad-list defined-strings notes)
-
- ;; get defined-fingers same length as notes
- (pad-list defined-fingers notes)
-
- ;; handle notes with strings assigned and fingering of 0
- (for-each
- (lambda (note string finger)
- (let ((digit (if (null? finger)
- #f
- finger)))
- (if (and (null? string)
- (not (eq? digit 0)))
- (set! unassigned-notes (cons note unassigned-notes))
- (if (eq? digit 0)
- (let ((fit-string
- (find (lambda (string)
- (open-string string (note-pitch note)))
- free-strings)))
- (if fit-string
- (begin
- (delete-free-string fit-string)
- (set-fret note fit-string))
- (begin
- (ly:warning (_ "No open string for pitch ~a")
- (note-pitch note))
- (set! unassigned-notes (cons note unassigned-notes)))))
- (begin
- (delete-free-string string)
- (set-fret note string))))))
- notes defined-strings defined-fingers)
-
- ;; handle notes without strings assigned
- (for-each
- (lambda (note)
- (let ((fit-string
- (find (lambda (string)
- (string-qualifies string (note-pitch note)))
- free-strings)))
- (if fit-string
- (set-fret note fit-string)
- (ly:warning (_ "No string for pitch ~a (given frets ~a)")
- (note-pitch note)
- specified-frets))))
- (sort unassigned-notes note-pitch>?))
-
- string-fret-fingering-tuples)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; tablature
find -name '*.gcda' -exec rm '{}' ';'
fi
-mkdir -p scripts/out-cov/
+mkdir -p scripts/out-cov
touch scripts/out-cov/midi2ly scripts/out-cov/midi2ly.1
make conf=cov -j2 && \
make conf=cov test-clean OUT_TEST=testcov LILYPOND_JOBS= && \
ln $depth/ly/*.ly .
ln $depth/lily/out-cov/*[ch] .
mkdir include
-ln $depth/lily/include/* include/
-ln $depth/flower/include/* include/
+ln $depth/lily/include/* include
+ln $depth/flower/include/* include
for a in *[cl] *.yy
do
- gcov -o $depth/lily/out-cov/ -p $a > $a.gcov-summary
+ gcov -o $depth/lily/out-cov -p $a > $a.gcov-summary
done
$depth/scripts/auxiliar/coverage.py --uncovered *.cc > uncovered.txt
cd $TOP_SRC_DIR
### update manuals
-find Documentation/ -path 'Documentation/snippets' -prune \
- -o -name '*.itely' | xargs $BUILD_DIR/out/bin/convert-ly -e -d
+find Documentation/ -path 'Documentation/snippets' -prune -o \
+ -name '*.itely' | xargs $BUILD_DIR/out/bin/convert-ly -e -d
### update .ly files
-find . -name '*.ly' | xargs $BUILD_DIR/out/bin/convert-ly -e -d
+# don't look in . otherwise it'll find stuff in build/ !
+find Documentation/ input/ ly/ \
+ -name '*.ly' | xargs $BUILD_DIR/out/bin/convert-ly -e -d
'Internals': 'Belső működés',
'Contributor': 'Közreműködés',
-# keep the spaces!
' (split HTML)': ' (HTML oldalak)',
' (big HTML)': ' (egy nagy HTML oldal)',
cat <<EOF > GNUmakefile
-depth = ./
+depth = .
include config\$(if \$(conf),-\$(conf),).make
include \$(configure-srcdir)/GNUmakefile.in
EOF
-at-dir = $(doc-dir)/
+at-dir = $(doc-dir)
at-ext = .in
EXTRA_DIST_FILES += $(call src-wildcard,*.ihtml)
$(INSTALLPY) -m 644 $(addprefix $(src-dir)/,$(INSTALLATION_FILES)) $(DESTDIR)$(INSTALLATION_DIR)/
$(foreach suff, $(INSTALLATION_SUFFIXES), \
($(INSTALLPY) -d $(DESTDIR)$(INSTALLATION_DIR$(suff)) || true) && \
- $(INSTALLPY) -m 644 $(addprefix $(src-dir)/, $(INSTALLATION_FILES$(suff))) $(DESTDIR)$(INSTALLATION_DIR$(suff))/ )
+ $(INSTALLPY) -m 644 $(addprefix $(src-dir), $(INSTALLATION_FILES$(suff))) $(DESTDIR)$(INSTALLATION_DIR$(suff))/ )
$(POST_INSTALL)
local-uninstall: local-uninstall-outfiles local-uninstall-files
# these two outdir FILES are distributed, since they make sense to have
# without running configure and make.
-at-dir = $(doc-dir)/
+at-dir = $(doc-dir)
at-ext = .in
# remove $(infodir)/$(INFO_IMAGES_DIR) in case it is a symlink
-rm -f $(DESTDIR)$(infodir)/$(INFO_IMAGES_DIR)
$(INSTALL) -d $(DESTDIR)$(infodir)/$(INFO_IMAGES_DIR)
- rsync -r --include '[0-9a-f][0-9a-f]' --include '*.png' --exclude '*' $(outdir)/ $(DESTDIR)$(infodir)/$(INFO_IMAGES_DIR)/
+ rsync -r --include '[0-9a-f][0-9a-f]' --include '*.png' --exclude '*' $(outdir)/ $(DESTDIR)$(infodir)/$(INFO_IMAGES_DIR)
uninstall-info-images:
rm -f $(DESTDIR)$(infodir)/$(INFO_IMAGES_DIR) || rm -rf $(DESTDIR)$(infodir)/$(INFO_IMAGES_DIR)
chmod -R a+r $(distdir)
chmod a+x `find $(distdir) -type d -print`
(cd ./$(depth)/$(outdir); $(TAR) -cf - --owner=0 --group=0 $(DIST_NAME) | gzip -9 > $(DIST_NAME).tar.gz)
- rm -rf $(distdir)/
+ rm -rf $(distdir)
local-help:
@echo " config rerun configure"
EXTRA_DIST_FILES = $(TEX_FILES) $(TEXINFO_FILES)
STEPMAKE_TEMPLATES = install install-out
-INSTALLATION_DIR = $(local_lilypond_datadir)/tex/
+INSTALLATION_DIR = $(local_lilypond_datadir)/tex
INSTALLATION_FILES = $(TEX_FILES)
include $(depth)/make/stepmake.make