@itemize
@item @uref{http://lilypond.org/test, Comparacions entre proves de regressió}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Arxiu de totes les proves de regressió}
@end itemize
replace @code{2.15.33-1} with the latest build):
@smallexample
-@uref{http://lilypond.org/download/binaries/test-output/lilypond-2.15.33-1.test-output.tar.bz2}
+@uref{http://lilypond.org/downloads/binaries/test-output/lilypond-2.15.33-1.test-output.tar.bz2}
@end smallexample
Copy the tarball into @file{gub/regtests/}, and tell the build
number.
@item
-Copy the tarball to @code{http://lilypond.org/download/gub-sources/lilypad/}.
+Copy the tarball to @code{http://lilypond.org/downloads/gub-sources/lilypad/}.
You will need to have SSH access to @code{lilypond.org}. If you do not, contact
the Release Manager via the lilypond-devel mailing list.
Melodické ozdoby se zadávají příkazem @code{\grace}, ačkoli se také dají
vytvářet uvozením hudebního výrazu příkazem @code{\appoggiatura} (dlouhý
-příraz, prodleva) a @code{\acciaccatura} (příraz, krátká appogiatura).
+příraz, prodleva) a @code{\acciaccatura} (příraz, krátká appoggiatura).
@lilypond[verbatim,quote]
\relative {
@itemize
@item @uref{http://lilypond.org/test, Porovnání dvou verzí}:
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archiv všech zkoušek regresí}
@end itemize
@funindex \grace
@funindex \slashedGrace
@funindex \acciaccatura
-@funindex \appoggiature
+@funindex \appoggiatura
@cindex Verzierungen
@cindex Ziernoten
Es gibt drei Arten von Verzierungen:
den Vorschlag (engl. acciaccatura), eine angebundene Verzierungsnote
-mit einem Schrägstrich durch den Hals, und den Vorhalt (engl. appogiatura),
+mit einem Schrägstrich durch den Hals, und den Vorhalt (engl. appoggiatura),
welcher den Wert der Hauptnote um seinen eigenen Wert verkürzt und
ohne Schrägstrich notiert wird. Man kann einen Vorschlag auch mit
Schrägstrich durch den Hals, aber ohne Legatobogen notieren. Diese
@itemize
@item @uref{http://lilypond.org/test, Vergleiche zweier Versionen}:
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archiv aller Regressionstests}
@end itemize
@itemize
@item @uref{http://lilypond.org/test, Comparaciones entre pruebas de regresión}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archivo de todas las pruebas de regresión}
@end itemize
Para barras de corchea normales, de pentagrama cruzado,
interrumpidas y en ángulo. El barrado debería depender del
contexto y de las notas vecinas (véase la sección 2.2 de
-@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon,_Jean-Pierre%29,
+@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon%2C_Jean-Pierre%29,
este libro}). Si es posible, reducir el tiempo de cálculo del
barrado.
Release 2.11.28 is now available as a binary installer for
FreeBSD x86_64. Download
-@uref{http://lilypond.org/download/binaries/freebsd-64/,the installer} and
+@uref{http://lilypond.org/downloads/binaries/freebsd-64/,the installer} and
do @emph{sh lilypond-2.11.28-1.freebsd-64.sh} in a command window.
@newsEnd
Starting with 2.7.26, the development team has been working on the
installers. We're proud to announce another version of these: they are
now available for
-@uref{http://lilypond.org/download/binaries/linux-x86/,
+@uref{http://lilypond.org/downloads/binaries/linux-x86/,
Linux/x86},
-@uref{http://lilypond.org/download/binaries/darwin-ppc/,
+@uref{http://lilypond.org/downloads/binaries/darwin-ppc/,
MacOS X} and
-@uref{http://lilypond.org/download/binaries/mingw/,
+@uref{http://lilypond.org/downloads/binaries/mingw/,
Windows}.
@newsEnd
Glossaire musicologique :
@rglosnamed{grace notes,ornements},
@rglosnamed{acciaccatura,acciaccature},
-@rglosnamed{appoggiatura,appogiature}.
+@rglosnamed{appoggiatura,appoggiature}.
Des @notation{notes d'ornement} s'obtiennent en appliquant la commande
@code{\grace}, @code{\appoggiatura} ou @code{\acciaccatura} à une
@item @code{\grace}
-@tab appogiatures
+@tab appoggiatures
@tab
@lilypond[relative=2]
\set Staff.initialTimeSignatureVisibility = #all-invisible
seront aussi reportés en MIDI :
@itemize
-@item les appogiatures -- celles-ci prendront la moitié de la valeur,
+@item les appoggiatures -- celles-ci prendront la moitié de la valeur,
dépourvue de point, de la note qui les suit -- par exemple,
@example
@seealso
Glossaire musicologique :
@rglosnamed{grace notes,ornements},
-@rglosnamed{acciaccatura,acciacature},
-@rglosnamed{appoggiatura,appogiature}.
+@rglosnamed{acciaccatura,acciaccature},
+@rglosnamed{appoggiatura,appoggiature}.
Manuel de notation :
@ref{Barres de ligature manuelles},
@item @uref{http://lilypond.org/test,
Comparaison entre différentes versions}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archive de tous les tests de régression}
@end itemize
Une ligature, qu'elle soit rectiligne, passe d'une portée à l'autre,
discontinue ou coudée, devrait dépendre du contexte et des notes
adjacentes (voir
-@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon,_Jean-Pierre%29,
+@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon%2C_Jean-Pierre%29,
la section 2.2 de cet article}). Dans la mesure du possible, raccourcir
le temps de calcul nécessaire à la génération des ligatures.
@itemize
@item @uref{http://lilypond.org/test, Összehasonlítás}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archívum}
@end itemize
@itemize
@item @uref{http://lilypond.org/test, Confronto tra i collaudi di regressione}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archivio di tutti i collaudi di regressione}
@end itemize
@itemize
@item @uref{http://lilypond.org/test, バージョン間での回帰テストの比較}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
すべての回帰テストのアーカイブ}
@end itemize
For regular, cross-staff, broken and kneed beams. Beaming should depend
on context and neighbor notes (see section 2.2 of
-@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon,_Jean-Pierre%29,
+@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon%2C_Jean-Pierre%29,
this book}). If possible also reduce beaming-computation time.
@strong{Difficulty:} medium
\acciaccatura g8 f4
</pre>
- <p>Both reflect the traditional meanings of acciaccatura and appogiatura,
+ <p>Both reflect the traditional meanings of acciaccatura and appoggiatura,
and both insert insert a slur from the first grace note to the main
note.
NL: dubbele voorslag,
DK: dobbelt forslag,
S: dubbelslag,
-FI: kaksoisappogiatura, kaksoisetuhele.
+FI: kaksoisappoggiatura, kaksoisetuhele.
@seealso
@ref{appoggiatura}.
contemporary-glissando.ly
double-glissando.ly
flat-flags-and-beam-nibs.ly
+flat-ties.ly
flute-slap-notation.ly
heavily-customized-polymetric-time-signatures.ly
laissez-vibrer-ties.ly
--- /dev/null
+%% DO NOT EDIT this file manually; it is automatically
+%% generated from LSR http://lsr.di.unimi.it
+%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
+%% and then run scripts/auxiliar/makelsr.py
+%%
+%% This file is in the public domain.
+\version "2.18.0"
+
+\header {
+ lsrtags = "midi, percussion, pitches, specific-notation"
+
+ texidoc = "
+If you want to use customized drum-pitch-names for an own drum-style
+with proper output for layout and midi, follow the steps as
+demonstrated in the code below. In short:
+
+* define the names * define the appearence * tell LilyPond to use it
+for layout * assign pitches to the names * tell LilyPond to use them
+for midi
+
+"
+ doctitle = "Customize drumPitchNames drumStyleTable and drumPitchTable in layout and midi"
+} % begin verbatim
+
+%% This snippet tries to amend
+%% NR 2.5.1 Common notation for percussion - Custom percussion staves
+%% http://lilypond.org/doc/v2.18/Documentation/notation/common-notation-for-percussion#custom-percussion-staves
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% To use custom drum-pitch-names for your score and midi you need to follow
+%% this route:
+%%
+%%%%%%%%%%%%
+%% LAYOUT:
+%%%%%%%%%%%%
+%%
+%% (1) Define a name and put it in `drumPitchNames'
+%% This can be done at toplevel with
+%% drumPitchNames #'my-name = #'my-name
+%% or shorter:
+%% drumPitchNames.my-name = #'my-name
+%% It's possible to add an alias as well.
+%% (2) Define how it should be printed
+%% Therefore put them into a toplevel-list, where each entry should look:
+%% (my-name
+%% note-head-style-or-default
+%% articulation-string-or-#f
+%% staff-position)
+%% Example:
+%% #(define my-style
+%% '(
+%% (my-name default "tenuto" -1)
+%% ; ...
+%% ))
+%% (3) Tell LilyPond to use this custom-definitions, with
+%% drumStyleTable = #(alist->hash-table my-style)
+%% in a \layout or \with
+%%
+%% Now we're done for layout, here a short, but complete example:
+%% \new DrumStaff
+%% \with { drumStyleTable = #(alist->hash-table my-style) }
+%% \drummode { my-name }
+%%
+%%%%%%%%%%%%
+%% MIDI:
+%%%%%%%%%%%%
+%%
+%% (1) Again at toplvel, assign a pitch to your custom-note-name
+%% midiDrumPitches #'my-name = #(ly:make-pitch -1 4 FLAT)
+%% or shorter:
+%% midiDrumPitches.my-name = ges
+%% Note that you have to use the name, which is in drumPitchNames, no alias
+%% (2) Tell LilyPond to use this pitch(es), with
+%% drumPitchTable = #(alist->hash-table midiDrumPitches)
+%%
+%% Example:
+%% \score {
+%% \new DrumStaff
+%% \with {
+%% drumStyleTable = #(alist->hash-table my-style)
+%% drumPitchTable = #(alist->hash-table midiDrumPitches)
+%% }
+%% \drummode { my-name4 }
+%% \layout {}
+%% \midi {}
+%% }
+%%
+%%%%%%%%%%%%
+%% TESTING
+%%%%%%%%%%%%
+%%
+%% To test whether all is fine, run the following sequence in terminal:
+%% lilypond my-file.ly
+%% midi2ly my-file.midi
+%% gedit my-file-midi.ly
+%%
+%% Which will do:
+%% 1. create pdf and midi
+%% 2. transform the midi back to a .ly-file
+%% (note: midi2ly is not always good in correctly identifying enharmonic pitches)
+%% 3. open this file in gedit (or use another editor)
+%% Now watch what you've got.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% FULL EXAMPLE
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+drumPitchNames.dbass = #'dbass
+drumPitchNames.dba = #'dbass % 'db is in use already
+drumPitchNames.dbassmute = #'dbassmute
+drumPitchNames.dbm = #'dbassmute
+drumPitchNames.do = #'dopen
+drumPitchNames.dopenmute = #'dopenmute
+drumPitchNames.dom = #'dopenmute
+drumPitchNames.dslap = #'dslap
+drumPitchNames.ds = #'dslap
+drumPitchNames.dslapmute = #'dslapmute
+drumPitchNames.dsm = #'dslapmute
+
+#(define djembe
+ '((dbass default #f -2)
+ (dbassmute default "stopped" -2)
+ (dopen default #f 0)
+ (dopenmute default "stopped" 0)
+ (dslap default #f 2)
+ (dslapmute default "stopped" 2)))
+
+midiDrumPitches.dbass = g
+midiDrumPitches.dbassmute = fis
+midiDrumPitches.dopen = a
+midiDrumPitches.dopenmute = gis
+midiDrumPitches.dslap = b
+midiDrumPitches.dslapmute = ais
+
+one = \drummode { r4 dba4 do ds r dbm dom dsm }
+
+\score {
+ \new DrumStaff
+ \with {
+ \override StaffSymbol.line-count = #3
+ instrumentName = #"Djembe "
+ drumStyleTable = #(alist->hash-table djembe)
+ drumPitchTable = #(alist->hash-table midiDrumPitches)
+ }
+ \one
+ \layout {}
+ \midi {}
+}
--- /dev/null
+%% DO NOT EDIT this file manually; it is automatically
+%% generated from LSR http://lsr.di.unimi.it
+%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
+%% and then run scripts/auxiliar/makelsr.py
+%%
+%% This file is in the public domain.
+\version "2.18.0"
+
+\header {
+ lsrtags = "contemporary-notation, scheme-language, staff-notation, tweaks-and-overrides"
+
+ texidoc = "
+The function takes the default @code{Tie.stencil} as an argument,
+calculating the result relying on the extents of this default. Further
+tweaking is possible by overriding @code{Tie.details.height-limit} or
+with @code{\\shape}. It's also possible to change the custom-definition
+on the fly.
+
+"
+ doctitle = "Flat Ties"
+} % begin verbatim
+
+%% http://lsr.di.unimi.it/LSR/Item?id=1031
+
+#(define ((flared-tie coords) grob)
+
+ (define (pair-to-list pair)
+ (list (car pair) (cdr pair)))
+
+ (define (normalize-coords goods x y dir)
+ (map
+ (lambda (coord)
+ ;(coord-scale coord (cons x (* y dir)))
+ (cons (* x (car coord)) (* y dir (cdr coord))))
+ goods))
+
+ (define (my-c-p-s points thick)
+ (make-connected-path-stencil
+ points
+ thick
+ 1.0
+ 1.0
+ #f
+ #f))
+
+ ;; outer let to trigger suicide
+ (let ((sten (ly:tie::print grob)))
+ (if (grob::is-live? grob)
+ (let* ((layout (ly:grob-layout grob))
+ (line-thickness (ly:output-def-lookup layout 'line-thickness))
+ (thickness (ly:grob-property grob 'thickness 0.1))
+ (used-thick (* line-thickness thickness))
+ (dir (ly:grob-property grob 'direction))
+ (xex (ly:stencil-extent sten X))
+ (yex (ly:stencil-extent sten Y))
+ (lenx (interval-length xex))
+ (leny (interval-length yex))
+ (xtrans (car xex))
+ (ytrans (if (> dir 0)(car yex) (cdr yex)))
+ (uplist
+ (map pair-to-list
+ (normalize-coords coords lenx (* leny 2) dir))))
+
+ (ly:stencil-translate
+ (my-c-p-s uplist used-thick)
+ (cons xtrans ytrans)))
+ '())))
+
+#(define flare-tie
+ (flared-tie '((0 . 0)(0.1 . 0.2) (0.9 . 0.2) (1.0 . 0.0))))
+
+\layout {
+ \context {
+ \Voice
+ \override Tie.stencil = #flare-tie
+ }
+}
+
+\paper { ragged-right = ##f }
+
+\relative c' {
+ a4~a
+ \override Tie.height-limit = 4
+ a'4~a
+ a'4~a
+ <a,, c e a c e a c e>~ q
+
+ \break
+
+ a'4~a
+ \once \override Tie.details.height-limit = 14
+ a4~a
+
+ \break
+
+ a4~a
+ \once \override Tie.details.height-limit = 0.5
+ a4~a
+
+ \break
+
+ a4~a
+ \shape #'((0 . 0) (0 . 0.4) (0 . 0.4) (0 . 0)) Tie
+ a4~a
+
+ \break
+
+ a4~a
+ \once \override Tie.stencil =
+ #(flared-tie '((0 . 0)(0.1 . 0.4) (0.9 . 0.4) (1.0 . 0.0)))
+ a4~a
+
+ a4~a
+ \once \override Tie.stencil =
+ #(flared-tie '((0 . 0)(0.06 . 0.1) (0.94 . 0.1) (1.0 . 0.0)))
+ a4~a
+}
changing-midi-output-to-one-channel-per-voice.ly
changing-the-tempo-without-a-metronome-mark.ly
creating-custom-dynamics-in-midi-output.ly
+customize-drumpitchnames,-drumstyletable-and-drumpitchtable-in-layout-and-midi.ly
demo-midiinstruments.ly
replacing-default-midi-instrument-equalization.ly
}
words = \lyricmode {
- Great is Thy faith- ful- ness,
+ Great is Thy faith -- ful -- ness,
}
\score {
adding-drum-parts.ly
+customize-drumpitchnames,-drumstyletable-and-drumpitchtable-in-layout-and-midi.ly
heavily-customized-polymetric-time-signatures.ly
jazz-combo-template.ly
percussion-beaters.ly
}
\score {
- \new GrandStaff <<
+ \new PianoStaff <<
\new Staff = upper { \new Voice = "singer" \upper }
\new Lyrics \lyricsto "singer" \text
\new Staff = lower { \lower }
>>
- \layout {
- \context {
- \GrandStaff
- \accepts "Lyrics"
- }
- \context {
- \Lyrics
- \consists "Bar_engraver"
- }
- }
+ \layout { }
\midi { }
}
coloring-notes-depending-on-their-pitch.ly
creating-a-sequence-of-notes-on-various-pitches.ly
creating-custom-key-signatures.ly
+customize-drumpitchnames,-drumstyletable-and-drumpitchtable-in-layout-and-midi.ly
forcing-a-clef-symbol-to-be-displayed.ly
generating-random-notes.ly
hiding-accidentals-on-tied-notes-at-the-start-of-a-new-system.ly
displaying-grob-ancestry.ly
drawing-boxes-around-grobs.ly
drawing-circles-around-various-objects.ly
+flat-ties.ly
generating-random-notes.ly
generating-whole-scores-also-book-parts-in-scheme-without-using-the-parser.ly
outputting-the-version-number.ly
making-an-object-invisible-with-the-transparent-property.ly
moving-dotted-notes-in-polyphony.ly
suppressing-warnings-for-clashing-note-columns.ly
+two--partcombine-pairs-on-one-staff.ly
controlling-the-placement-of-chord-fingerings.ly
creating-blank-staves.ly
custodes.ly
+customize-drumpitchnames,-drumstyletable-and-drumpitchtable-in-layout-and-midi.ly
demo-midiinstruments.ly
embedding-native-postscript-in-a--markup-block.ly
engravers-one-by-one.ly
display-bracket-with-only-one-staff-in-a-system.ly
extending-a-trillspanner.ly
extending-glissandi-across-repeats.ly
+flat-ties.ly
forcing-measure-width-to-adapt-to-metronomemarks-width.ly
glissandi-can-skip-grobs.ly
how-to-print-two-rehearsal-marks-above-and-below-the-same-barline-method-1.ly
time-signature-in-parentheses---method-3.ly
time-signature-in-parentheses.ly
tweaking-clef-properties.ly
+two--partcombine-pairs-on-one-staff.ly
use-square-bracket-at-the-start-of-a-staff-group.ly
using-autochange-with-more-than-one-voice.ly
vertical-aligned-staffgroups-without-connecting-systemstartbar.ly
extending-a-trillspanner.ly
extending-glissandi-across-repeats.ly
fine-tuning-pedal-brackets.ly
+flat-ties.ly
forcing-horizontal-shift-of-notes.ly
fret-diagrams-explained-and-developed.ly
generating-custom-flags.ly
--- /dev/null
+%% DO NOT EDIT this file manually; it is automatically
+%% generated from LSR http://lsr.di.unimi.it
+%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
+%% and then run scripts/auxiliar/makelsr.py
+%%
+%% This file is in the public domain.
+\version "2.19.22"
+
+\header {
+ lsrtags = "simultaneous-notes, staff-notation"
+
+ texidoc = "
+The @code{\\partcombine} function takes two music expressions each
+containing a part, and distributes them among four @code{Voice}s named
+@qq{two} @qq{one} @qq{solo} and @qq{chords} depending on when and how
+the parts merged into a common voice. The voices output from
+@code{\\partcombine} can have their layout properties adjusted in the
+usual way. Here we define extensions of @code{\\partcombine} to make
+it easier to put four voices on a staff.
+
+soprano = @{ d'4 | cis' b e' d'8 cis' | cis'2 b @} alto = @{ fis4 |
+e8 fis gis ais b4 b | b ais fis2 @} tenor = @{ a8 b | cis' dis' e'4 b8
+cis' d'4 | gis cis' dis'2 @} bass = @{ fis8 gis | a4 gis g fis | eis
+fis b,2 @}
+
+\\new Staff <<
+ \\key b\\minor
+ \\clef alto
+ \\partial 4
+ \\transpose b b'
+ \\partcombineUp \\soprano \\alto
+ \\partcombineDown \\tenor \\bass >>
+
+"
+ doctitle = "Two \\partcombine pairs on one staff"
+} % begin verbatim
+
+\layout {
+ \context {
+ \Staff
+ \accepts "VoiceBox"
+ }
+ \context {
+ \name "VoiceBox"
+ \type "Engraver_group"
+ \defaultchild "Voice"
+ \accepts "Voice"
+ }
+}
+
+partcombineUp =
+#(define-music-function (partOne partTwo)
+ (ly:music? ly:music?)
+"Take the music in @var{partOne} and @var{partTwo} and return
+a @code{VoiceBox} named @q{Up} containing @code{Voice}s
+that contain @var{partOne} and @var{partTwo} merged into one
+voice where feasible. This variant sets the default voicing
+in the output to use upward stems."
+#{
+ \new VoiceBox = "Up" <<
+ \context Voice = "one" { \voiceOne }
+ \context Voice = "two" { \voiceThree }
+ \context Voice = "shared" { \voiceOne }
+ \context Voice = "solo" { \voiceOne }
+ \partcombine #partOne #partTwo
+ >>
+#})
+
+partcombineDown = #
+(define-music-function (partOne partTwo)
+ (ly:music? ly:music?)
+"Take the music in @var{partOne} and @var{partTwo} and return
+a @code{VoiceBox} named @q{Down} containing @code{Voice}s
+that contain @var{partOne} and @var{partTwo} merged into one
+voice where feasible. This variant sets the default voicing
+in the output to use downward stems."
+#{
+ \new VoiceBox = "Down" <<
+ \set VoiceBox.soloText = #"Solo III"
+ \set VoiceBox.soloIIText = #"Solo IV"
+ \context Voice ="one" { \voiceFour }
+ \context Voice ="two" { \voiceTwo }
+ \context Voice ="shared" { \voiceFour }
+ \context Voice ="solo" { \voiceFour }
+ \partcombine #partOne #partTwo
+ >>
+#})
+
+soprano = { d'4 | cis' b e' d'8 cis' | cis'2 b }
+alto = { fis4 | e8 fis gis ais b4 b | b ais fis2 }
+tenor = { a8 b | cis' dis' e'4 b8 cis' d'4 | gis cis' dis'2 }
+bass = { fis8 gis | a4 gis g fis | eis fis b,2 }
+
+\new Staff <<
+ \key b\minor
+ \clef alto
+ \partial 4
+ \transpose b b'
+ \partcombineUp \soprano \alto
+ \partcombineDown \tenor \bass
+>>
@section Downloading
The primary download site for sourcecode is
-@uref{http://lilypond.org/download/}.
+@uref{http://lilypond.org/downloads/}.
@section Compilation
@itemize
@item @uref{http://lilypond.org/test, Comparisons between regression tests}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archive of all regression tests}
@end itemize
For regular, cross-staff, broken and kneed beams. Beaming should depend
on context and neighbor notes (see section 2.2 of
-@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon,_Jean-Pierre%29,
+@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon%2C_Jean-Pierre%29,
this book}). If possible also reduce beaming-computation time.
@strong{Difficulty:} medium
user-created examples, hints and tips.
@item
-@uref{http://benlemon.me/blog/music/lilypond/operation-lilypond/,Video Tutorials}:
+@uref{http://bit.ly/LilyPondBeginners,Video Tutorials}:
Ben Lemon, a LilyPond user, has created a range of video tutorials on
his blog and which are aimed at new users.
@c used for news about the upcoming release; see CG 10.2
@newsItem
-@subheading LilyPond 2.19.41 released @emph{May 1, 2016}
+@subheading LilyPond 2.19.43 released @emph{June 8, 2016}
We are happy to announce the release of LilyPond
-2.19.41. This release includes a number of enhancements, and contains some
+2.19.43. This release includes a number of enhancements, and contains some
work in progress. You will have access to the very latest features, but
some may be incomplete, and you may encounter bugs and crashes. If you
require a stable version of Lilypond, we recommend using the 2.18
and numerous other contributors.
@newsEnd
-
-@newsItem
-@subheading LilyPond blog. @emph{June 2, 2013}
-
-Janek Warchoł has created a LilyPond blog. You can find it at
-@uref{http://lilypondblog.org/, lilypondblog.org}!
-
-@newsEnd
-
-@newsItem
-@subheading LilyPond 2.16.2 released! @emph{January 4, 2013}
-
-We are happy to announce the release of LilyPond 2.16.2. This release is mainly
-to correct a problem with lilypond-book running on Windows. We recommend that
-only people requiring this functionality upgrade to this version.
-
-@newsEnd
-
-@newsItem
-@subheading The LilyPond Report #28. @emph{November 12, 2012}
-
-The @uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?The-LilyPond-Report-28, October
-issue of the @emph{LilyPond Report}} focuses on the
-@uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?LilyPond-meeting-in-Waltrop,
-meeting of LilyPond developers and users} in Waltrop, Germany last
-August. Of course, there are also some musings on LilyPond
-triggered by the release of 2.16.0 and 2.17.0 occuring from that
-venue.
-
-There are also two monthly financial reports from David Kastrup
-whose work on LilyPond is
-@uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?The-LilyPond-Report-24#an_urgent_request_for_funding,
-solely paid for} by financial contributions from other developer
-and users (thank you!), and a report about experiences from
-@uref{http://scorio.com, a web-based music typesetting service}
-using LilyPond internally.
-
-Come @uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?The-LilyPond-Report-28, read
-LilyPond Report 28} now; comments and contributions are warmly
-encouraged!
-@newsEnd
-
-@newsItem
-@subheading LilyPond 2.16.1 released! @emph{November 9, 2012}
-
-We are happy to announce the release of LilyPond 2.16.1. This has a number of
-updates to the previous stable version, and should cause no problems. We
-recommend that everybody upgrade to this version.
-@newsEnd
-
-@newsItem
-@subheading Lilypond 2.16.0 released! @emph{August 24, 2012}
-
-We are proud to announce the release of GNU LilyPond 2.16.1.
-LilyPond is a music engraving program, devoted to producing the
-highest-quality sheet music possible. It brings the aesthetics of
-traditionally engraved music to computer printouts.
-
-Many improvements have been made in the past year since the previous
-main stable version. A few major improvements are:
-
-@itemize
-@item
-Support for kievan square notation
-@item
-User and programming interfaces have greatly improved
-@item
-Music functions have become quite more versatile
-@end itemize
-
-A full list of new features is given in:
-
-@example
-@uref{http://lilypond.org/doc/v2.16/Documentation/changes/index.html}
-@end example
-
-Happy music typesetting! LilyPond 2.16 was brought to you by...
-
-Main development team:
-
-Bertrand Bordage, Trevor Daniels, Colin Hall, Phil Holmes, Ian Hulin,
-Reinhold Kainhofer, David Kastrup, Jonathan Kulp, Werner Lemberg,
-John Mandereau, Patrick McCarty, Joe Neeman, Han-Wen Nienhuys,
-Jan Nieuwenhuizen, Graham Percival, Mark Polesky, Neil Puttock,
-Mike Solomon, Carl Sorensen, Francisco Vila, Valentin Villenave,
-Jan Warchoł
-
-Programming contributors:
-
-Aleksandr Andreev, Sven Axelsson, Peter Chubb, Karin Hoethker,
-Marc Hohl, David Nalesnik, Justin Ohmie, Benkő Pál, Julien Rioux, Patrick Schmidt,
-Adam Spiers, Heikki Taurainen, Piers Titus van der Torren,
-Jan-Peter Voigt, Janek Warchol
-
-Documentation contributors:
-
-James Lowe, Pavel Roskin, Alberto Simoes, Stefan Weil
-
-Bug squad:
-
-Colin Campbell, Eluze, Phil Holmes, Marek Klein, Ralph Palmer,
-James Lowe
-
-Support:
-
-Colin Campbell, Christian Hitz, Phil Holmes
-
-Translation contributors:
-
-Jean-Charles Malahieude, Till Paala, Yoshiki Sawada
-
-@newsEnd
* don't duplicate entries from news-front.itexi
@end ignore
+@newsItem
+@subheading LilyPond 2.19.42 released @emph{May 15, 2016}
+
+We are happy to announce the release of LilyPond
+2.19.42. This release includes a number of enhancements, and contains some
+work in progress. You will have access to the very latest features, but
+some may be incomplete, and you may encounter bugs and crashes. If you
+require a stable version of Lilypond, we recommend using the 2.18
+version.
+
+@newsEnd
+
+@newsItem
+@subheading LilyPond 2.19.41 released @emph{May 1, 2016}
+
+We are happy to announce the release of LilyPond
+2.19.41. This release includes a number of enhancements, and contains some
+work in progress. You will have access to the very latest features, but
+some may be incomplete, and you may encounter bugs and crashes. If you
+require a stable version of Lilypond, we recommend using the 2.18
+version.
+
+@newsEnd
+
@newsItem
@subheading LilyPond 2.19.40 released @emph{April 17, 2016}
@newsEnd
+@newsItem
+@subheading LilyPond blog. @emph{June 2, 2013}
+
+Janek Warchoł has created a LilyPond blog. You can find it at
+@uref{http://lilypondblog.org/, lilypondblog.org}!
+
+@newsEnd
+
@newsItem
@subheading LilyPond 2.17.19 released! @emph{May 26, 2013}
@newsEnd
+@newsItem
+@subheading LilyPond 2.16.2 released! @emph{January 4, 2013}
+
+We are happy to announce the release of LilyPond 2.16.2. This release is mainly
+to correct a problem with lilypond-book running on Windows. We recommend that
+only people requiring this functionality upgrade to this version.
+
+@newsEnd
+
@newsItem
@subheading LilyPond 2.17.9 released! @emph{December 15, 2012}
@newsEnd
+@newsItem
+@subheading The LilyPond Report #28. @emph{November 12, 2012}
+
+The @uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?The-LilyPond-Report-28, October
+issue of the @emph{LilyPond Report}} focuses on the
+@uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?LilyPond-meeting-in-Waltrop,
+meeting of LilyPond developers and users} in Waltrop, Germany last
+August. Of course, there are also some musings on LilyPond
+triggered by the release of 2.16.0 and 2.17.0 occuring from that
+venue.
+
+There are also two monthly financial reports from David Kastrup
+whose work on LilyPond is
+@uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?The-LilyPond-Report-24#an_urgent_request_for_funding,
+solely paid for} by financial contributions from other developer
+and users (thank you!), and a report about experiences from
+@uref{http://scorio.com, a web-based music typesetting service}
+using LilyPond internally.
+
+Come @uref{http://web.archive.org/web/20110325004849/http://news.lilynet.net/?The-LilyPond-Report-28, read
+LilyPond Report 28} now; comments and contributions are warmly
+encouraged!
+@newsEnd
+
@newsItem
@subheading LilyPond 2.16.1 released! @emph{November 9, 2012}
traditionally engraved music to computer printouts.
Many improvements have been made in the past year since the previous
-main stable version. A few major improvements are:
+main stable version. A few major improvements are:
@itemize
@item
@item
User and programming interfaces have greatly improved
@item
-Music functions have become quite more versatile
+Music functions have become quite more versatile
@end itemize
A full list of new features is given in:
Translation contributors:
-Jean-Charles Malahieude, Till Paala, Yoshiki Sawada
+Jean-Charles Malahieude, Till Paala, Yoshiki Sawada
@newsEnd
Release 2.11.28 is now available as a binary installer for
FreeBSD x86_64. Download
-@uref{http://lilypond.org/download/binaries/freebsd-64/,the installer} and
+@uref{http://lilypond.org/downloads/binaries/freebsd-64/,the installer} and
do @emph{sh lilypond-2.11.28-1.freebsd-64.sh} in a command window.
@newsEnd
Starting with 2.7.26, the development team has been working on the
installers. We're proud to announce another version of these: they are
now available for
-@uref{http://lilypond.org/download/binaries/linux-x86/,
+@uref{http://lilypond.org/downloads/binaries/linux-x86/,
Linux/x86},
-@uref{http://lilypond.org/download/binaries/darwin-ppc/,
+@uref{http://lilypond.org/downloads/binaries/darwin-ppc/,
MacOS X} and
-@uref{http://lilypond.org/download/binaries/mingw/,
+@uref{http://lilypond.org/downloads/binaries/mingw/,
Windows}.
@newsEnd
@itemize
@item @uref{http://lilypond.org/test, Comparisons between regression tests}
-@item @uref{http://lilypond.org/download/binaries/test-output/,
+@item @uref{http://lilypond.org/downloads/binaries/test-output/,
Archive of all regression tests}
@end itemize
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=19
-PATCH_LEVEL=42
+PATCH_LEVEL=44
MY_PATCH_LEVEL=
VERSION_STABLE=2.18.2
-VERSION_DEVEL=2.19.41
+VERSION_DEVEL=2.19.43
STEPMAKE_OPTIONAL_REQUIRED(CXX, c++, $1)
CXXFLAGS="$CXXFLAGS $OPTIMIZE"
- LD='$(CXX)'
AC_SUBST(CXX)
AC_SUBST(CXXFLAGS)
- AC_SUBST(LD)
])
update_local_key_signature (sig);
}
-ADD_ACKNOWLEDGER (Accidental_engraver, arpeggio);
-ADD_ACKNOWLEDGER (Accidental_engraver, finger);
-ADD_ACKNOWLEDGER (Accidental_engraver, rhythmic_head);
-ADD_END_ACKNOWLEDGER (Accidental_engraver, tie);
-ADD_ACKNOWLEDGER (Accidental_engraver, note_column);
+
+void
+Accidental_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Accidental_engraver, arpeggio);
+ ADD_ACKNOWLEDGER (Accidental_engraver, finger);
+ ADD_ACKNOWLEDGER (Accidental_engraver, rhythmic_head);
+ ADD_END_ACKNOWLEDGER (Accidental_engraver, tie);
+ ADD_ACKNOWLEDGER (Accidental_engraver, note_column);
+}
ADD_TRANSLATOR (Accidental_engraver,
/* doc */
#include "scm-hash.hh"
#include "warn.hh"
-const char * const All_font_metrics::type_p_name_ = 0;
-
Index_to_charcode_map const *
All_font_metrics::get_index_to_charcode_map (const string &filename,
int face_index,
public:
TRANSLATOR_DECLARATIONS (Ambitus_engraver);
protected:
- DECLARE_ACKNOWLEDGER (note_head);
+ void acknowledge_note_head (Grob_info);
void process_music ();
void stop_translation_timestep ();
}
}
-ADD_ACKNOWLEDGER (Ambitus_engraver, note_head);
+void
+Ambitus_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Ambitus_engraver, note_head);
+}
+
ADD_TRANSLATOR (Ambitus_engraver,
/* doc */
"Create an ambitus.",
protected:
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (arpeggio);
+ void listen_arpeggio (Stream_event *);
private:
Item *arpeggio_;
Stream_event *arpeggio_event_;
arpeggio_event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Arpeggio_engraver, arpeggio);
void Arpeggio_engraver::listen_arpeggio (Stream_event *ev)
{
ASSIGN_EVENT_ONCE (arpeggio_event_, ev);
arpeggio_event_ = 0;
}
-ADD_ACKNOWLEDGER (Arpeggio_engraver, stem);
-ADD_ACKNOWLEDGER (Arpeggio_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Arpeggio_engraver, note_column);
+
+void
+Arpeggio_engraver::boot ()
+{
+ ADD_LISTENER (Arpeggio_engraver, arpeggio);
+ ADD_ACKNOWLEDGER (Arpeggio_engraver, stem);
+ ADD_ACKNOWLEDGER (Arpeggio_engraver, rhythmic_head);
+ ADD_ACKNOWLEDGER (Arpeggio_engraver, note_column);
+}
ADD_TRANSLATOR (Arpeggio_engraver,
/* doc */
virtual void finalize ();
virtual void derived_mark () const;
- DECLARE_ACKNOWLEDGER (rest);
- DECLARE_ACKNOWLEDGER (beam);
- DECLARE_ACKNOWLEDGER (bar_line);
- DECLARE_ACKNOWLEDGER (breathing_sign);
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_TRANSLATOR_LISTENER (beam_forbid);
+public:
+ void acknowledge_rest (Grob_info);
+ void acknowledge_beam (Grob_info);
+ void acknowledge_bar_line (Grob_info);
+ void acknowledge_breathing_sign (Grob_info);
+ void acknowledge_stem (Grob_info);
+ void listen_beam_forbid (Stream_event *);
private:
virtual bool test_moment (Direction, Moment, Moment);
beam_settings_ = SCM_EOL;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Auto_beam_engraver, beam_forbid);
void
Auto_beam_engraver::listen_beam_forbid (Stream_event *ev)
{
process_acknowledged_count_++;
}
-ADD_ACKNOWLEDGER (Auto_beam_engraver, stem);
-ADD_ACKNOWLEDGER (Auto_beam_engraver, bar_line);
-ADD_ACKNOWLEDGER (Auto_beam_engraver, beam);
-ADD_ACKNOWLEDGER (Auto_beam_engraver, breathing_sign);
-ADD_ACKNOWLEDGER (Auto_beam_engraver, rest);
+void
+Auto_beam_engraver::boot ()
+{
+ ADD_LISTENER (Auto_beam_engraver, beam_forbid);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, stem);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, bar_line);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, beam);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, breathing_sign);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, rest);
+}
+
ADD_TRANSLATOR (Auto_beam_engraver,
/* doc */
"Generate beams based on measure characteristics and observed"
class Grace_auto_beam_engraver : public Auto_beam_engraver
{
TRANSLATOR_DECLARATIONS (Grace_auto_beam_engraver);
- DECLARE_TRANSLATOR_LISTENER (beam_forbid);
+ TRANSLATOR_INHERIT (Auto_beam_engraver);
private:
Moment last_grace_start_; // Full starting time of last grace group
// not considered.
}
-IMPLEMENT_TRANSLATOR_LISTENER (Grace_auto_beam_engraver, beam_forbid);
-void
-Grace_auto_beam_engraver::listen_beam_forbid (Stream_event *ev)
-{
- Auto_beam_engraver::listen_beam_forbid (ev);
-}
-
bool
Grace_auto_beam_engraver::is_same_grace_state (Moment, Moment)
{
return !test_mom.grace_part_;
}
-ADD_ACKNOWLEDGER (Grace_auto_beam_engraver, stem);
-ADD_ACKNOWLEDGER (Grace_auto_beam_engraver, bar_line);
-ADD_ACKNOWLEDGER (Grace_auto_beam_engraver, beam);
-ADD_ACKNOWLEDGER (Grace_auto_beam_engraver, breathing_sign);
-ADD_ACKNOWLEDGER (Grace_auto_beam_engraver, rest);
+void
+Grace_auto_beam_engraver::boot ()
+{
+ ADD_LISTENER (Auto_beam_engraver, beam_forbid);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, stem);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, bar_line);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, beam);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, breathing_sign);
+ ADD_ACKNOWLEDGER (Auto_beam_engraver, rest);
+}
+
ADD_TRANSLATOR (Grace_auto_beam_engraver,
/* doc */
"Generates one autobeam group across an entire grace phrase. "
void process_music ();
virtual void initialize ();
virtual void finalize ();
- DECLARE_ACKNOWLEDGER (grob);
+ void acknowledge_grob (Grob_info);
void process_acknowledged ();
virtual Spanner *get_spanner ();
virtual void add_element (Grob *);
Axis_group_interface::add_element (staffline_, e);
}
-ADD_ACKNOWLEDGER (Axis_group_engraver, grob);
+
+void
+Axis_group_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Axis_group_engraver, grob);
+}
ADD_TRANSLATOR (Axis_group_engraver,
/* doc */
{
SCM axes = me->get_property ("axes");
- return (SCM_BOOL_F != scm_memq (scm_from_int (a), axes));
+ return scm_is_true (scm_memq (scm_from_int (a), axes));
}
Interval
{
TRANSLATOR_DECLARATIONS (Balloon_engraver);
- DECLARE_TRANSLATOR_LISTENER (annotate_output);
- DECLARE_ACKNOWLEDGER (grob);
+ void listen_annotate_output (Stream_event *);
+ void acknowledge_grob (Grob_info);
vector<Stream_event *> events_;
void stop_translation_timestep ();
void balloonify (Grob *, Stream_event *);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Balloon_engraver, annotate_output);
void
Balloon_engraver::listen_annotate_output (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Balloon_engraver, grob);
+
+void
+Balloon_engraver::boot ()
+{
+ ADD_LISTENER (Balloon_engraver, annotate_output);
+ ADD_ACKNOWLEDGER (Balloon_engraver, grob);
+}
ADD_TRANSLATOR (Balloon_engraver,
/* doc */
void stop_translation_timestep ();
void process_acknowledged ();
- DECLARE_END_ACKNOWLEDGER (spanner);
+ void acknowledge_end_spanner (Grob_info);
private:
void create_bar ();
spanners_.push_back (dynamic_cast<Spanner *> (g));
}
-ADD_END_ACKNOWLEDGER (Bar_engraver, spanner);
+
+void
+Bar_engraver::boot ()
+{
+ ADD_END_ACKNOWLEDGER (Bar_engraver, spanner);
+}
ADD_TRANSLATOR (Bar_engraver,
/* doc */
protected:
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (alternative);
- DECLARE_ACKNOWLEDGER (break_alignment);
+ void listen_alternative (Stream_event *);
+ void acknowledge_break_alignment (Grob_info);
void process_music ();
void create_items ();
TRANSLATOR_DECLARATIONS (Bar_number_engraver);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Bar_number_engraver, alternative);
void
Bar_number_engraver::listen_alternative (Stream_event *ev)
{
text_ = make_item ("BarNumber", SCM_EOL);
}
-ADD_ACKNOWLEDGER (Bar_number_engraver, break_alignment);
+
+void
+Bar_number_engraver::boot ()
+{
+ ADD_LISTENER (Bar_number_engraver, alternative);
+ ADD_ACKNOWLEDGER (Bar_number_engraver, break_alignment);
+}
ADD_TRANSLATOR (Bar_number_engraver,
/* doc */
vector<Grob_info> beams_;
vector<Grob_info> covered_grobs_;
- DECLARE_ACKNOWLEDGER (note_head);
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (accidental);
- DECLARE_ACKNOWLEDGER (clef);
- DECLARE_ACKNOWLEDGER (clef_modifier);
- DECLARE_ACKNOWLEDGER (key_signature);
- DECLARE_ACKNOWLEDGER (time_signature);
- DECLARE_ACKNOWLEDGER (beam);
- DECLARE_ACKNOWLEDGER (flag);
+ void acknowledge_note_head (Grob_info);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_accidental (Grob_info);
+ void acknowledge_clef (Grob_info);
+ void acknowledge_clef_modifier (Grob_info);
+ void acknowledge_key_signature (Grob_info);
+ void acknowledge_time_signature (Grob_info);
+ void acknowledge_beam (Grob_info);
+ void acknowledge_flag (Grob_info);
virtual void finalize ();
#include "translator.icc"
-ADD_ACKNOWLEDGER (Beam_collision_engraver, note_head);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, stem);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, accidental);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, clef);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, key_signature);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, time_signature);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, clef_modifier);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, flag);
-ADD_ACKNOWLEDGER (Beam_collision_engraver, beam);
+
+void
+Beam_collision_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, note_head);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, stem);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, accidental);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, clef);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, key_signature);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, time_signature);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, clef_modifier);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, flag);
+ ADD_ACKNOWLEDGER (Beam_collision_engraver, beam);
+}
ADD_TRANSLATOR (Beam_collision_engraver,
/* doc */
class Beam_engraver : public Engraver
{
public:
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (rest);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_rest (Grob_info);
protected:
Stream_event *start_ev_;
virtual bool valid_start_point ();
virtual bool valid_end_point ();
- DECLARE_TRANSLATOR_LISTENER (beam);
+ void listen_beam (Stream_event *);
public:
TRANSLATOR_DECLARATIONS (Beam_engraver);
};
prev_start_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Beam_engraver, beam);
void
Beam_engraver::listen_beam (Stream_event *ev)
{
Beam::add_stem (beam_, stem);
}
-ADD_ACKNOWLEDGER (Beam_engraver, stem);
-ADD_ACKNOWLEDGER (Beam_engraver, rest);
+
+void
+Beam_engraver::boot ()
+{
+ ADD_LISTENER (Beam_engraver, beam);
+ ADD_ACKNOWLEDGER (Beam_engraver, stem);
+ ADD_ACKNOWLEDGER (Beam_engraver, rest);
+}
ADD_TRANSLATOR (Beam_engraver,
/* doc */
{
public:
TRANSLATOR_DECLARATIONS (Grace_beam_engraver);
-
- DECLARE_TRANSLATOR_LISTENER (beam);
+ TRANSLATOR_INHERIT (Beam_engraver);
+ void listen_beam (Stream_event *);
protected:
virtual bool valid_start_point ();
/*
Ugh, C&P code.
*/
-IMPLEMENT_TRANSLATOR_LISTENER (Grace_beam_engraver, beam);
void
Grace_beam_engraver::listen_beam (Stream_event *ev)
{
stop_ev_ = ev;
}
-ADD_ACKNOWLEDGER (Grace_beam_engraver, stem);
-ADD_ACKNOWLEDGER (Grace_beam_engraver, rest);
+
+void
+Grace_beam_engraver::boot ()
+{
+ ADD_LISTENER (Grace_beam_engraver, beam);
+ ADD_ACKNOWLEDGER (Beam_engraver, stem);
+ ADD_ACKNOWLEDGER (Beam_engraver, rest);
+}
ADD_TRANSLATOR (Grace_beam_engraver,
/* doc */
void start_translation_timestep ();
void process_music ();
void set_melisma (bool);
- DECLARE_TRANSLATOR_LISTENER (beam);
+ void listen_beam (Stream_event *);
private:
Stream_event *start_ev_;
Stream_event *now_stop_ev_;
now_stop_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Beam_performer, beam);
void
Beam_performer::listen_beam (Stream_event *ev)
{
now_stop_ev_ = ev;
}
+void
+Beam_performer::boot ()
+{
+ ADD_LISTENER (Beam_performer, beam);
+}
+
ADD_TRANSLATOR (Beam_performer,
/* doc */
"",
{
public:
TRANSLATOR_DECLARATIONS (Bend_engraver);
- DECLARE_ACKNOWLEDGER (note_head);
+ void acknowledge_note_head (Grob_info);
protected:
- DECLARE_TRANSLATOR_LISTENER (bend_after);
+ void listen_bend_after (Stream_event *);
void finalize ();
void process_music ();
void stop_translation_timestep ();
fall_event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Bend_engraver, bend_after);
void
Bend_engraver::listen_bend_after (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Bend_engraver, note_head);
+
+void
+Bend_engraver::boot ()
+{
+ ADD_LISTENER (Bend_engraver, bend_after);
+ ADD_ACKNOWLEDGER (Bend_engraver, note_head);
+}
ADD_TRANSLATOR (Bend_engraver,
/* doc */
}
-const char Book::type_p_name_[] = "ly:book?";
+const char * const Book::type_p_name_ = "ly:book?";
/****************************************************************/
-const char Box::type_p_name_[] = "ly:box?";
+const char * const Box::type_p_name_ = "ly:box?";
virtual void derived_mark () const;
public:
TRANSLATOR_DECLARATIONS (Break_align_engraver);
- DECLARE_ACKNOWLEDGER (break_aligned);
- DECLARE_ACKNOWLEDGER (break_alignable);
+ void acknowledge_break_aligned (Grob_info);
+ void acknowledge_break_alignable (Grob_info);
};
void
Axis_group_interface::add_element (group, item);
}
-ADD_ACKNOWLEDGER (Break_align_engraver, break_aligned);
-ADD_ACKNOWLEDGER (Break_align_engraver, break_alignable);
+void
+Break_align_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Break_align_engraver, break_aligned);
+ ADD_ACKNOWLEDGER (Break_align_engraver, break_alignable);
+}
+
ADD_TRANSLATOR (Break_align_engraver,
/* doc */
"Align grobs with corresponding @code{break-align-symbols}"
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (breathing);
+ void listen_breathing (Stream_event *);
private:
Stream_event *breathing_sign_event_;
Grob *breathing_sign_;
breathing_sign_event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Breathing_sign_engraver, breathing);
void
Breathing_sign_engraver::listen_breathing (Stream_event *ev)
{
breathing_sign_event_ = 0;
}
+void
+Breathing_sign_engraver::boot ()
+{
+ ADD_LISTENER (Breathing_sign_engraver, breathing);
+}
+
ADD_TRANSLATOR (Breathing_sign_engraver,
/* doc */
"Create a breathing sign.",
+++ /dev/null
-/*
- This file is part of LilyPond, the GNU music typesetter.
-
- Copyright (C) 2016 David Kastrup <dak@gnu.org>
-
- LilyPond is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- LilyPond is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "callback.hh"
-
-const char * const Callback_wrapper::type_p_name_ = 0;
void stop_translation_timestep ();
void process_music ();
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (note);
- DECLARE_TRANSLATOR_LISTENER (rest);
+ void listen_note (Stream_event *);
+ void listen_rest (Stream_event *);
private:
vector<Stream_event *> notes_;
context ()->set_property ("lastChord", markup);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, note);
void
Chord_name_engraver::listen_note (Stream_event *ev)
{
notes_.push_back (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, rest);
void
Chord_name_engraver::listen_rest (Stream_event *ev)
{
The READs description is not strictly accurate:
which properties are read depend on the chord naming function active.
*/
+void
+Chord_name_engraver::boot ()
+{
+ ADD_LISTENER (Chord_name_engraver, note);
+ ADD_LISTENER (Chord_name_engraver, rest);
+}
+
ADD_TRANSLATOR (Chord_name_engraver,
/* doc */
"Catch note and rest events and generate the appropriate chordname.",
protected:
virtual void finalize ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (tremolo_span);
- DECLARE_ACKNOWLEDGER (stem);
+ void listen_tremolo_span (Stream_event *);
+ void acknowledge_stem (Grob_info);
};
Chord_tremolo_engraver::Chord_tremolo_engraver ()
previous_stem_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Chord_tremolo_engraver, tremolo_span);
void
Chord_tremolo_engraver::listen_tremolo_span (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Chord_tremolo_engraver, stem);
+void
+Chord_tremolo_engraver::boot ()
+{
+ ADD_LISTENER (Chord_tremolo_engraver, tremolo_span);
+ ADD_ACKNOWLEDGER (Chord_tremolo_engraver, stem);
+}
+
ADD_TRANSLATOR (Chord_tremolo_engraver,
/* doc */
"Generate beams for tremolo repeats.",
protected:
void stop_translation_timestep ();
void process_music ();
- DECLARE_ACKNOWLEDGER (bar_line);
+ void acknowledge_bar_line (Grob_info);
virtual void derived_mark () const;
private:
}
}
-ADD_ACKNOWLEDGER (Clef_engraver, bar_line);
+void
+Clef_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Clef_engraver, bar_line);
+}
+
ADD_TRANSLATOR (Clef_engraver,
/* doc */
"Determine and set reference point for pitches.",
protected:
TRANSLATOR_DECLARATIONS (Cluster_spanner_engraver);
- DECLARE_TRANSLATOR_LISTENER (cluster_note);
- DECLARE_ACKNOWLEDGER (note_column);
+ void listen_cluster_note (Stream_event *);
+ void acknowledge_note_column (Grob_info);
void stop_translation_timestep ();
virtual void process_music ();
virtual void finalize ();
beacon_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Cluster_spanner_engraver, cluster_note);
void
Cluster_spanner_engraver::listen_cluster_note (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Cluster_spanner_engraver, note_column);
+void
+Cluster_spanner_engraver::boot ()
+{
+ ADD_LISTENER (Cluster_spanner_engraver, cluster_note);
+ ADD_ACKNOWLEDGER (Cluster_spanner_engraver, note_column);
+}
+
ADD_TRANSLATOR (Cluster_spanner_engraver,
/* doc */
"Engrave a cluster using @code{Spanner} notation.",
vector<Grob *> note_columns_;
protected:
- DECLARE_ACKNOWLEDGER (note_column);
+ void acknowledge_note_column (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
public:
col_ = 0;
}
-ADD_ACKNOWLEDGER (Collision_engraver, note_column);
+
+void
+Collision_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Collision_engraver, note_column);
+}
ADD_TRANSLATOR (Collision_engraver,
/* doc */
void start_translation_timestep ();
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (note);
+ void listen_note (Stream_event *);
};
void
is_first_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Completion_heads_engraver, note);
void
Completion_heads_engraver::listen_note (Stream_event *ev)
{
tie_column_ = 0;
}
+void
+Completion_heads_engraver::boot ()
+{
+ ADD_LISTENER (Completion_heads_engraver, note);
+}
+
ADD_TRANSLATOR (Completion_heads_engraver,
/* doc */
"This engraver replaces @code{Note_heads_engraver}. It plays"
void start_translation_timestep ();
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (rest);
+ void listen_rest (Stream_event *);
};
void
is_first_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Completion_rest_engraver, rest);
void
Completion_rest_engraver::listen_rest (Stream_event *ev)
{
{
}
+void
+Completion_rest_engraver::boot ()
+{
+ ADD_LISTENER (Completion_rest_engraver, rest);
+}
+
ADD_TRANSLATOR (Completion_rest_engraver,
/* doc */
"This engraver replaces @code{Rest_engraver}. It plays"
TRANSLATOR_DECLARATIONS (Concurrent_hairpin_engraver);
protected:
- DECLARE_ACKNOWLEDGER (hairpin);
- DECLARE_END_ACKNOWLEDGER (hairpin);
+ void acknowledge_hairpin (Grob_info);
+ void acknowledge_end_hairpin (Grob_info);
void stop_translation_timestep ();
void finalize ();
hairpins_hanging_out_.resize (0);
}
-ADD_ACKNOWLEDGER (Concurrent_hairpin_engraver, hairpin);
-ADD_END_ACKNOWLEDGER (Concurrent_hairpin_engraver, hairpin);
+
+void
+Concurrent_hairpin_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Concurrent_hairpin_engraver, hairpin);
+ ADD_END_ACKNOWLEDGER (Concurrent_hairpin_engraver, hairpin);
+}
ADD_TRANSLATOR (Concurrent_hairpin_engraver,
/* doc */
{
}
-const char Context_def::type_p_name_[] = "ly:context-def?";
+const char * const Context_def::type_p_name_ = "ly:context-def?";
int
Context_def::print_smob (SCM port, scm_print_state *) const
mods_ = scm_reverse (mod_list);
}
-const char Context_mod::type_p_name_[] = "ly:context-mod?";
+const char * const Context_mod::type_p_name_ = "ly:context-mod?";
int
Context_mod::print_smob (SCM port, scm_print_state *) const
{
public:
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
friend class Grob_property_info;
friend SCM ly_make_grob_properties (SCM);
cooked_ (alist), cooked_from_ (alist), nested_ (0) { }
};
-const char Grob_properties::type_p_name_[] = "ly:grob-properties?";
+const char * const Grob_properties::type_p_name_ = "ly:grob-properties?";
SCM
Grob_properties::mark_smob () const
ctx->check_removal ();
if (ctx->is_removable ())
{
- recurse_over_translators (ctx, &Translator::finalize,
- &Translator_group::finalize,
- UP);
+ recurse_over_translators
+ (ctx,
+ Callback0_wrapper::make_smob
+ <Translator, &Translator::finalize> (),
+ Callback0_wrapper::make_smob
+ <Translator_group, &Translator_group::finalize> (),
+ UP);
send_stream_event (ctx, "RemoveContext", 0, 0);
}
}
return properties_scm_;
}
-const char Context::type_p_name_[] = "ly:context?";
+const char * const Context::type_p_name_ = "ly:context?";
Global_context *
Context::get_global_context () const
add_text (Audio_text::TEXT, id_string);
}
+void
+Control_track_performer::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Control_track_performer,
/* doc */
"",
protected:
void stop_translation_timestep ();
void process_music ();
- DECLARE_ACKNOWLEDGER (bar_line);
+ void acknowledge_bar_line (Grob_info);
virtual void derived_mark () const;
private:
}
}
-ADD_ACKNOWLEDGER (Cue_clef_engraver, bar_line);
+void
+Cue_clef_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Cue_clef_engraver, bar_line);
+}
+
ADD_TRANSLATOR (Cue_clef_engraver,
/* doc */
"Determine and set reference point for pitches in cued voices.",
public:
TRANSLATOR_DECLARATIONS (Custos_engraver);
void start_translation_timestep ();
- DECLARE_ACKNOWLEDGER (bar);
- DECLARE_ACKNOWLEDGER (note_head);
+ void acknowledge_bar (Grob_info);
+ void acknowledge_note_head (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
virtual void finalize ();
custodes_.clear ();
}
-ADD_ACKNOWLEDGER (Custos_engraver, bar);
-ADD_ACKNOWLEDGER (Custos_engraver, note_head);
+
+void
+Custos_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Custos_engraver, bar);
+ ADD_ACKNOWLEDGER (Custos_engraver, note_head);
+}
ADD_TRANSLATOR (Custos_engraver,
/* doc */
#include "translator.icc"
+void
+Default_bar_line_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Default_bar_line_engraver,
/* doc */
"This engraver determines what kind of automatic bar lines"
#include "warn.hh"
#include "lily-imports.hh"
-const char Dispatcher::type_p_name_[] = "ly:dispatcher?";
+const char * const Dispatcher::type_p_name_ = "ly:dispatcher?";
Dispatcher::~Dispatcher ()
{
protected:
- DECLARE_ACKNOWLEDGER (rhythmic_head);
+ void acknowledge_rhythmic_head (Grob_info);
void stop_translation_timestep ();
};
}
}
-ADD_ACKNOWLEDGER (Dot_column_engraver, rhythmic_head);
+void
+Dot_column_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Dot_column_engraver, rhythmic_head);
+}
+
ADD_TRANSLATOR (Dot_column_engraver,
/* doc */
"Engrave dots on dotted notes shifted to the right of the"
class Dots_engraver : public Engraver
{
- DECLARE_ACKNOWLEDGER (rhythmic_head);
+ void acknowledge_rhythmic_head (Grob_info);
TRANSLATOR_DECLARATIONS (Dots_engraver);
};
}
}
-ADD_ACKNOWLEDGER (Dots_engraver, rhythmic_head);
+
+void
+Dots_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Dots_engraver, rhythmic_head);
+}
ADD_TRANSLATOR (Dots_engraver,
"Create @ref{Dots} objects for"
// moment (global time) where percent started
Moment start_mom_;
- DECLARE_TRANSLATOR_LISTENER (double_percent);
+ void listen_double_percent (Stream_event *);
void process_music ();
};
percent_event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Double_percent_repeat_engraver, double_percent);
void
Double_percent_repeat_engraver::listen_double_percent (Stream_event *ev)
{
}
}
+void
+Double_percent_repeat_engraver::boot ()
+{
+ ADD_LISTENER (Double_percent_repeat_engraver, double_percent);
+}
+
ADD_TRANSLATOR (Double_percent_repeat_engraver,
/* doc */
"Make double measure repeats.",
protected:
void process_music ();
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (note);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_note_column (Grob_info);
+ void listen_note (Stream_event *);
void stop_translation_timestep ();
};
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Drum_notes_engraver, note);
void
Drum_notes_engraver::listen_note (Stream_event *ev)
{
events_.clear ();
}
-ADD_ACKNOWLEDGER (Drum_notes_engraver, stem);
-ADD_ACKNOWLEDGER (Drum_notes_engraver, note_column);
+
+void
+Drum_notes_engraver::boot ()
+{
+ ADD_LISTENER (Drum_notes_engraver, note);
+ ADD_ACKNOWLEDGER (Drum_notes_engraver, stem);
+ ADD_ACKNOWLEDGER (Drum_notes_engraver, note_column);
+}
ADD_TRANSLATOR (Drum_notes_engraver,
/* doc */
protected:
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (note);
+ void listen_note (Stream_event *);
private:
vector<Stream_event *> note_evs_;
};
note_evs_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Drum_note_performer, note);
void
Drum_note_performer::listen_note (Stream_event *ev)
{
note_evs_.push_back (ev);
}
+void
+Drum_note_performer::boot ()
+{
+ ADD_LISTENER (Drum_note_performer, note);
+}
+
ADD_TRANSLATOR (Drum_note_performer,
/* doc */
"Play drum notes.",
return s;
}
-const char Duration::type_p_name_[] = "ly:duration?";
+const char * const Duration::type_p_name_ = "ly:duration?";
int
class Dynamic_align_engraver : public Engraver
{
TRANSLATOR_DECLARATIONS (Dynamic_align_engraver);
- DECLARE_ACKNOWLEDGER (rhythmic_head);
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (dynamic);
- DECLARE_ACKNOWLEDGER (footnote_spanner);
- DECLARE_END_ACKNOWLEDGER (dynamic);
+ void acknowledge_rhythmic_head (Grob_info);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_dynamic (Grob_info);
+ void acknowledge_footnote_spanner (Grob_info);
+ void acknowledge_end_dynamic (Grob_info);
protected:
virtual void stop_translation_timestep ();
current_dynamic_spanner_ = 0;
}
-ADD_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
-ADD_ACKNOWLEDGER (Dynamic_align_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Dynamic_align_engraver, stem);
-ADD_ACKNOWLEDGER (Dynamic_align_engraver, footnote_spanner);
-ADD_END_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
void
Dynamic_align_engraver::create_line_spanner (Grob *cause)
support_.clear ();
}
+void
+Dynamic_align_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, rhythmic_head);
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, stem);
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, footnote_spanner);
+ ADD_END_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
+}
+
ADD_TRANSLATOR (Dynamic_align_engraver,
/* doc */
"Align hairpins and dynamic texts on a horizontal line.",
class Dynamic_engraver : public Engraver
{
TRANSLATOR_DECLARATIONS (Dynamic_engraver);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (absolute_dynamic);
- DECLARE_TRANSLATOR_LISTENER (span_dynamic);
- DECLARE_TRANSLATOR_LISTENER (break_span);
+ void acknowledge_note_column (Grob_info);
+ void listen_absolute_dynamic (Stream_event *);
+ void listen_span_dynamic (Stream_event *);
+ void listen_break_span (Stream_event *);
protected:
virtual void process_music ();
end_new_spanner_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_engraver, absolute_dynamic);
void
Dynamic_engraver::listen_absolute_dynamic (Stream_event *ev)
{
ASSIGN_EVENT_ONCE (script_event_, ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_engraver, span_dynamic);
void
Dynamic_engraver::listen_span_dynamic (Stream_event *ev)
{
ASSIGN_EVENT_ONCE (accepted_spanevents_drul_[d], ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_engraver, break_span);
void
Dynamic_engraver::listen_break_span (Stream_event *event)
{
finished_spanner_->set_bound (RIGHT, info.grob ());
}
-ADD_ACKNOWLEDGER (Dynamic_engraver, note_column);
+void
+Dynamic_engraver::boot ()
+{
+ ADD_LISTENER (Dynamic_engraver, absolute_dynamic);
+ ADD_LISTENER (Dynamic_engraver, span_dynamic);
+ ADD_LISTENER (Dynamic_engraver, break_span);
+ ADD_ACKNOWLEDGER (Dynamic_engraver, note_column);
+}
+
ADD_TRANSLATOR (Dynamic_engraver,
/* doc */
"Create hairpins, dynamic texts and dynamic text spanners.",
void process_music ();
Real equalize_volume (Real);
- DECLARE_TRANSLATOR_LISTENER (decrescendo);
- DECLARE_TRANSLATOR_LISTENER (crescendo);
- DECLARE_TRANSLATOR_LISTENER (absolute_dynamic);
+ void listen_decrescendo (Stream_event *);
+ void listen_crescendo (Stream_event *);
+ void listen_absolute_dynamic (Stream_event *);
private:
Stream_event *script_event_;
Drul_array<Stream_event *> span_events_;
= span_events_[RIGHT] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_performer, decrescendo);
void
Dynamic_performer::listen_decrescendo (Stream_event *r)
{
grow_dir_[d] = SMALLER;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_performer, crescendo);
void
Dynamic_performer::listen_crescendo (Stream_event *r)
{
grow_dir_[d] = BIGGER;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_performer, absolute_dynamic);
void
Dynamic_performer::listen_absolute_dynamic (Stream_event *r)
{
script_event_ = r;
}
+void
+Dynamic_performer::boot ()
+{
+ ADD_LISTENER (Dynamic_performer, decrescendo);
+ ADD_LISTENER (Dynamic_performer, crescendo);
+ ADD_LISTENER (Dynamic_performer, absolute_dynamic);
+}
+
ADD_TRANSLATOR (Dynamic_performer,
/* doc */
"",
{
return unsmob<Grob> (obj) || unsmob<Stream_event> (obj) || scm_is_null (obj);
}
-
-#include "translator.icc"
-
-ADD_TRANSLATOR (Engraver,
- /* doc */
- "Base class for engravers. Does nothing, so it is not used.",
-
- /* create */
- "",
-
- /* read */
- "",
-
- /* write */
- ""
- );
-
TRANSLATOR_DECLARATIONS (Episema_engraver);
protected:
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (episema);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (note_head);
+ void listen_episema (Stream_event *);
+ void acknowledge_note_column (Grob_info);
+ void acknowledge_note_head (Grob_info);
void stop_translation_timestep ();
void process_music ();
event_drul_.set (0, 0);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Episema_engraver, episema);
void
Episema_engraver::listen_episema (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Episema_engraver, note_column);
-ADD_ACKNOWLEDGER (Episema_engraver, note_head);
+
+void
+Episema_engraver::boot ()
+{
+ ADD_LISTENER (Episema_engraver, episema);
+ ADD_ACKNOWLEDGER (Episema_engraver, note_column);
+ ADD_ACKNOWLEDGER (Episema_engraver, note_head);
+}
ADD_TRANSLATOR (Episema_engraver,
/* doc */
TRANSLATOR_DECLARATIONS (Extender_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (extender);
- DECLARE_TRANSLATOR_LISTENER (completize_extender);
- DECLARE_ACKNOWLEDGER (lyric_syllable);
+ void listen_extender (Stream_event *);
+ void listen_completize_extender (Stream_event *);
+ void acknowledge_lyric_syllable (Grob_info);
virtual void finalize ();
ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Extender_engraver, extender);
void
Extender_engraver::listen_extender (Stream_event *ev)
{
end before the associated voice (this prevents the right bound being extended
to the next note-column if no lyric follows the extender)
*/
-IMPLEMENT_TRANSLATOR_LISTENER (Extender_engraver, completize_extender);
void
Extender_engraver::listen_completize_extender (Stream_event * /* ev */)
{
}
}
-ADD_ACKNOWLEDGER (Extender_engraver, lyric_syllable);
+void
+Extender_engraver::boot ()
+{
+ ADD_LISTENER (Extender_engraver, extender);
+ ADD_LISTENER (Extender_engraver, completize_extender);
+ ADD_ACKNOWLEDGER (Extender_engraver, lyric_syllable);
+}
+
ADD_TRANSLATOR (Extender_engraver,
/* doc */
"Create lyric extenders.",
Moment stop_moment_;
bool have_rest_;
- DECLARE_TRANSLATOR_LISTENER (rest);
- DECLARE_TRANSLATOR_LISTENER (bass_figure);
+ void listen_rest (Stream_event *);
+ void listen_bass_figure (Stream_event *);
virtual void derived_mark () const;
clear_spanners ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, rest);
void
Figured_bass_engraver::listen_rest (Stream_event *)
{
have_rest_ = true;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, bass_figure);
void
Figured_bass_engraver::listen_bass_figure (Stream_event *ev)
{
}
}
+void
+Figured_bass_engraver::boot ()
+{
+ ADD_LISTENER (Figured_bass_engraver, rest);
+ ADD_LISTENER (Figured_bass_engraver, bass_figure);
+}
+
ADD_TRANSLATOR (Figured_bass_engraver,
/* doc */
"Make figured bass numbers.",
vector<Grob *> support_;
vector<Grob *> span_support_;
protected:
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (slur);
- DECLARE_END_ACKNOWLEDGER (slur);
- DECLARE_END_ACKNOWLEDGER (tie);
- DECLARE_ACKNOWLEDGER (bass_figure_alignment);
- DECLARE_END_ACKNOWLEDGER (bass_figure_alignment);
+ void acknowledge_note_column (Grob_info);
+ void acknowledge_slur (Grob_info);
+ void acknowledge_end_slur (Grob_info);
+ void acknowledge_end_tie (Grob_info);
+ void acknowledge_bass_figure_alignment (Grob_info);
+ void acknowledge_end_bass_figure_alignment (Grob_info);
virtual void finalize ();
void start_spanner ();
start_spanner ();
}
-ADD_ACKNOWLEDGER (Figured_bass_position_engraver, note_column);
-ADD_ACKNOWLEDGER (Figured_bass_position_engraver, slur);
-ADD_END_ACKNOWLEDGER (Figured_bass_position_engraver, slur);
-ADD_END_ACKNOWLEDGER (Figured_bass_position_engraver, tie);
-ADD_ACKNOWLEDGER (Figured_bass_position_engraver, bass_figure_alignment);
-ADD_END_ACKNOWLEDGER (Figured_bass_position_engraver, bass_figure_alignment);
+
+void
+Figured_bass_position_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Figured_bass_position_engraver, note_column);
+ ADD_ACKNOWLEDGER (Figured_bass_position_engraver, slur);
+ ADD_END_ACKNOWLEDGER (Figured_bass_position_engraver, slur);
+ ADD_END_ACKNOWLEDGER (Figured_bass_position_engraver, tie);
+ ADD_ACKNOWLEDGER (Figured_bass_position_engraver, bass_figure_alignment);
+ ADD_END_ACKNOWLEDGER (Figured_bass_position_engraver, bass_figure_alignment);
+}
ADD_TRANSLATOR (Figured_bass_position_engraver,
/* doc */
public:
TRANSLATOR_DECLARATIONS (Fingering_column_engraver);
protected:
- DECLARE_ACKNOWLEDGER (finger);
+ void acknowledge_finger (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
};
}
}
-ADD_ACKNOWLEDGER (Fingering_column_engraver, finger);
+void
+Fingering_column_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Fingering_column_engraver, finger);
+}
+
ADD_TRANSLATOR (Fingering_column_engraver,
/* doc */
"Find potentially colliding scripts and put them into a"
protected:
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (fingering);
- DECLARE_ACKNOWLEDGER (rhythmic_head);
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (flag);
+ void listen_fingering (Stream_event *);
+ void acknowledge_rhythmic_head (Grob_info);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_flag (Grob_info);
private:
void make_script (Direction, Stream_event *, int);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Fingering_engraver, fingering);
void
Fingering_engraver::listen_fingering (Stream_event *ev)
{
{
}
-ADD_ACKNOWLEDGER (Fingering_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Fingering_engraver, stem);
-ADD_ACKNOWLEDGER (Fingering_engraver, flag);
+
+void
+Fingering_engraver::boot ()
+{
+ ADD_LISTENER (Fingering_engraver, fingering);
+ ADD_ACKNOWLEDGER (Fingering_engraver, rhythmic_head);
+ ADD_ACKNOWLEDGER (Fingering_engraver, stem);
+ ADD_ACKNOWLEDGER (Fingering_engraver, flag);
+}
ADD_TRANSLATOR (Fingering_engraver,
/* doc */
return 1;
}
-const char Font_metric::type_p_name_[] = "ly:font-metric?";
+const char * const Font_metric::type_p_name_ = "ly:font-metric?";
SCM
Font_metric::font_file_name () const
TRANSLATOR_DECLARATIONS (Font_size_engraver);
protected:
- DECLARE_ACKNOWLEDGER (font);
+ void acknowledge_font (Grob_info);
void process_music ();
Real size;
private:
#include "translator.icc"
-ADD_ACKNOWLEDGER (Font_size_engraver, font);
+void
+Font_size_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Font_size_engraver, font);
+}
+
ADD_TRANSLATOR (Font_size_engraver,
/* doc */
"Put @code{fontSize} into @code{font-size} grob property.",
{
TRANSLATOR_DECLARATIONS (Footnote_engraver);
- DECLARE_ACKNOWLEDGER (grob);
- DECLARE_END_ACKNOWLEDGER (grob);
+ void acknowledge_grob (Grob_info);
+ void acknowledge_end_grob (Grob_info);
vector<Drul_array<Spanner *> > annotated_spanners_;
}
}
-ADD_ACKNOWLEDGER (Footnote_engraver, grob);
-ADD_END_ACKNOWLEDGER (Footnote_engraver, grob);
+
+void
+Footnote_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Footnote_engraver, grob);
+ ADD_END_ACKNOWLEDGER (Footnote_engraver, grob);
+}
ADD_TRANSLATOR (Footnote_engraver,
/* doc */
}
}
+void
+Forbid_line_break_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Forbid_line_break_engraver,
/* doc */
"Forbid line breaks when note heads are still playing at some"
void stop_translation_timestep ();
void process_music ();
virtual void derived_mark () const;
- DECLARE_TRANSLATOR_LISTENER (note);
- DECLARE_TRANSLATOR_LISTENER (string_number);
- DECLARE_TRANSLATOR_LISTENER (fingering);
+ void listen_note (Stream_event *);
+ void listen_string_number (Stream_event *);
+ void listen_fingering (Stream_event *);
private:
SCM last_placements_;
last_placements_ = SCM_BOOL_F;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, note);
void
Fretboard_engraver::listen_note (Stream_event *ev)
{
note_events_.push_back (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, string_number);
void
Fretboard_engraver::listen_string_number (Stream_event *ev)
{
tabstring_events_.push_back (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, fingering);
void
Fretboard_engraver::listen_fingering (Stream_event *ev)
{
fingering_events_.clear ();
}
+void
+Fretboard_engraver::boot ()
+{
+ ADD_LISTENER (Fretboard_engraver, note);
+ ADD_LISTENER (Fretboard_engraver, string_number);
+ ADD_LISTENER (Fretboard_engraver, fingering);
+}
+
ADD_TRANSLATOR (Fretboard_engraver,
/* doc */
"Generate fret diagram from one or more events of type"
TRANSLATOR_DECLARATIONS (Glissando_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (glissando);
- DECLARE_ACKNOWLEDGER (note_column);
+ void listen_glissando (Stream_event *);
+ void acknowledge_note_column (Grob_info);
virtual void finalize ();
void stop_translation_timestep ();
stop_glissandi_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Glissando_engraver, glissando);
void
Glissando_engraver::listen_glissando (Stream_event *ev)
{
kill_me_[i]->suicide ();
}
-ADD_ACKNOWLEDGER (Glissando_engraver, note_column);
+void
+Glissando_engraver::boot ()
+{
+ ADD_LISTENER (Glissando_engraver, glissando);
+ ADD_ACKNOWLEDGER (Glissando_engraver, note_column);
+}
+
ADD_TRANSLATOR (Glissando_engraver,
/* doc */
"Engrave glissandi.",
Engraver::derived_mark ();
}
+void
+Grace_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Grace_engraver,
/* doc */
"Set font size and other properties for grace notes.",
grace_spacing_ = 0;
}
+void
+Grace_spacing_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Grace_spacing_engraver,
"Bookkeeping of shortest starting and playing notes in grace"
" note runs.",
public:
TRANSLATOR_DECLARATIONS (Grid_line_span_engraver);
protected:
- DECLARE_ACKNOWLEDGER (grid_point);
+ void acknowledge_grid_point (Grob_info);
void stop_translation_timestep ();
};
lines_.resize (0);
}
-ADD_ACKNOWLEDGER (Grid_line_span_engraver, grid_point);
+void
+Grid_line_span_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Grid_line_span_engraver, grid_point);
+}
+
ADD_TRANSLATOR (Grid_line_span_engraver,
/* doc */
"This engraver makes cross-staff lines: It catches all normal"
{
}
+void
+Grid_point_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Grid_point_engraver,
/* doc */
"Generate grid points.",
filter_map (map_fun);
}
-const char Grob_array::type_p_name_[] = "ly:grob-array?";
+const char * const Grob_array::type_p_name_ = "ly:grob-array?";
SCM
TRANSLATOR_DECLARATIONS (Grob_pq_engraver);
protected:
virtual void initialize ();
- DECLARE_ACKNOWLEDGER (grob);
+ void acknowledge_grob (Grob_info);
void start_translation_timestep ();
void stop_translation_timestep ();
void process_acknowledged ();
context ()->set_property ("busyGrobs", busy);
}
-ADD_ACKNOWLEDGER (Grob_pq_engraver, grob);
+void
+Grob_pq_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Grob_pq_engraver, grob);
+}
+
ADD_TRANSLATOR (Grob_pq_engraver,
/* doc */
"Administrate when certain grobs (e.g., note heads) stop"
#include "warn.hh"
-const char Grob::type_p_name_[] = "ly:grob?";
+const char * const Grob::type_p_name_ = "ly:grob?";
SCM
Grob::mark_smob () const
void stop_translation_timestep ();
void process_music ();
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (note_grouping);
+ void acknowledge_note_column (Grob_info);
+ void listen_note_grouping (Stream_event *);
};
Horizontal_bracket_engraver::Horizontal_bracket_engraver ()
push_count_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Horizontal_bracket_engraver, note_grouping);
void
Horizontal_bracket_engraver::listen_note_grouping (Stream_event *ev)
{
events_.clear ();
}
-ADD_ACKNOWLEDGER (Horizontal_bracket_engraver, note_column);
+void
+Horizontal_bracket_engraver::boot ()
+{
+ ADD_LISTENER (Horizontal_bracket_engraver, note_grouping);
+ ADD_ACKNOWLEDGER (Horizontal_bracket_engraver, note_column);
+}
+
ADD_TRANSLATOR (Horizontal_bracket_engraver,
/* doc */
"Create horizontal brackets over notes for musical analysis"
protected:
- DECLARE_ACKNOWLEDGER (lyric_syllable);
- DECLARE_TRANSLATOR_LISTENER (hyphen);
+ void acknowledge_lyric_syllable (Grob_info);
+ void listen_hyphen (Stream_event *);
virtual void finalize ();
finished_hyphen_->set_bound (RIGHT, item);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Hyphen_engraver, hyphen);
void
Hyphen_engraver::listen_hyphen (Stream_event *ev)
{
ev_ = 0;
}
-ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable);
+
+void
+Hyphen_engraver::boot ()
+{
+ ADD_LISTENER (Hyphen_engraver, hyphen);
+ ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable);
+}
ADD_TRANSLATOR (Hyphen_engraver,
/* doc */
All_font_metrics (All_font_metrics const &);
public:
- static const char * const type_p_name_; // = 0
SCM mark_smob () const;
Index_to_charcode_map const *get_index_to_charcode_map (const string &filename,
{
public:
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Book ();
SCM header_;
Output_def *paper_;
class Box : public Simple_smob<Box>
{
public:
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
Interval interval_a_[NO_AXES];
public:
// this involves an adjustment of the this pointer from Smob_core to
// the scope containing the callback.
SCM (*trampoline_) (SCM, SCM);
- Callback_wrapper (SCM (*trampoline) (SCM, SCM)) : trampoline_ (trampoline)
+ Callback_wrapper (SCM (*trampoline) (SCM, SCM))
+ : trampoline_ (trampoline)
{ } // Private constructor, use only in make_smob
public:
- static const char * const type_p_name_; // = 0
LY_DECLARE_SMOB_PROC (&Callback_wrapper::call, 2, 0, 0)
SCM call (SCM target, SCM arg)
{
}
};
+class Callback2_wrapper : public Simple_smob<Callback2_wrapper>
+{
+ // See Callback_wrapper for the details. Callback2_wrapper just
+ // supports an additional SCM argument as compared to
+ // Callback_wrapper but is otherwise identical.
+ SCM (*trampoline_) (SCM, SCM, SCM);
+ Callback2_wrapper (SCM (*trampoline) (SCM, SCM, SCM))
+ : trampoline_ (trampoline)
+ { } // Private constructor, use only in make_smob
+public:
+ LY_DECLARE_SMOB_PROC (&Callback2_wrapper::call, 3, 0, 0)
+ SCM call (SCM target, SCM arg1, SCM arg2)
+ {
+ return trampoline_ (target, arg1, arg2);
+ }
+
+ template <SCM (*trampoline) (SCM, SCM, SCM)>
+ static SCM make_smob ()
+ {
+ static SCM res =
+ scm_permanent_object (Callback2_wrapper (trampoline).smobbed_copy ());
+ return res;
+ }
+};
+
+class Callback0_wrapper : public Simple_smob<Callback0_wrapper>
+{
+ // See Callback_wrapper for the details. Callback0_wrapper does not
+ // pass arguments but is otherwise identical to Callback_wrapper.
+ SCM (*trampoline_) (SCM);
+ Callback0_wrapper (SCM (*trampoline) (SCM))
+ : trampoline_ (trampoline)
+ { } // Private constructor, use only in make_smob
+public:
+ LY_DECLARE_SMOB_PROC (&Callback0_wrapper::call, 1, 0, 0)
+ SCM call (SCM target)
+ {
+ return trampoline_ (target);
+ }
+
+ template <SCM (*trampoline) (SCM)>
+ static SCM make_smob ()
+ {
+ static SCM res =
+ scm_permanent_object (Callback0_wrapper (trampoline).smobbed_copy ());
+ return res;
+ }
+ // Since there are no arguments at all, we might as well provide
+ // default trampolines
+ template <class T, SCM (T::*p)()>
+ static SCM trampoline (SCM target)
+ {
+ T *t = LY_ASSERT_SMOB (T, target, 1);
+ return (t->*p) ();
+ }
+
+ template <class T, void (T::*p)()>
+ static SCM trampoline (SCM target)
+ {
+ T *t = LY_ASSERT_SMOB (T, target, 1);
+ (t->*p) ();
+ return SCM_UNSPECIFIED;
+ }
+
+ template <class T, SCM (T::*p)()>
+ static SCM make_smob ()
+ {
+ return make_smob<trampoline<T, p> > ();
+ }
+
+ template <class T, void (T::*p)()>
+ static SCM make_smob ()
+ {
+ return make_smob<trampoline<T, p> > ();
+ }
+};
+
+// The following will usually be used unsmobbified, relying on its
+// constituents being protected independently.
+
+class Method_instance : public Simple_smob<Method_instance>
+{
+ SCM method_, instance_;
+public:
+ LY_DECLARE_SMOB_PROC (&Method_instance::call, 0, 0, 1)
+ SCM call (SCM rest)
+ {
+ return scm_apply_1 (method_, instance_, rest);
+ }
+
+ Method_instance (SCM method, SCM instance)
+ : method_ (method), instance_ (instance)
+ { }
+ Method_instance (SCM method, Smob_core *instance)
+ : method_ (method), instance_ (instance->self_scm ())
+ { }
+ SCM method () const { return method_; }
+ SCM instance () const { return instance_; }
+ SCM operator () () const
+ {
+ return scm_call_1 (method_, instance_);
+ }
+ SCM operator () (SCM arg) const
+ {
+ return scm_call_2 (method_, instance_, arg);
+ }
+ SCM operator () (SCM arg1, SCM arg2) const
+ {
+ return scm_call_3 (method_, instance_, arg1, arg2);
+ }
+ SCM mark_smob () const
+ {
+ scm_gc_mark (method_);
+ return instance_;
+ }
+};
#endif
public:
// no TRANSLATOR_DECLARATIONS (Coherent_ligature_engraver) needed
// since this class is abstract
+ TRANSLATOR_INHERIT (Ligature_engraver);
+ DECLARE_TRANSLATOR_CALLBACKS (Coherent_ligature_engraver);
protected:
virtual void build_ligature (Spanner *ligature,
{
SCM mark_smob () const;
int print_smob (SCM, scm_print_state *) const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Context_def ();
private:
/*
{
SCM mark_smob () const;
int print_smob (SCM, scm_print_state *) const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
SCM mods_;
public:
public:
SCM mark_smob () const;
int print_smob (SCM, scm_print_state *) const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Context ();
private:
Scheme_hash_table *properties_dict () const;
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Dispatcher ();
private:
/* Hash table. Each event-class maps to a list of listeners. */
{
static SCM equal_p (SCM, SCM);
int print_smob (SCM, scm_print_state *) const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
Duration ();
Duration (int, int);
Duration (Rational, bool scale);
#ifndef ENGRAVER_HH
#define ENGRAVER_HH
+#include "callback.hh"
+#include "grob.hh"
#include "grob-info.hh"
#include "translator.hh"
Engraver_group *get_daddy_engraver () const;
public:
+ template <class T, void (T::*callback)(Grob_info)>
+ static SCM ack_trampoline (SCM target, SCM grob, SCM source_engraver)
+ {
+ T *t = LY_ASSERT_SMOB (T, target, 1);
+ Grob *g = LY_ASSERT_SMOB (Grob, grob, 2);
+ Engraver *e = LY_ASSERT_SMOB (Engraver, source_engraver, 3);
+
+ (t->*callback) (Grob_info (e, g));
+ return SCM_UNSPECIFIED;
+ }
+
/**
Announce element. Default: pass on to daddy. Utility
*/
/**
override other ctor
*/
- TRANSLATOR_DECLARATIONS (Engraver);
+ DECLARE_CLASSNAME (Engraver);
+ DECLARE_TRANSLATOR_CALLBACKS (Engraver);
+ Engraver ();
};
#define make_item(x, cause) internal_make_item (ly_symbol2scm (x), cause, x, __FILE__, __LINE__, __FUNCTION__)
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Font_metric ();
private:
DECLARE_CLASSNAME (Font_metric);
Stream_event *pes_or_flexa_req_;
public:
+ void listen_pes_or_flexa (Stream_event *ev);
// no TRANSLATOR_DECLARATIONS (Gregorian_ligature_engraver) needed
// since this class is abstract
+ TRANSLATOR_INHERIT(Coherent_ligature_engraver);
+ DECLARE_TRANSLATOR_CALLBACKS (Gregorian_ligature_engraver);
protected:
Gregorian_ligature_engraver ();
- virtual void listen_pes_or_flexa (Stream_event *ev);
virtual void build_ligature (Spanner *ligature,
vector<Grob_info> const &primitives);
virtual void transform_heads (Spanner *ligature,
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
vector<Grob *> grobs_;
bool ordered_;
#define INTERFACE_HH
#include "lily-guile.hh"
+#include "protected-scm.hh"
class Grob;
friend bool has_interface(Grob *);
private:
- static SCM interface_symbol_;
+ static Protected_scm interface_symbol_;
static char const *cxx_name_;
static char const *description_;
static char const *variables_;
};
template <class Interface>
-SCM Grob_interface<Interface>::interface_symbol_;
+Protected_scm Grob_interface<Interface>::interface_symbol_;
#endif /* INTERFACE_HH */
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Grob ();
private:
DECLARE_CLASSNAME (Grob);
char const *end_;
Source_file *source_file_;
public:
- static const char type_p_name_[];
+ static const char * const type_p_name_;
int print_smob (SCM, scm_print_state *) const;
static SCM equal_p (SCM, SCM);
SCM mark_smob () const;
void stop_translation_timestep ();
virtual void finalize ();
- DECLARE_ACKNOWLEDGER (rest);
- DECLARE_ACKNOWLEDGER (ligature_head);
- virtual void listen_ligature (Stream_event *ev);
void process_music ();
virtual Spanner *create_ligature_spanner () = 0;
virtual void typeset_ligature (Spanner *ligature,
SCM brew_ligature_primitive_proc;
public:
+ void acknowledge_rest (Grob_info);
+ void acknowledge_ligature_head (Grob_info);
+ void listen_ligature (Stream_event *ev);
// no TRANSLATOR_DECLARATIONS (Ligature_engraver) needed since this
// class is abstract
+ DECLARE_TRANSLATOR_CALLBACKS (Ligature_engraver);
private:
Drul_array<Stream_event *> events_drul_;
extern Variable beat_structure;
extern Variable calc_repeat_slash_count;
extern Variable car_less;
+ extern Variable chordmodifiers;
extern Variable construct_chord_elements;
extern Variable default_time_signature_settings;
+ extern Variable drum_pitch_names;
extern Variable grob_compose_function;
extern Variable grob_offset_function;
extern Variable hash_table_to_alist;
#endif
extern Variable f_parser;
extern Variable percussion_p;
+ extern Variable pitchnames;
extern Variable pure_chain_offset_callback;
extern Variable remove_stencil_warnings;
extern Variable scale_layout;
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Lily_lexer ();
private:
int lookup_keyword (const string&);
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Lily_parser ();
Lily_lexer *lexer_;
Sources *sources_;
#include "flower-proto.hh"
-class Acknowledge_information;
class All_font_metrics;
class Audio_column;
class Audio_control_function_value_change;
class Dot_configuration;
class Dot_formatting_problem;
class Engraver;
-class Engraver;
class Engraver_group;
class Event;
class Event_chord;
SCM callback_;
SCM target_;
public:
- static const char type_p_name_[];
+ static const char * const type_p_name_;
Listener (SCM callback, SCM target)
: callback_ (callback), target_ (target) { }
#include "interval.hh"
double log_2 (double x);
-int intlog2 (int d);
+
+/*
+ Return the 2-log, rounded down
+*/
+template <class T>
+int
+intlog2 (T d)
+{
+ if (d <= 0)
+ error ("intlog2 with negative argument: " + ::to_string (d));
+ int i = 0;
+ while ((d != 1))
+ {
+ d /= 2;
+ i++;
+ }
+
+ assert (! (d / 2));
+ return i;
+}
inline int
sign (int i)
public:
static SCM equal_p (SCM, SCM);
int print_smob (SCM, scm_print_state *) const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
Moment ();
Moment (int m);
class Music_function : public Smob2<Music_function>
{
public:
- static const char type_p_name_[];
+ static const char * const type_p_name_;
int print_smob (SCM, scm_print_state *) const;
SCM get_signature () const { return scm1 (); }
SCM get_function () const { return scm2 (); }
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Music_iterator ();
protected:
Moment music_length_;
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Music_output ();
private:
DECLARE_CLASSNAME (Music_output);
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Output_def ();
VIRTUAL_COPY_CONSTRUCTOR (Output_def, Output_def);
{
public:
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Page_marker ();
private:
SCM symbol_; /* either 'page-turn-permission or 'page-break-permission */
{
public:
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Paper_book ();
private:
SCM systems_;
virtual void initialize ();
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (break);
- DECLARE_TRANSLATOR_LISTENER (label);
+ void listen_break (Stream_event *);
+ void listen_label (Stream_event *);
- DECLARE_ACKNOWLEDGER (item);
- DECLARE_ACKNOWLEDGER (note_spacing);
- DECLARE_ACKNOWLEDGER (staff_spacing);
+ void acknowledge_item (Grob_info);
+ void acknowledge_note_spacing (Grob_info);
+ void acknowledge_staff_spacing (Grob_info);
System *system_;
vector<Stream_event *> break_events_;
class Paper_outputter : public Smob<Paper_outputter>
{
public:
- static const char * const type_p_name_; // = 0
SCM mark_smob () const;
virtual ~Paper_outputter ();
private:
class Performer : public Translator
{
public:
- VIRTUAL_COPY_CONSTRUCTOR (Translator, Performer);
+ DECLARE_CLASSNAME (Performer);
friend class Performer_group;
Performer_group *get_daddy_performer () const;
static SCM equal_p (SCM, SCM);
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
int octave_;
int notename_;
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
static SCM equal_p (SCM, SCM);
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Prob ();
private:
DECLARE_CLASSNAME (Prob);
static SCM list_;
static SCM last_;
Protected_scm (Protected_scm const &);
+ void protectify (SCM);
public:
Protected_scm ();
Protected_scm (SCM);
- ~Protected_scm ();
Protected_scm &operator = (SCM);
Protected_scm &operator = (Protected_scm const &);
- operator SCM () const;
+ operator const SCM & () const;
+ operator SCM & ();
};
#endif /* PROTECTED_SCM_HH */
struct Scale : public Smob<Scale>
{
- static const char * const type_p_name_; // = 0
virtual ~Scale ();
Scale (vector<Rational> const &);
Scale (Scale const &);
protected:
~Scheme_engraver ();
- void stop_translation_timestep ();
- void start_translation_timestep ();
- void process_music ();
- void process_acknowledged ();
-
virtual void initialize ();
virtual void finalize ();
virtual void derived_mark () const;
virtual bool must_be_last () const;
private:
- void acknowledge_grob_by_hash (Grob_info info, SCM iface_function_hash);
- void init_acknowledgers (SCM alist, SCM *hash);
+ virtual SCM get_acknowledger (SCM sym, Direction start_end)
+ {
+ return generic_get_acknowledger
+ (sym, interface_acknowledger_hash_[start_end]);
+ }
- DECLARE_ACKNOWLEDGER (grob);
- DECLARE_END_ACKNOWLEDGER (grob);
+ SCM init_acknowledgers (SCM alist);
+ // For now no description. In future, something derived from the
+ // definition might make sense.
+ SCM translator_description () const { return SCM_EOL; }
bool must_be_last_;
- SCM acknowledge_grob_function_;
- SCM stop_translation_timestep_function_;
- SCM start_translation_timestep_function_;
- SCM process_music_function_;
- SCM process_acknowledged_function_;
SCM initialize_function_;
SCM finalize_function_;
+ SCM precomputable_methods_ [TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
// hashq table of interface-symbol -> scheme-function
- SCM interface_acknowledger_hash_;
- SCM interface_end_acknowledger_hash_;
+ Drul_array<SCM> interface_acknowledger_hash_;
// Alist of listened-symbol . scheme-function
SCM per_instance_listeners_;
};
#endif /* SCHEME_ENGRAVER_HH */
-
class Scheme_hash_table : public Smob1<Scheme_hash_table>
{
public:
- static const char * const type_p_name_; // = 0
int print_smob (SCM, scm_print_state *) const;
bool try_retrieve (SCM key, SCM *val);
bool contains (SCM key) const;
{
public:
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Score ();
private:
SCM music_;
class Skyline_pair : public Simple_smob<Skyline_pair>
{
public:
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
Drul_array<Skyline> skylines_;
class Skyline : public Simple_smob<Skyline>
{
public:
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
list<Building> buildings_;
Direction sky_;
const char* event_name_;
virtual SCM event_symbol () = 0;
- DECLARE_ACKNOWLEDGER (inline_accidental);
- DECLARE_ACKNOWLEDGER (fingering);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (script);
- DECLARE_ACKNOWLEDGER (dots);
- DECLARE_ACKNOWLEDGER (text_script);
- DECLARE_END_ACKNOWLEDGER (tie);
- DECLARE_ACKNOWLEDGER (tuplet_number);
-
- void listen_note (Stream_event *ev);
- void listen_slur (Stream_event *ev, Stream_event *note = 0);
void acknowledge_extra_object (Grob_info);
void stop_translation_timestep ();
void process_music ();
virtual void derived_mark () const;
public:
+ void acknowledge_inline_accidental (Grob_info);
+ void acknowledge_fingering (Grob_info);
+ void acknowledge_note_column (Grob_info);
+ void acknowledge_script (Grob_info);
+ void acknowledge_dots (Grob_info);
+ void acknowledge_text_script (Grob_info);
+ void acknowledge_end_tie (Grob_info);
+ void acknowledge_tuplet_number (Grob_info);
+ void listen_note (Stream_event *ev);
+ void listen_slur (Stream_event *ev, Stream_event *note);
+ // You'd think the following is the same as defaulting `note' to 0,
+ // but template resolution for trampolines disagrees. Huh.
+ void listen_slur (Stream_event *ev) { listen_slur (ev, 0); }
// no TRANSLATOR_DECLARATIONS (Slur_proto_engraver) needed since this
// class is abstract
+ DECLARE_TRANSLATOR_CALLBACKS (Slur_proto_engraver);
};
#endif // SLUR_PROTO_ENGRAVER_HH
debugging purposes. If the class does not define this function,
the output will be #<Classname> when printing.
- - a static const type_p_name_[] string set to something like
+ - a static const * const type_p_name_ string set to something like
"ly:grob?". When provided, an accordingly named function for
checking for the given smob type will be available in Scheme.
// Most default functions are do-nothings. void init() will
// recognize their address when not overriden and will then refrain
// altogether from passing the the respective callbacks to GUILE.
+
SCM mark_smob (void) const;
static SCM mark_trampoline (SCM); // Used for calling mark_smob
static size_t free_smob (SCM obj);
static int print_trampoline (SCM, SCM, scm_print_state *);
static void smob_proc_init (scm_t_bits) { };
- // type_p_name_ has to be defined in the Super class, either with a
- // static const char [] string or as a null pointer of type const
- // char *. We used to provide a default here for convenience, but
- // battling the various conflicting C++ standards was too much of a
- // hassle.
+ // Define type_p_name_ in the Super class as a const char * const.
+ // Without such definition it defaults to 0, producing no predicate.
+
+ static const char * const type_p_name_; // = 0
// LY_DECLARE_SMOB_PROC is used in the Super class definition for
// making a smob callable like a function. Its first argument is a
template <class Super>
string Smob_base<Super>::smob_name_;
+template <class Super>
+const char * const Smob_base<Super>::type_p_name_ = 0;
+
template <class Super>
void Smob_base<Super>::init ()
{
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Source_file ();
private:
vector<char const *> newline_locations_;
{
public:
static SCM equal_p (SCM, SCM);
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
Real distance_;
Real min_distance_;
{
public:
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
Box dim_;
SCM expr_;
#define TRANSLATOR_DISPATCH_LIST_HH
#include "lily-proto.hh"
+#include "callback.hh"
#include "std-vector.hh"
#include "smobs.hh"
#include "translator.hh"
-struct Engraver_dispatch_entry
-{
- Engraver *engraver_;
- Translator::Grob_info_callback function_;
-};
-
class Engraver_dispatch_list : public Simple_smob<Engraver_dispatch_list>
{
- vector<Engraver_dispatch_entry> dispatch_entries_;
+ vector<Method_instance> dispatch_entries_;
public:
- static const char * const type_p_name_; // = 0
void apply (Grob_info);
SCM static create (SCM trans_list,
SCM iface_list, Direction);
#ifndef TRANSLATOR_GROUP_HH
#define TRANSLATOR_GROUP_HH
+#include "callback.hh"
#include "listener.hh"
#include "translator.hh"
-typedef void (Translator:: *Translator_method) (void);
-typedef void (Translator_group:: *Translator_group_method) (void);
-typedef void (*Translator_group_void_method) (Translator_group *);
-
-struct Translator_method_binding
-{
- Translator *translator_;
- Translator::Callback method_;
-
- Translator_method_binding ()
- {
- }
- Translator_method_binding (Translator *tr, Translator::Callback ptr)
- {
- translator_ = tr;
- method_ = ptr;
- }
- void invoke ()
- {
- if (method_)
- (translator_->*method_) ();
- }
-};
-
class Translator_group : public Smob<Translator_group>
{
public:
SCM mark_smob () const;
int print_smob (SCM, scm_print_state *) const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Translator_group ();
private:
void precompute_method_bindings ();
- vector<Translator_method_binding>
+ vector<Method_instance>
precomputed_method_bindings_[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
- Translator_group_void_method
- precomputed_self_method_bindings_[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
-
SCM protected_events_;
void create_child_translator (SCM);
void stop_translation_timestep ();
void start_translation_timestep ();
- virtual void fetch_precomputable_methods (Translator_group_void_method[]);
-
Translator_group ();
void precomputed_translator_foreach (Translator_precompute_index);
- void call_precomputed_self_method (Translator_precompute_index);
Context *context () const { return context_; }
protected:
};
SCM names_to_translators (SCM namelist, Context *tg);
-void recurse_over_translators (Context *c, Translator_method ptr,
- Translator_group_method ptr2, Direction);
+void recurse_over_translators (Context *c, SCM tr_method,
+ SCM tr_group_method, Direction);
void precomputed_recurse_over_translators (Context *c, Translator_precompute_index idx, Direction dir);
Translator_group *get_translator_group (SCM sym);
#include "global-ctor.hh"
#include "lily-proto.hh"
#include "virtual-methods.hh"
+#include "callback.hh"
#include "input.hh" // for error reporting
#include "smobs.hh"
#include "std-vector.hh"
#define TRANSLATOR_FAMILY_DECLARATIONS(NAME) \
public: \
VIRTUAL_COPY_CONSTRUCTOR (Translator, NAME); \
- static Drul_array<vector<Acknowledge_information> > acknowledge_static_array_drul_; \
- virtual void fetch_precomputable_methods (Callback methods[]); \
- static Grob_info_callback static_get_acknowledger (SCM sym); \
- static Grob_info_callback static_get_end_acknowledger(SCM); \
- virtual Grob_info_callback get_acknowledger (SCM sym) \
- { \
- return static_get_acknowledger (sym); \
- } \
- virtual Grob_info_callback get_end_acknowledger (SCM sym) \
- { \
- return static_get_end_acknowledger (sym); \
- } \
+ virtual void fetch_precomputable_methods (SCM methods[]); \
+ DECLARE_TRANSLATOR_CALLBACKS (NAME); \
+ TRANSLATOR_INHERIT (Translator); \
+ /* end #define */
+
+#define TRANSLATOR_INHERIT(BASE) \
+ using BASE::method_finder
+
+#define DECLARE_TRANSLATOR_CALLBACKS(NAME) \
+ template <void (NAME::*mf)()> \
+ static SCM method_finder () { return method_find_base<NAME, mf> (); } \
/* end #define */
/*
*/
#define TRANSLATOR_DECLARATIONS(NAME) \
- TRANSLATOR_FAMILY_DECLARATIONS(NAME) \
+ public: \
+ TRANSLATOR_FAMILY_DECLARATIONS (NAME); \
+ static Drul_array<Protected_scm> acknowledge_static_array_drul_; \
static SCM static_description_; \
static Protected_scm listener_list_; \
+ static SCM static_get_acknowledger (SCM sym, Direction start_end); \
+ virtual SCM get_acknowledger (SCM sym, Direction start_end) \
+ { \
+ return static_get_acknowledger (sym, start_end); \
+ } \
public: \
NAME (); \
+ static void boot (); \
virtual SCM static_translator_description () const; \
virtual SCM translator_description () const; \
virtual SCM get_listener_list () const \
} \
/* end #define */
-#define DECLARE_TRANSLATOR_LISTENER(m) \
-public: \
-inline void listen_ ## m (Stream_event *); \
-/* Should be private */ \
-static void _internal_declare_ ## m ();
-
-#define DECLARE_ACKNOWLEDGER(x) public : void acknowledge_ ## x (Grob_info); protected:
-#define DECLARE_END_ACKNOWLEDGER(x) public : void acknowledge_end_ ## x (Grob_info); protected:
-
enum Translator_precompute_index
{
START_TRANSLATION_TIMESTEP,
class Translator : public Smob<Translator>
{
public:
- // We don't make Grob_info_callback specific to Engraver since we
- // otherwise get into a circular mess with regard to the definitions
- // as the timing of Engraver is exercised from within Translator
- typedef void (Translator::*Grob_info_callback) (Grob_info);
- typedef void (Translator::*Callback) (void);
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
virtual ~Translator ();
private:
void init ();
public:
Context *context () const { return daddy_context_; }
+ Translator ();
Translator (Translator const &);
SCM internal_get_property (SCM symbol) const;
Context *get_score_context () const;
Global_context *get_global_context () const;
- TRANSLATOR_DECLARATIONS (Translator);
+ DECLARE_CLASSNAME (Translator);
+ virtual Translator *clone () const = 0;
+ virtual void fetch_precomputable_methods (SCM methods[]) = 0;
+ virtual SCM get_listener_list () const = 0;
+ virtual SCM translator_description () const = 0;
+ virtual SCM get_acknowledger (SCM sym, Direction start_end) = 0;
protected: // should be private.
Context *daddy_context_;
return SCM_UNSPECIFIED;
}
+ template <class T, void (T::*mf)()>
+ static SCM
+ method_find_base () { return Callback0_wrapper::make_smob<T, mf> (); }
+
+ // Fallback for non-overriden callbacks for which &T::x degrades to
+ // &Translator::x
+ template <void (Translator::*)()>
+ static SCM
+ method_finder () { return SCM_UNDEFINED; }
+
virtual void derived_mark () const;
static SCM event_class_symbol (const char *ev_class);
SCM static_translator_description (const char *grobs,
friend class Translator_group;
};
-struct Acknowledge_information
-{
- SCM symbol_;
- Translator::Grob_info_callback function_;
-
- Acknowledge_information ()
- {
- symbol_ = SCM_EOL;
- function_ = 0;
- }
-};
-
-
void add_translator (Translator *trans);
Translator *get_translator (SCM s);
+
+SCM
+generic_get_acknowledger (SCM sym, SCM ack_hash);
+
Moment get_event_length (Stream_event *s, Moment now);
Moment get_event_length (Stream_event *s);
#include "callback.hh"
#include "std-vector.hh"
-#include "translator.hh"
+#include "engraver.hh"
/*
TODO: derive "foo-bar-interface" from Foo_bar classname.
SCM T::static_description_ = SCM_EOL; \
static void _ ## T ## _adder () \
{ \
+ T::boot (); \
T *t = new T; \
T::static_description_ = \
scm_permanent_object (t->static_translator_description ()); \
{ \
return static_description_; \
} \
- ADD_GLOBAL_CTOR (_ ## T ## _adder); \
+ ADD_GLOBAL_CTOR (_ ## T ## _adder); \
/* end define */
#define DEFINE_TRANSLATOR_LISTENER_LIST(T) \
- Protected_scm T::listener_list_ (SCM_EOL); \
- /* end define */
+ Protected_scm T::listener_list_ (SCM_EOL)
#define DEFINE_ACKNOWLEDGERS(classname) \
- Drul_array< vector<Acknowledge_information> > classname::acknowledge_static_array_drul_; \
- Translator::Grob_info_callback \
- classname::static_get_acknowledger (SCM sym) \
- { \
- return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[START]); \
- } \
- Translator::Grob_info_callback \
- classname::static_get_end_acknowledger (SCM sym) \
+ Drul_array<Protected_scm> classname::acknowledge_static_array_drul_; \
+ SCM \
+ classname::static_get_acknowledger (SCM sym, Direction start_end) \
{ \
- return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[STOP]); \
+ return generic_get_acknowledger \
+ (sym, acknowledge_static_array_drul_[start_end]); \
} \
/* end define */
return Translator::static_translator_description (grobs, desc, listener_list_, read, write); \
}
-#define ADD_TRANSLATOR_FAMILY(classname) \
- IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS (classname); \
- DEFINE_ACKNOWLEDGERS(classname) \
-
#define ADD_TRANSLATOR(classname, desc, grobs, read, write) \
- ADD_TRANSLATOR_FAMILY (classname) \
+ IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS (classname); \
+ DEFINE_ACKNOWLEDGERS(classname); \
ADD_THIS_TRANSLATOR (classname); \
- DEFINE_TRANSLATOR_DOC(classname, desc, grobs, read, write) \
- DEFINE_TRANSLATOR_LISTENER_LIST(classname) \
+ DEFINE_TRANSLATOR_DOC(classname, desc, grobs, read, write); \
+ DEFINE_TRANSLATOR_LISTENER_LIST(classname);
#define IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS(T) \
void \
- T::fetch_precomputable_methods (Translator::Callback ptrs[]) \
+ T::fetch_precomputable_methods (SCM ptrs[]) \
{ \
ptrs[START_TRANSLATION_TIMESTEP] = \
- (&T::start_translation_timestep \
- == &Translator::start_translation_timestep) \
- ? 0 \
- : static_cast<Callback> (&T::start_translation_timestep); \
+ method_finder <&T::start_translation_timestep> (); \
\
ptrs[STOP_TRANSLATION_TIMESTEP] = \
- (& T::stop_translation_timestep == & Translator::stop_translation_timestep) \
- ? 0 \
- : static_cast<Callback> (&T::stop_translation_timestep); \
- \
+ method_finder <&T::stop_translation_timestep> (); \
+ \
ptrs[PROCESS_MUSIC] = \
- (&T::process_music == &Translator::process_music) \
- ? 0 \
- : static_cast<Callback> (&T::process_music); \
+ method_finder <&T::process_music> (); \
\
ptrs[PROCESS_ACKNOWLEDGED] = \
- (&T::process_acknowledged == &Translator::process_acknowledged) \
- ? 0 \
- : static_cast<Callback> (&T::process_acknowledged); \
+ method_finder <&T::process_acknowledged> (); \
}
-void add_acknowledger (Translator::Grob_info_callback ptr,
+void add_acknowledger (SCM ptr,
char const *func_name,
- vector<Acknowledge_information> *ack_array);
-
-Translator::Grob_info_callback
-generic_get_acknowledger (SCM sym,
- vector<Acknowledge_information> const *ack_array);
+ SCM &ack_hash);
#define ADD_ACKNOWLEDGER(CLASS, NAME) \
- void CLASS ## NAME ## _ack_adder () \
- { \
- add_acknowledger (static_cast<Translator::Grob_info_callback> (&CLASS::acknowledge_ ## NAME), #NAME, &CLASS::acknowledge_static_array_drul_[START]); \
- } \
- ADD_SCM_INIT_FUNC (CLASS ## NAME ## _ack_adder_initclass, CLASS ## NAME ## _ack_adder);
+ add_acknowledger (Callback2_wrapper::make_smob \
+ <ack_trampoline<CLASS, &CLASS::acknowledge_ ## NAME> > (), \
+ #NAME, acknowledge_static_array_drul_[START])
-#define ADD_END_ACKNOWLEDGER(CLASS, NAME) \
- void CLASS ## NAME ## _end_ack_adder () \
- { \
- add_acknowledger (static_cast<Translator::Grob_info_callback> (&CLASS::acknowledge_end_ ## NAME), #NAME, &CLASS::acknowledge_static_array_drul_[STOP]); \
- } \
- ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder);
+#define ADD_END_ACKNOWLEDGER(CLASS, NAME) \
+ add_acknowledger (Callback2_wrapper::make_smob \
+ <ack_trampoline<CLASS, &CLASS::acknowledge_end_ ## NAME> > (), \
+ #NAME, acknowledge_static_array_drul_[STOP])
/*
Implement the method cl::listen_##m, and make it listen to stream
events of class m.
*/
-#define IMPLEMENT_TRANSLATOR_LISTENER(cl, m) \
-void \
-cl :: _internal_declare_ ## m () \
-{ \
+#define ADD_LISTENER(cl, m) \
listener_list_ = scm_acons \
(event_class_symbol (#m), \
Callback_wrapper::make_smob \
- <trampoline <cl, &cl::listen_ ## m> > (), listener_list_); \
-} \
- \
-ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m);
+ <trampoline <cl, &cl::listen_ ## m> > (), listener_list_)
#endif /* TRANSLATOR_ICC */
class Unpure_pure_container : public Smob2<Unpure_pure_container>
{
public:
- static const char type_p_name_ [];
+ static const char * const type_p_name_;
SCM unpure_part () const { return scm1 (); }
// A container that has the same callback for both 'pure' and 'unpure' lookups
// and which ignores the 'start' and 'end' columnns.
/* Dummy input location for use if real one is missing. */
Input dummy_input_global;
-const char Input::type_p_name_[] = "ly:input-location?";
+const char * const Input::type_p_name_ = "ly:input-location?";
SCM
Input::mark_smob () const
vector<Grob *> backup_axis_groups_;
virtual void finalize ();
- DECLARE_ACKNOWLEDGER (axis_group);
+ void acknowledge_axis_group (Grob_info);
void process_music ();
void start_spanner ();
void consider_start_spanner ();
text_spanner_ = 0;
}
-ADD_ACKNOWLEDGER (Instrument_name_engraver, axis_group);
+
+void
+Instrument_name_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Instrument_name_engraver, axis_group);
+}
ADD_TRANSLATOR (Instrument_name_engraver,
/* doc */
text_ = 0;
}
+void
+Instrument_switch_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Instrument_switch_engraver,
/* doc */
"Create a cue text for taking instrument.",
public:
TRANSLATOR_DECLARATIONS (Keep_alive_together_engraver);
- DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
+ void acknowledge_hara_kiri_group_spanner (Grob_info);
virtual void finalize ();
};
}
}
-ADD_ACKNOWLEDGER (Keep_alive_together_engraver, hara_kiri_group_spanner);
+
+void
+Keep_alive_together_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Keep_alive_together_engraver, hara_kiri_group_spanner);
+}
ADD_TRANSLATOR (Keep_alive_together_engraver,
/* doc */
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (key_change);
- DECLARE_ACKNOWLEDGER (clef);
- DECLARE_ACKNOWLEDGER (bar_line);
+ void listen_key_change (Stream_event *);
+ void acknowledge_clef (Grob_info);
+ void acknowledge_bar_line (Grob_info);
};
void
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Key_engraver, key_change);
void
Key_engraver::listen_key_change (Stream_event *ev)
{
context ()->set_property ("tonic", p.smobbed_copy ());
}
-ADD_ACKNOWLEDGER (Key_engraver, clef);
-ADD_ACKNOWLEDGER (Key_engraver, bar_line);
+
+void
+Key_engraver::boot ()
+{
+ ADD_LISTENER (Key_engraver, key_change);
+ ADD_ACKNOWLEDGER (Key_engraver, clef);
+ ADD_ACKNOWLEDGER (Key_engraver, bar_line);
+}
ADD_TRANSLATOR (Key_engraver,
/* doc */
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (key_change);
+ void listen_key_change (Stream_event *);
private:
Stream_event *key_ev_;
Audio_key *audio_;
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Key_performer, key_change);
void
Key_performer::listen_key_change (Stream_event *ev)
{
key_ev_ = ev;
}
+void
+Key_performer::boot ()
+{
+ ADD_LISTENER (Key_performer, key_change);
+}
+
ADD_TRANSLATOR (Key_performer,
/* doc */
"",
virtual Spanner *create_ligature_spanner ();
virtual void build_ligature (Spanner *ligature,
vector<Grob_info> const &primitives);
- DECLARE_TRANSLATOR_LISTENER (ligature);
public:
TRANSLATOR_DECLARATIONS (Kievan_ligature_engraver);
+ TRANSLATOR_INHERIT (Coherent_ligature_engraver);
private:
void fold_up_primitives (vector<Grob_info> const &primitives, Real padding, Real &min_length);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Kievan_ligature_engraver, ligature);
-void
-Kievan_ligature_engraver::listen_ligature (Stream_event *ev)
-{
- Ligature_engraver::listen_ligature (ev);
-}
-
Kievan_ligature_engraver::Kievan_ligature_engraver ()
{
}
-ADD_ACKNOWLEDGER (Kievan_ligature_engraver, rest);
-ADD_ACKNOWLEDGER (Kievan_ligature_engraver, ligature_head);
+
+void
+Kievan_ligature_engraver::boot ()
+{
+ ADD_LISTENER (Ligature_engraver, ligature);
+ ADD_ACKNOWLEDGER (Ligature_engraver, rest);
+ ADD_ACKNOWLEDGER (Ligature_engraver, ligature_head);
+}
ADD_TRANSLATOR (Kievan_ligature_engraver,
/* doc */
vector<Grob *> lv_ties_;
void stop_translation_timestep ();
- DECLARE_ACKNOWLEDGER (note_head);
+ void acknowledge_note_head (Grob_info);
protected:
- DECLARE_TRANSLATOR_LISTENER (laissez_vibrer);
+ void listen_laissez_vibrer (Stream_event *);
public:
TRANSLATOR_DECLARATIONS (Laissez_vibrer_engraver);
};
lv_ties_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Laissez_vibrer_engraver, laissez_vibrer);
void
Laissez_vibrer_engraver::listen_laissez_vibrer (Stream_event *ev)
{
lv_ties_.push_back (lv_tie);
}
-ADD_ACKNOWLEDGER (Laissez_vibrer_engraver, note_head);
+void
+Laissez_vibrer_engraver::boot ()
+{
+ ADD_LISTENER (Laissez_vibrer_engraver, laissez_vibrer);
+ ADD_ACKNOWLEDGER (Laissez_vibrer_engraver, note_head);
+}
+
ADD_TRANSLATOR (Laissez_vibrer_engraver,
/* doc */
"Create laissez vibrer items.",
virtual void finalize ();
void process_music ();
- DECLARE_ACKNOWLEDGER (ledgered);
- DECLARE_ACKNOWLEDGER (staff_symbol);
+ void acknowledge_ledgered (Grob_info);
+ void acknowledge_staff_symbol (Grob_info);
void start_spanner ();
void stop_spanner ();
ledgered_grobs_.push_back (s.grob ());
}
-ADD_ACKNOWLEDGER (Ledger_line_engraver, ledgered);
-ADD_ACKNOWLEDGER (Ledger_line_engraver, staff_symbol);
+void
+Ledger_line_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Ledger_line_engraver, ledgered);
+ ADD_ACKNOWLEDGER (Ledger_line_engraver, staff_symbol);
+}
+
ADD_TRANSLATOR (Ledger_line_engraver,
/* doc */
"Create the spanner to draw ledger lines, and notices"
protected:
virtual void process_music ();
virtual void stop_translation_timestep ();
- DECLARE_ACKNOWLEDGER (rest);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (ligature);
+ void acknowledge_rest (Grob_info);
+ void acknowledge_note_column (Grob_info);
+ void listen_ligature (Stream_event *);
public:
TRANSLATOR_DECLARATIONS (Ligature_bracket_engraver);
Stream_event *previous_start_event_;
};
-IMPLEMENT_TRANSLATOR_LISTENER (Ligature_bracket_engraver, ligature);
void
Ligature_bracket_engraver::listen_ligature (Stream_event *ev)
{
finished_ligature_ = 0;
}
-ADD_ACKNOWLEDGER (Ligature_bracket_engraver, rest);
-ADD_ACKNOWLEDGER (Ligature_bracket_engraver, note_column);
+
+void
+Ligature_bracket_engraver::boot ()
+{
+ ADD_LISTENER (Ligature_bracket_engraver, ligature);
+ ADD_ACKNOWLEDGER (Ligature_bracket_engraver, rest);
+ ADD_ACKNOWLEDGER (Ligature_bracket_engraver, note_column);
+}
ADD_TRANSLATOR (Ligature_bracket_engraver,
/* doc */
Variable beat_structure ("beat-structure");
Variable calc_repeat_slash_count ("calc-repeat-slash-count");
Variable car_less ("car<");
+ Variable chordmodifiers ("chordmodifiers");
Variable construct_chord_elements ("construct-chord-elements");
Variable default_time_signature_settings ("default-time-signature-settings");
+ Variable drum_pitch_names ("drumPitchNames");
Variable grob_compose_function ("grob::compose-function");
Variable grob_offset_function ("grob::offset-function");
Variable hash_table_to_alist ("hash-table->alist");
#endif
Variable f_parser ("%parser");
Variable percussion_p ("percussion?");
+ Variable pitchnames ("pitchnames");
Variable pure_chain_offset_callback ("pure-chain-offset-callback");
Variable remove_stencil_warnings ("remove-stencil-warnings");
Variable scale_layout ("scale-layout");
}
-const char Lily_lexer::type_p_name_[] = "ly:lily-lexer?";
+const char * const Lily_lexer::type_p_name_ = "ly:lily-lexer?";
SCM
Lily_lexer::mark_smob () const
error_level_ = 1;
}
-const char Lily_parser::type_p_name_[] = "ly:lily-parser?";
+const char * const Lily_parser::type_p_name_ = "ly:lily-parser?";
/****************************************************************
OUTPUT-DEF
#include "listener.hh"
-const char Listener::type_p_name_[] = "ly:listener?";
+const char * const Listener::type_p_name_ = "ly:listener?";
applies to the given polygon. However, this is quite complicated
to check. */
+#ifdef DEBUG
const Real epsilon = 0.01;
-#ifdef DEBUG
/* remove consecutive duplicate points */
for (vsize i = 0; i < points.size (); i++)
{
protected:
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (lyric);
+ void listen_lyric (Stream_event *);
public:
TRANSLATOR_DECLARATIONS (Lyric_engraver);
event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Lyric_engraver, lyric);
void
Lyric_engraver::listen_lyric (Stream_event *ev)
{
event_ = 0;
}
+void
+Lyric_engraver::boot ()
+{
+ ADD_LISTENER (Lyric_engraver, lyric);
+}
+
ADD_TRANSLATOR (Lyric_engraver,
/* doc */
"Engrave text for lyrics.",
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (lyric);
+ void listen_lyric (Stream_event *);
private:
vector<Stream_event *> events_;
Audio_text *audio_;
events_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Lyric_performer, lyric);
void
Lyric_performer::listen_lyric (Stream_event *event)
{
events_.push_back (event);
}
+void
+Lyric_performer::boot ()
+{
+ ADD_LISTENER (Lyric_performer, lyric);
+}
+
ADD_TRANSLATOR (Lyric_performer,
/* doc */
"",
void stop_translation_timestep ();
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (mark);
- DECLARE_ACKNOWLEDGER (break_alignment);
+ void listen_mark (Stream_event *);
+ void acknowledge_break_alignment (Grob_info);
};
Mark_engraver::Mark_engraver ()
text_ = make_item ("RehearsalMark", ev->self_scm ());
}
-IMPLEMENT_TRANSLATOR_LISTENER (Mark_engraver, mark);
void
Mark_engraver::listen_mark (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Mark_engraver, break_alignment);
+
+void
+Mark_engraver::boot ()
+{
+ ADD_LISTENER (Mark_engraver, mark);
+ ADD_ACKNOWLEDGER (Mark_engraver, break_alignment);
+}
ADD_TRANSLATOR (Mark_engraver,
/* doc */
void process_music ();
virtual void finalize ();
- DECLARE_ACKNOWLEDGER (note_column);
+ void acknowledge_note_column (Grob_info);
};
void
grouping_ = 0;
}
-ADD_ACKNOWLEDGER (Measure_grouping_engraver, note_column);
+void
+Measure_grouping_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Measure_grouping_engraver, note_column);
+}
+
ADD_TRANSLATOR (Measure_grouping_engraver,
/* doc */
"Create @code{MeasureGrouping} to indicate beat subdivision.",
Grob *stem_;
protected:
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (slur);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_slur (Grob_info);
TRANSLATOR_DECLARATIONS (Melody_engraver);
void stop_translation_timestep ();
void process_acknowledged ();
#include "translator.icc"
-ADD_ACKNOWLEDGER (Melody_engraver, stem);
-ADD_ACKNOWLEDGER (Melody_engraver, slur);
+
+void
+Melody_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Melody_engraver, stem);
+ ADD_ACKNOWLEDGER (Melody_engraver, slur);
+}
ADD_TRANSLATOR (Melody_engraver,
/* doc */
virtual Spanner *create_ligature_spanner ();
virtual void build_ligature (Spanner *ligature,
vector<Grob_info> const &primitives);
- DECLARE_TRANSLATOR_LISTENER (ligature);
public:
TRANSLATOR_DECLARATIONS (Mensural_ligature_engraver);
+ TRANSLATOR_INHERIT (Coherent_ligature_engraver);
private:
void transform_heads (vector<Grob_info> const &primitives);
Real &min_length);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Mensural_ligature_engraver, ligature);
-void
-Mensural_ligature_engraver::listen_ligature (Stream_event *ev)
-{
- Ligature_engraver::listen_ligature (ev);
-}
-
Mensural_ligature_engraver::Mensural_ligature_engraver ()
{
brew_ligature_primitive_proc
ligature->set_property ("minimum-length", scm_from_double (min_length));
}
-ADD_ACKNOWLEDGER (Mensural_ligature_engraver, rest);
-ADD_ACKNOWLEDGER (Mensural_ligature_engraver, ligature_head);
+
+void
+Mensural_ligature_engraver::boot ()
+{
+ ADD_LISTENER (Ligature_engraver, ligature);
+ ADD_ACKNOWLEDGER (Ligature_engraver, rest);
+ ADD_ACKNOWLEDGER (Ligature_engraver, ligature_head);
+}
ADD_TRANSLATOR (Mensural_ligature_engraver,
/* doc */
void stop_translation_timestep ();
void process_music ();
- DECLARE_ACKNOWLEDGER (break_aligned);
- DECLARE_ACKNOWLEDGER (break_alignment);
- DECLARE_ACKNOWLEDGER (grob);
+ void acknowledge_break_aligned (Grob_info);
+ void acknowledge_break_alignment (Grob_info);
+ void acknowledge_grob (Grob_info);
- DECLARE_TRANSLATOR_LISTENER (tempo_change);
+ void listen_tempo_change (Stream_event *);
};
Metronome_mark_engraver::Metronome_mark_engraver ()
tempo_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Metronome_mark_engraver, tempo_change);
void
Metronome_mark_engraver::listen_tempo_change (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Metronome_mark_engraver, break_aligned);
-ADD_ACKNOWLEDGER (Metronome_mark_engraver, break_alignment);
-ADD_ACKNOWLEDGER (Metronome_mark_engraver, grob);
+
+void
+Metronome_mark_engraver::boot ()
+{
+ ADD_LISTENER (Metronome_mark_engraver, tempo_change);
+ ADD_ACKNOWLEDGER (Metronome_mark_engraver, break_aligned);
+ ADD_ACKNOWLEDGER (Metronome_mark_engraver, break_alignment);
+ ADD_ACKNOWLEDGER (Metronome_mark_engraver, grob);
+}
ADD_TRANSLATOR (Metronome_mark_engraver,
/* doc */
}
}
+void
+Midi_control_function_performer::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Midi_control_function_performer,
/* doc */
"",
#include "offset.hh"
#include "warn.hh"
-/*
- Return the 2-log, rounded down
-*/
-int
-intlog2 (int d)
-{
- if (d <= 0)
- error ("intlog2 with negative argument: " + ::to_string (d));
- int i = 0;
- while ((d != 1))
- {
- d /= 2;
- i++;
- }
-
- assert (! (d / 2));
- return i;
-}
-
double
log_2 (double x)
{
}
-const char Moment::type_p_name_[] = "ly:moment?";
+const char * const Moment::type_p_name_ = "ly:moment?";
int
protected:
void process_music ();
void start_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (multi_measure_rest);
- DECLARE_TRANSLATOR_LISTENER (multi_measure_text);
+ void listen_multi_measure_rest (Stream_event *);
+ void listen_multi_measure_text (Stream_event *);
private:
void add_bound_item_to_grobs (Item *);
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Multi_measure_rest_engraver, multi_measure_rest);
void
Multi_measure_rest_engraver::listen_multi_measure_rest (Stream_event *ev)
{
clear_lapsed_events (now);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Multi_measure_rest_engraver, multi_measure_text);
void
Multi_measure_rest_engraver::listen_multi_measure_text (Stream_event *ev)
{
clear_lapsed_events (now_mom ());
}
+void
+Multi_measure_rest_engraver::boot ()
+{
+ ADD_LISTENER (Multi_measure_rest_engraver, multi_measure_rest);
+ ADD_LISTENER (Multi_measure_rest_engraver, multi_measure_text);
+}
+
ADD_TRANSLATOR (Multi_measure_rest_engraver,
/* doc */
"Engrave multi-measure rests that are produced with"
#include "fluid.hh"
#include "lily-imports.hh"
-const char Music_function::type_p_name_[] = "ly:music-function?";
+const char * const Music_function::type_p_name_ = "ly:music-function?";
/* Print a textual represenation of the smob to a given port. */
int
/****************************************************************/
-const char Music_iterator::type_p_name_[] = "ly:iterator?";
+const char * const Music_iterator::type_p_name_ = "ly:iterator?";
SCM
Music_iterator::mark_smob () const
{
}
-const char Music_output::type_p_name_[] = "ly:music-output?";
+const char * const Music_output::type_p_name_ = "ly:music-output?";
SCM
Music_output::mark_smob () const
TRANSLATOR_DECLARATIONS (New_fingering_engraver);
protected:
void stop_translation_timestep ();
- DECLARE_ACKNOWLEDGER (rhythmic_head);
- DECLARE_ACKNOWLEDGER (inline_accidental);
- DECLARE_ACKNOWLEDGER (stem);
+ void acknowledge_rhythmic_head (Grob_info);
+ void acknowledge_inline_accidental (Grob_info);
+ void acknowledge_stem (Grob_info);
void add_fingering (Grob *, SCM,
vector<Finger_tuple> *,
Stream_event *, Stream_event *);
stem_ = 0;
}
-ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (New_fingering_engraver, inline_accidental);
-ADD_ACKNOWLEDGER (New_fingering_engraver, stem);
+
+void
+New_fingering_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head);
+ ADD_ACKNOWLEDGER (New_fingering_engraver, inline_accidental);
+ ADD_ACKNOWLEDGER (New_fingering_engraver, stem);
+}
ADD_TRANSLATOR (New_fingering_engraver,
/* doc */
TRANSLATOR_DECLARATIONS (Note_head_line_engraver);
protected:
- DECLARE_ACKNOWLEDGER (rhythmic_head);
+ void acknowledge_rhythmic_head (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
#include "translator.icc"
-ADD_ACKNOWLEDGER (Note_head_line_engraver, rhythmic_head);
+void
+Note_head_line_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Note_head_line_engraver, rhythmic_head);
+}
+
ADD_TRANSLATOR (Note_head_line_engraver,
/* doc */
"Engrave a line between two note heads in a staff"
TRANSLATOR_DECLARATIONS (Note_heads_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (note);
+ void listen_note (Stream_event *);
void process_music ();
void stop_translation_timestep ();
};
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Note_heads_engraver, note);
void
Note_heads_engraver::listen_note (Stream_event *ev)
{
note_evs_.clear ();
}
+void
+Note_heads_engraver::boot ()
+{
+ ADD_LISTENER (Note_heads_engraver, note);
+}
+
ADD_TRANSLATOR (Note_heads_engraver,
/* doc */
"Generate note heads.",
TRANSLATOR_DECLARATIONS (Note_name_engraver);
vector<Stream_event *> events_;
- DECLARE_TRANSLATOR_LISTENER (note);
+ void listen_note (Stream_event *);
void process_music ();
void stop_translation_timestep ();
};
-IMPLEMENT_TRANSLATOR_LISTENER (Note_name_engraver, note);
void
Note_name_engraver::listen_note (Stream_event *ev)
{
{
}
+void
+Note_name_engraver::boot ()
+{
+ ADD_LISTENER (Note_name_engraver, note);
+}
+
ADD_TRANSLATOR (Note_name_engraver,
/* doc */
"Print pitches as words.",
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (note);
- DECLARE_TRANSLATOR_LISTENER (breathing);
+ void listen_note (Stream_event *);
+ void listen_breathing (Stream_event *);
+ void listen_tie (Stream_event *);
+ void listen_articulation (Stream_event *);
private:
- vector<Stream_event *> note_evs_;
+ vector<Stream_event *> note_evs_, script_evs_;
vector<Audio_note *> notes_;
vector<Audio_note *> last_notes_;
Moment last_start_;
-
};
void
Stream_event *tie_event = 0;
Moment len = get_event_length (n, now_mom ());
int velocity = 0;
+
+ for (vsize j = script_evs_.size (); j--;)
+ articulations = scm_cons (script_evs_[j]->self_scm (), articulations);
+
for (SCM s = articulations; scm_is_pair (s); s = scm_cdr (s))
{
Stream_event *ev = unsmob<Stream_event> (scm_car (s));
notes_.clear ();
note_evs_.clear ();
+ script_evs_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Note_performer, note)
void
Note_performer::listen_note (Stream_event *ev)
{
note_evs_.push_back (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Note_performer, breathing)
+void
+Note_performer::listen_tie (Stream_event *ev)
+{
+ script_evs_.push_back (ev);
+}
+
+void
+Note_performer::listen_articulation (Stream_event *ev)
+{
+ script_evs_.push_back (ev);
+}
+
void
Note_performer::listen_breathing (Stream_event *ev)
{
}
}
+void
+Note_performer::boot ()
+{
+ ADD_LISTENER (Note_performer, note);
+ ADD_LISTENER (Note_performer, breathing);
+ ADD_LISTENER (Note_performer, tie);
+ ADD_LISTENER (Note_performer, articulation);
+}
+
ADD_TRANSLATOR (Note_performer,
/* doc */
"",
TRANSLATOR_DECLARATIONS (Note_spacing_engraver);
protected:
- DECLARE_ACKNOWLEDGER (rhythmic_grob);
- DECLARE_ACKNOWLEDGER (note_column);
+ void acknowledge_rhythmic_grob (Grob_info);
+ void acknowledge_note_column (Grob_info);
void stop_translation_timestep ();
virtual void finalize ();
virtual void derived_mark () const;
}
-ADD_ACKNOWLEDGER (Note_spacing_engraver, note_column);
-ADD_ACKNOWLEDGER (Note_spacing_engraver, rhythmic_grob);
+
+void
+Note_spacing_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Note_spacing_engraver, note_column);
+ ADD_ACKNOWLEDGER (Note_spacing_engraver, rhythmic_grob);
+}
ADD_TRANSLATOR (Note_spacing_engraver,
/* doc */
along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "international.hh"
#include "modified-font-metric.hh"
#include "open-type-font.hh"
+#include "freetype.hh"
+
+#ifdef FT_FONT_FORMATS_H
+/* FreeType 2.6+ */
+#include FT_FONT_FORMATS_H
+#else
+/* FreeType 2.5.5 and earlier */
+#include FT_XFREE86_H
+#define FT_Get_Font_Format FT_Get_X11_Font_Format
+#endif
LY_DEFINE (ly_font_sub_fonts, "ly:font-sub-fonts", 1, 0, 0,
(SCM font),
return otf->glyph_list ();
}
+
+LY_DEFINE (ly_get_font_format, "ly:get-font-format",
+ 1, 1, 0, (SCM font_file_name, SCM idx),
+ "Get the font format for @var{font_file_name},"
+ " returning it as a symbol. The optional"
+ " @var{idx} argument is useful for TrueType Collections (TTC) and"
+ " OpenType/CFF collections (OTC) only;"
+ " it specifies the font index within the TTC/OTC."
+ " The default value of @var{idx} is@tie{}0.")
+{
+ LY_ASSERT_TYPE (scm_is_string, font_file_name, 1);
+
+ int i = 0;
+ if (!SCM_UNBNDP (idx))
+ {
+ LY_ASSERT_TYPE (scm_is_integer, idx, 2);
+ i = scm_to_int (idx);
+ if (i < 0)
+ {
+ warning (_ ("font index must be non-negative, using index 0"));
+ i = 0;
+ }
+ }
+
+ string file_name = ly_scm2string (font_file_name);
+
+ FT_Face face;
+ /* check whether font index is valid */
+ if (i > 0)
+ {
+ face = open_ft_face (file_name, -1);
+ if (i >= face->num_faces)
+ {
+ warning (_f ("font index %d too large for font `%s', using index 0",
+ i, file_name.c_str ()));
+ i = 0;
+ }
+ FT_Done_Face (face);
+ }
+
+ face = open_ft_face (file_name, i);
+ SCM asscm = scm_from_ascii_symbol (FT_Get_Font_Format (face));
+ FT_Done_Face (face);
+
+ return asscm;
+}
protected:
virtual void finalize ();
- DECLARE_ACKNOWLEDGER (note_column);
+ void acknowledge_note_column (Grob_info);
void process_music ();
void stop_translation_timestep ();
#include "translator.icc"
-ADD_ACKNOWLEDGER (Ottava_spanner_engraver, note_column);
+
+void
+Ottava_spanner_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Ottava_spanner_engraver, note_column);
+}
ADD_TRANSLATOR (Ottava_spanner_engraver,
/* doc */
{
Context_def *td = unsmob<Context_def> (scm_cdar (s));
SCM key = scm_caar (s);
- if (td && key == td->get_context_name ())
- ell = scm_cons (scm_cons (key, td->to_alist ()), ell);
+ if (td && scm_is_eq (key, td->get_context_name ()))
+ ell = scm_cons (scm_cons (key, td->to_alist ()), ell);
}
return ell;
}
}
const char
-Output_def::type_p_name_[] = "ly:output-def?";
+* const Output_def::type_p_name_ = "ly:output-def?";
LY_DEFINE (ly_paper_outputscale, "ly:paper-outputscale",
1, 0, 0, (SCM def),
}
SCM alist2 = SCM_EOL;
- if (scm_hash_table_p (tab2) == SCM_BOOL_T)
+ if (scm_is_true (scm_hash_table_p (tab2)))
{
// strip original-fonts/pango-font-descriptions
alist2 = scm_append (ly_alist_vals (ly_hash2alist (tab2)));
protected:
vector<Stream_event*> props_;
- DECLARE_ACKNOWLEDGER (grob);
- DECLARE_TRANSLATOR_LISTENER (apply_output);
+ void acknowledge_grob (Grob_info);
+ void listen_apply_output (Stream_event *);
void stop_translation_timestep ();
};
-IMPLEMENT_TRANSLATOR_LISTENER (Output_property_engraver, apply_output);
void
Output_property_engraver::listen_apply_output (Stream_event *ev)
{
{
}
-ADD_ACKNOWLEDGER (Output_property_engraver, grob);
+void
+Output_property_engraver::boot ()
+{
+ ADD_LISTENER (Output_property_engraver, apply_output);
+ ADD_ACKNOWLEDGER (Output_property_engraver, grob);
+}
+
ADD_TRANSLATOR (Output_property_engraver,
/* doc */
"Apply a procedure to any grob acknowledged.",
{
}
-const char Page_marker::type_p_name_[] = "ly:page-marker?";
+const char * const Page_marker::type_p_name_ = "ly:page-marker?";
SCM
Page_marker::mark_smob () const
Grob *breakable_column (Page_turn_event const &);
protected:
- DECLARE_TRANSLATOR_LISTENER (break);
- DECLARE_ACKNOWLEDGER (note_head);
+ void listen_break (Stream_event *);
+ void acknowledge_note_head (Grob_info);
public:
TRANSLATOR_DECLARATIONS (Page_turn_engraver);
note_end_ = now_mom () + dur_ptr->get_length ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Page_turn_engraver, break);
void
Page_turn_engraver::listen_break (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Page_turn_engraver, note_head);
+
+void
+Page_turn_engraver::boot ()
+{
+ ADD_LISTENER (Page_turn_engraver, break);
+ ADD_ACKNOWLEDGER (Page_turn_engraver, note_head);
+}
ADD_TRANSLATOR (Page_turn_engraver,
/* doc */
{
}
-const char Paper_book::type_p_name_[] = "ly:paper-book?";
+const char * const Paper_book::type_p_name_ = "ly:paper-book?";
SCM
Paper_book::mark_smob () const
system_->add_column (musical_column_);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Paper_column_engraver, break);
void
Paper_column_engraver::listen_break (Stream_event *ev)
{
break_events_.push_back (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Paper_column_engraver, label);
void
Paper_column_engraver::listen_label (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Paper_column_engraver, item);
-ADD_ACKNOWLEDGER (Paper_column_engraver, note_spacing);
-ADD_ACKNOWLEDGER (Paper_column_engraver, staff_spacing);
+
+void
+Paper_column_engraver::boot ()
+{
+ ADD_LISTENER (Paper_column_engraver, break);
+ ADD_LISTENER (Paper_column_engraver, label);
+ ADD_ACKNOWLEDGER (Paper_column_engraver, item);
+ ADD_ACKNOWLEDGER (Paper_column_engraver, note_spacing);
+ ADD_ACKNOWLEDGER (Paper_column_engraver, staff_spacing);
+}
ADD_TRANSLATOR (Paper_column_engraver,
/* doc */
#include "lily-imports.hh"
-const char * const Paper_outputter::type_p_name_ = 0;
-
Paper_outputter::Paper_outputter (SCM port, const string &format)
{
file_ = port;
TRANSLATOR_DECLARATIONS (Parenthesis_engraver);
protected:
- DECLARE_ACKNOWLEDGER (grob);
+ void acknowledge_grob (Grob_info);
};
Parenthesis_engraver::Parenthesis_engraver ()
}
}
-ADD_ACKNOWLEDGER (Parenthesis_engraver, grob);
+void
+Parenthesis_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Parenthesis_engraver, grob);
+}
+
ADD_TRANSLATOR (Parenthesis_engraver,
/* doc */
"Parenthesize objects whose music cause has the"
start_symbol:
lilypond
| EMBEDDED_LILY {
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::pitchnames);
} embedded_lilypond {
parser->lexer_->pop_state ();
*retval = $3;
embedded_scm
|
{
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::pitchnames);
}
composite_music
{
{
if (scm_is_pair ($1))
$1 = scm_car ($1);
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::pitchnames);
} music_or_context_def
{
parser->lexer_->pop_state ();
context_modification:
WITH
{
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::pitchnames);
} '{' context_mod_list '}'
{
parser->lexer_->pop_state ();
mode_changing_head:
NOTEMODE {
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::pitchnames);
$$ = ly_symbol2scm ("notes");
}
| DRUMMODE
{
- SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::drum_pitch_names);
$$ = ly_symbol2scm ("drums");
}
$$ = ly_symbol2scm ("figures");
}
| CHORDMODE {
- SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
- parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
- nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_chord_state (nn);
+ parser->lexer_->chordmodifier_tab_ =
+ alist_to_hashq (Lily::chordmodifiers);
+ parser->lexer_->push_chord_state (Lily::pitchnames);
$$ = ly_symbol2scm ("chords");
}
mode_changing_head_with_context:
DRUMS {
- SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::drum_pitch_names);
$$ = ly_symbol2scm ("DrumStaff");
}
$$ = ly_symbol2scm ("FiguredBass");
}
| CHORDS {
- SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
- parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
- nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_chord_state (nn);
+ parser->lexer_->chordmodifier_tab_ =
+ alist_to_hashq (Lily::chordmodifiers);
+ parser->lexer_->push_chord_state (Lily::pitchnames);
$$ = ly_symbol2scm ("ChordNames");
}
| LYRICS
$$ = $2;
}
| SCORELINES {
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::pitchnames);
} '{' score_body '}' {
Score *sc = unsmob<Score> ($4);
sc->origin ()->set_spot (@$);
$$ = make_simple_markup ($1);
}
| SCORE {
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
+ parser->lexer_->push_note_state (Lily::pitchnames);
} '{' score_body '}' {
Score *sc = unsmob<Score> ($4);
sc->origin ()->set_spot (@$);
TRANSLATOR_DECLARATIONS (Part_combine_engraver);
protected:
- DECLARE_ACKNOWLEDGER (note_head);
- DECLARE_ACKNOWLEDGER (stem);
+ void acknowledge_note_head (Grob_info);
+ void acknowledge_stem (Grob_info);
- DECLARE_TRANSLATOR_LISTENER (part_combine);
- DECLARE_TRANSLATOR_LISTENER (note);
+ void listen_part_combine (Stream_event *);
+ void listen_note (Stream_event *);
void process_music ();
void stop_translation_timestep ();
void create_item (Stream_event *ev);
Stream_event *waiting_event_;
};
-IMPLEMENT_TRANSLATOR_LISTENER (Part_combine_engraver, part_combine);
void
Part_combine_engraver::listen_part_combine (Stream_event *ev)
{
waiting_event_ = new_event_;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Part_combine_engraver, note);
void
Part_combine_engraver::listen_note (Stream_event *)
{
note_found_ = false;
}
-ADD_ACKNOWLEDGER (Part_combine_engraver, note_head);
-ADD_ACKNOWLEDGER (Part_combine_engraver, stem);
+void
+Part_combine_engraver::boot ()
+{
+ ADD_LISTENER (Part_combine_engraver, part_combine);
+ ADD_LISTENER (Part_combine_engraver, note);
+ ADD_ACKNOWLEDGER (Part_combine_engraver, note_head);
+ ADD_ACKNOWLEDGER (Part_combine_engraver, stem);
+}
+
ADD_TRANSLATOR (Part_combine_engraver,
/* doc */
"Part combine engraver for orchestral scores: Print markings"
Moment command_moment_;
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (percent);
+ void listen_percent (Stream_event *);
void start_translation_timestep ();
void stop_translation_timestep ();
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Percent_repeat_engraver, percent);
void
Percent_repeat_engraver::listen_percent (Stream_event *ev)
{
{
}
+void
+Percent_repeat_engraver::boot ()
+{
+ ADD_LISTENER (Percent_repeat_engraver, percent);
+}
+
ADD_TRANSLATOR (Percent_repeat_engraver,
/* doc */
"Make whole measure repeats.",
+#include "international.hh"
#include "program-option.hh"
#include "source-file.hh"
#include "memory-stream.hh"
}
LY_DEFINE (ly_otf_2_cff, "ly:otf->cff",
- 1, 0, 0, (SCM otf_file_name),
+ 1, 1, 0, (SCM otf_file_name, SCM idx),
"Convert the contents of an OTF file to a CFF file,"
- " returning it as a string.")
+ " returning it as a string. The optional"
+ " @var{idx} argument is useful for OpenType/CFF collections (OTC)"
+ " only; it specifies the font index within the OTC. The default"
+ " value of @var{idx} is@tie{}0.")
{
LY_ASSERT_TYPE (scm_is_string, otf_file_name, 1);
+ int i = 0;
+ if (!SCM_UNBNDP (idx))
+ {
+ LY_ASSERT_TYPE (scm_is_integer, idx, 2);
+ i = scm_to_int (idx);
+ if (i < 0)
+ {
+ warning (_ ("font index must be non-negative, using index 0"));
+ i = 0;
+ }
+ }
+
string file_name = ly_scm2string (otf_file_name);
debug_output ("[" + file_name); // start message on a new line
- FT_Face face = open_ft_face (file_name, 0 /* index */);
+ FT_Face face;
+ /* check whether font index is valid */
+ if (i > 0)
+ {
+ face = open_ft_face (file_name, -1);
+ if (i >= face->num_faces)
+ {
+ warning (_f ("font index %d too large for font `%s', using index 0",
+ i, file_name.c_str ()));
+ i = 0;
+ }
+ FT_Done_Face (face);
+ }
+
+ face = open_ft_face (file_name, i);
string table = get_otf_table (face, "CFF ");
SCM asscm = scm_from_latin1_stringn ((char *) table.data (),
table.length ());
+ FT_Done_Face (face);
debug_output ("]", false);
class Phrasing_slur_engraver : public Slur_proto_engraver
{
protected:
- DECLARE_TRANSLATOR_LISTENER (phrasing_slur);
- DECLARE_TRANSLATOR_LISTENER (note);
- DECLARE_ACKNOWLEDGER (slur);
+ void listen_phrasing_slur (Stream_event *);
+ void acknowledge_slur (Grob_info);
public:
SCM event_symbol ();
TRANSLATOR_DECLARATIONS (Phrasing_slur_engraver);
+ TRANSLATOR_INHERIT (Slur_proto_engraver);
};
Phrasing_slur_engraver::Phrasing_slur_engraver () :
return ly_symbol2scm ("phrasing-slur-event");
}
-IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, phrasing_slur);
void
Phrasing_slur_engraver::listen_phrasing_slur (Stream_event *ev)
{
Slur_proto_engraver::listen_slur (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, note);
void
-Phrasing_slur_engraver::listen_note (Stream_event *ev)
+Phrasing_slur_engraver::acknowledge_slur (Grob_info info)
{
- Slur_proto_engraver::listen_note (ev);
+ acknowledge_extra_object (info);
}
+
void
-Phrasing_slur_engraver::acknowledge_slur (Grob_info info)
+Phrasing_slur_engraver::boot ()
{
- acknowledge_extra_object (info);
+ ADD_LISTENER (Phrasing_slur_engraver, phrasing_slur);
+ ADD_LISTENER (Slur_proto_engraver, note);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, inline_accidental);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, fingering);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, note_column);
+ ADD_ACKNOWLEDGER (Phrasing_slur_engraver, slur);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, script);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, dots);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, text_script);
+ ADD_END_ACKNOWLEDGER (Slur_proto_engraver, tie);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, tuplet_number);
}
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, inline_accidental);
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, fingering)
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, note_column);
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, slur);
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, script);
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, dots);
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, text_script);
-ADD_END_ACKNOWLEDGER (Phrasing_slur_engraver, tie);
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, tuplet_number);
-
ADD_TRANSLATOR (Phrasing_slur_engraver,
/* doc */
"Print phrasing slurs. Similar to @ref{Slur_engraver}.",
protected:
virtual void finalize ();
- DECLARE_ACKNOWLEDGER (piano_pedal_script);
- DECLARE_ACKNOWLEDGER (piano_pedal_bracket);
- DECLARE_ACKNOWLEDGER (note_column);
+ void acknowledge_piano_pedal_script (Grob_info);
+ void acknowledge_piano_pedal_bracket (Grob_info);
+ void acknowledge_note_column (Grob_info);
- DECLARE_END_ACKNOWLEDGER (piano_pedal_bracket);
+ void acknowledge_end_piano_pedal_bracket (Grob_info);
void stop_translation_timestep ();
void start_translation_timestep ();
}
}
-ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, note_column);
-ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
-ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_script);
-ADD_END_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
+
+void
+Piano_pedal_align_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, note_column);
+ ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
+ ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_script);
+ ADD_END_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
+}
ADD_TRANSLATOR (Piano_pedal_align_engraver,
/* doc */
protected:
virtual void initialize ();
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (sustain);
- DECLARE_TRANSLATOR_LISTENER (una_corda);
- DECLARE_TRANSLATOR_LISTENER (sostenuto);
+ void listen_sustain (Stream_event *);
+ void listen_una_corda (Stream_event *);
+ void listen_sostenuto (Stream_event *);
void stop_translation_timestep ();
void process_music ();
info_list_[NUM_PEDAL_TYPES].type_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sostenuto);
void
Piano_pedal_engraver::listen_sostenuto (Stream_event *ev)
{
ASSIGN_EVENT_ONCE (info_list_[SOSTENUTO].event_drul_[d], ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sustain);
void
Piano_pedal_engraver::listen_sustain (Stream_event *ev)
{
ASSIGN_EVENT_ONCE (info_list_[SUSTAIN].event_drul_[d], ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, una_corda);
void
Piano_pedal_engraver::listen_una_corda (Stream_event *ev)
{
}
}
+void
+Piano_pedal_engraver::boot ()
+{
+ ADD_LISTENER (Piano_pedal_engraver, sostenuto);
+ ADD_LISTENER (Piano_pedal_engraver, sustain);
+ ADD_LISTENER (Piano_pedal_engraver, una_corda);
+}
+
ADD_TRANSLATOR (Piano_pedal_engraver,
/* doc */
"Engrave piano pedal symbols and brackets.",
void process_music ();
void stop_translation_timestep ();
void start_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (sustain);
- DECLARE_TRANSLATOR_LISTENER (una_corda);
- DECLARE_TRANSLATOR_LISTENER (sostenuto);
+ void listen_sustain (Stream_event *);
+ void listen_una_corda (Stream_event *);
+ void listen_sostenuto (Stream_event *);
private:
vector<Audio_piano_pedal *> audios_;
Pedal_info info_alist_[NUM_PEDAL_TYPES];
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sostenuto);
void
Piano_pedal_performer::listen_sostenuto (Stream_event *r)
{
info_alist_[SOSTENUTO].event_drul_[d] = r;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sustain);
void
Piano_pedal_performer::listen_sustain (Stream_event *r)
{
info_alist_[SUSTAIN].event_drul_[d] = r;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, una_corda);
void
Piano_pedal_performer::listen_una_corda (Stream_event *r)
{
info_alist_[UNA_CORDA].event_drul_[d] = r;
}
+void
+Piano_pedal_performer::boot ()
+{
+ ADD_LISTENER (Piano_pedal_performer, sostenuto);
+ ADD_LISTENER (Piano_pedal_performer, sustain);
+ ADD_LISTENER (Piano_pedal_performer, una_corda);
+}
+
ADD_TRANSLATOR (Piano_pedal_performer,
/* doc */
"",
{
public:
TRANSLATOR_DECLARATIONS (Pitch_squash_engraver);
- DECLARE_ACKNOWLEDGER (note_head);
+ void acknowledge_note_head (Grob_info);
};
void
}
#include "translator.icc"
-ADD_ACKNOWLEDGER (Pitch_squash_engraver, note_head);
+void
+Pitch_squash_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Pitch_squash_engraver, note_head);
+}
+
ADD_TRANSLATOR (Pitch_squash_engraver,
/* doc */
"Set the vertical position of note heads to"
notename_ = notename;
}
-const char Pitch::type_p_name_[] = "ly:pitch?";
+const char * const Pitch::type_p_name_ = "ly:pitch?";
SCM
Pitch::mark_smob () const
TRANSLATOR_DECLARATIONS (Pitched_trill_engraver);
protected:
- DECLARE_ACKNOWLEDGER (note_head);
- DECLARE_ACKNOWLEDGER (dots);
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (flag);
- DECLARE_ACKNOWLEDGER (trill_spanner);
+ void acknowledge_note_head (Grob_info);
+ void acknowledge_dots (Grob_info);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_flag (Grob_info);
+ void acknowledge_trill_spanner (Grob_info);
void stop_translation_timestep ();
private:
trill_accidental_ = 0;
}
-ADD_ACKNOWLEDGER (Pitched_trill_engraver, note_head);
-ADD_ACKNOWLEDGER (Pitched_trill_engraver, dots);
-ADD_ACKNOWLEDGER (Pitched_trill_engraver, stem);
-ADD_ACKNOWLEDGER (Pitched_trill_engraver, flag);
-ADD_ACKNOWLEDGER (Pitched_trill_engraver, trill_spanner);
+
+void
+Pitched_trill_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Pitched_trill_engraver, note_head);
+ ADD_ACKNOWLEDGER (Pitched_trill_engraver, dots);
+ ADD_ACKNOWLEDGER (Pitched_trill_engraver, stem);
+ ADD_ACKNOWLEDGER (Pitched_trill_engraver, flag);
+ ADD_ACKNOWLEDGER (Pitched_trill_engraver, trill_spanner);
+}
ADD_TRANSLATOR (Pitched_trill_engraver,
/* doc */
#include "profile.hh"
-const char Prob::type_p_name_[] = "ly:prob?";
+const char * const Prob::type_p_name_ = "ly:prob?";
SCM
Prob::equal_p (SCM sa, SCM sb)
assert (SCM_IMP (s));
}
-// For static objects, this will be called at program exit. With the
-// state of the memory system unknown, we refrain from any cleanup
-// actions outside of the object memory itself.
+SCM Protected_scm::list_ = SCM_EOL;
+SCM Protected_scm::last_ = SCM_EOL;
-Protected_scm::~Protected_scm ()
+void
+Protected_scm::protectify (SCM s)
{
- object_ = SCM_UNDEFINED;
+ s = scm_list_1 (s);
+ if (SCM_CONSP (last_))
+ SCM_SETCDR (last_, s);
+ else
+ list_ = scm_permanent_object (s);
+ last_ = object_ = s;
}
-SCM Protected_scm::list_ = SCM_EOL;
-SCM Protected_scm::last_ = SCM_EOL;
-
Protected_scm &
Protected_scm::operator = (SCM s)
{
else if (SCM_IMP (s))
object_ = s;
else
- {
- s = scm_list_1 (s);
- if (SCM_CONSP (last_))
- SCM_SETCDR (last_, s);
- else
- list_ = scm_permanent_object (s);
- last_ = object_ = s;
- }
+ protectify (s);
return *this;
}
return *this = (SCM) s;
}
-Protected_scm::operator SCM () const
+Protected_scm::operator SCM const & () const
{
- return SCM_CONSP (object_) ? SCM_CAR (object_) : object_;
+ return SCM_CONSP (object_) ? *SCM_CARLOC (object_) : object_;
+}
+
+Protected_scm::operator SCM & ()
+{
+ // The reference may be used to overwrite an immediate value with a
+ // non-immediate one, so we _have_ to create full protection.
+ if (!SCM_CONSP (object_))
+ protectify (object_);
+
+ return *SCM_CARLOC (object_);
}
public:
TRANSLATOR_DECLARATIONS (Pure_from_neighbor_engraver);
protected:
- DECLARE_ACKNOWLEDGER (pure_from_neighbor);
- DECLARE_ACKNOWLEDGER (item);
+ void acknowledge_pure_from_neighbor (Grob_info);
+ void acknowledge_item (Grob_info);
void finalize ();
};
pure_relevants_.clear ();
}
-ADD_ACKNOWLEDGER (Pure_from_neighbor_engraver, item);
-ADD_ACKNOWLEDGER (Pure_from_neighbor_engraver, pure_from_neighbor);
+void
+Pure_from_neighbor_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Pure_from_neighbor_engraver, item);
+ ADD_ACKNOWLEDGER (Pure_from_neighbor_engraver, pure_from_neighbor);
+}
+
ADD_TRANSLATOR (Pure_from_neighbor_engraver,
/* doc */
"Coordinates items that get their pure heights from their neighbors.",
}
}
+void
+Repeat_acknowledge_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Repeat_acknowledge_engraver,
/* doc */
"Acknowledge repeated music, and convert the contents of"
vector<Grob *> semi_ties_;
void stop_translation_timestep ();
- DECLARE_ACKNOWLEDGER (note_head);
- DECLARE_TRANSLATOR_LISTENER (repeat_tie);
+ void acknowledge_note_head (Grob_info);
+ void listen_repeat_tie (Stream_event *);
public:
TRANSLATOR_DECLARATIONS (Repeat_tie_engraver);
semi_ties_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Repeat_tie_engraver, repeat_tie);
void
Repeat_tie_engraver::listen_repeat_tie (Stream_event *ev)
{
}
-ADD_ACKNOWLEDGER (Repeat_tie_engraver, note_head);
+void
+Repeat_tie_engraver::boot ()
+{
+ ADD_LISTENER (Repeat_tie_engraver, repeat_tie);
+ ADD_ACKNOWLEDGER (Repeat_tie_engraver, note_head);
+}
+
ADD_TRANSLATOR (Repeat_tie_engraver,
/* doc */
"Create repeat ties.",
rest_collision_ = 0;
}
+void
+Rest_collision_engraver::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Rest_collision_engraver,
/* doc */
"Handle collisions of rests.",
protected:
void start_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (rest);
+ void listen_rest (Stream_event *);
public:
TRANSLATOR_DECLARATIONS (Rest_engraver);
};
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Rest_engraver, rest);
void
Rest_engraver::listen_rest (Stream_event *ev)
{
ASSIGN_EVENT_ONCE (rest_event_, ev);
}
+void
+Rest_engraver::boot ()
+{
+ ADD_LISTENER (Rest_engraver, rest);
+}
+
ADD_TRANSLATOR (Rest_engraver,
/* doc */
"Engrave rests.",
TRANSLATOR_DECLARATIONS (Rhythmic_column_engraver);
protected:
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (flag);
- DECLARE_ACKNOWLEDGER (rhythmic_head);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_flag (Grob_info);
+ void acknowledge_rhythmic_head (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
};
flag_ = 0;
}
-ADD_ACKNOWLEDGER (Rhythmic_column_engraver, stem);
-ADD_ACKNOWLEDGER (Rhythmic_column_engraver, flag);
-ADD_ACKNOWLEDGER (Rhythmic_column_engraver, rhythmic_head);
+
+void
+Rhythmic_column_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Rhythmic_column_engraver, stem);
+ ADD_ACKNOWLEDGER (Rhythmic_column_engraver, flag);
+ ADD_ACKNOWLEDGER (Rhythmic_column_engraver, rhythmic_head);
+}
ADD_TRANSLATOR (Rhythmic_column_engraver,
/* doc */
return SCM_UNSPECIFIED;
}
-const char * const Scale::type_p_name_ = 0;
-
int
Scale::step_count () const
{
#include "translator.icc"
+#include "scm-hash.hh"
+
Scheme_engraver::Scheme_engraver (SCM definition)
{
- stop_translation_timestep_function_ = SCM_EOL;
- start_translation_timestep_function_ = SCM_EOL;
- process_music_function_ = SCM_EOL;
- process_acknowledged_function_ = SCM_EOL;
initialize_function_ = SCM_EOL;
finalize_function_ = SCM_EOL;
- interface_acknowledger_hash_ = SCM_EOL;
- interface_end_acknowledger_hash_ = SCM_EOL;
+ interface_acknowledger_hash_.set (SCM_EOL, SCM_EOL);
must_be_last_ = false;
per_instance_listeners_ = SCM_EOL;
+ for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
+ precomputable_methods_[i] = SCM_UNDEFINED;
init_from_scheme (definition);
}
{
}
-// Extracts the value if callable, if not return #f.
+// Extracts the value if callable, if not return SCM_UNDEFINED;
static SCM
callable (SCM symbol, SCM defn)
{
SCM val = ly_assoc_get (symbol, defn, SCM_BOOL_F);
- return ly_is_procedure (val) ? val : SCM_BOOL_F;
+ return ly_is_procedure (val) ? val : SCM_UNDEFINED;
}
bool
return must_be_last_;
}
+void
+Scheme_engraver::fetch_precomputable_methods (SCM ptrs[])
+{
+ for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
+ ptrs[i] = precomputable_methods_[i];
+}
+
void
Scheme_engraver::init_from_scheme (SCM definition)
{
- start_translation_timestep_function_ = callable (ly_symbol2scm ("start-translation-timestep"),
- definition);
- stop_translation_timestep_function_ = callable (ly_symbol2scm ("stop-translation-timestep"),
- definition);
- process_music_function_ = callable (ly_symbol2scm ("process-music"), definition);
- process_acknowledged_function_ = callable (ly_symbol2scm ("process-acknowledged"),
- definition);
+ precomputable_methods_[START_TRANSLATION_TIMESTEP]
+ = callable (ly_symbol2scm ("start-translation-timestep"), definition);
+ precomputable_methods_[STOP_TRANSLATION_TIMESTEP]
+ = callable (ly_symbol2scm ("stop-translation-timestep"), definition);
+ precomputable_methods_[PROCESS_MUSIC]
+ = callable (ly_symbol2scm ("process-music"), definition);
+ precomputable_methods_[PROCESS_ACKNOWLEDGED]
+ = callable (ly_symbol2scm ("process-acknowledged"), definition);
initialize_function_ = callable (ly_symbol2scm ("initialize"), definition);
finalize_function_ = callable (ly_symbol2scm ("finalize"), definition);
- SCM listeners = ly_assoc_get (ly_symbol2scm ("listeners"), definition, SCM_EOL);
-
- per_instance_listeners_ = SCM_EOL;
+ SCM p = ly_assoc_get (ly_symbol2scm ("listeners"), definition, SCM_EOL);
+ SCM listeners = SCM_EOL;
must_be_last_ = to_boolean (ly_assoc_get (ly_symbol2scm ("must-be-last"),
definition,
SCM_BOOL_F));
- for (SCM p = listeners; scm_is_pair (p); p = scm_cdr (p))
+ for (; scm_is_pair (p); p = scm_cdr (p))
{
SCM event_class = scm_caar (p);
SCM proc = scm_cdar (p);
// We should check the arity of the function?
// Record for later lookup.
- per_instance_listeners_ = scm_acons (event_class, proc, per_instance_listeners_);
+ listeners = scm_acons (event_class, proc, listeners);
}
- init_acknowledgers (ly_assoc_get (ly_symbol2scm ("acknowledgers"),
- definition, SCM_EOL),
- &interface_acknowledger_hash_);
+ SCM hash1 =
+ init_acknowledgers (ly_assoc_get (ly_symbol2scm ("acknowledgers"),
+ definition, SCM_EOL));
+ SCM hash2 =
+ init_acknowledgers (ly_assoc_get (ly_symbol2scm ("end-acknowledgers"),
+ definition, SCM_EOL));
- init_acknowledgers (ly_assoc_get (ly_symbol2scm ("end-acknowledgers"),
- definition, SCM_EOL),
- &interface_end_acknowledger_hash_);
+ per_instance_listeners_ = listeners;
+ interface_acknowledger_hash_.set (hash1, hash2);
+
+ // It's not defined whether Scheme_engraver::derived_mark is already
+ // active while the construction is underway, so we make sure we
+ // keep a version of everything on the stack that is not still
+ // covered by `definition'.
+
+ scm_remember_upto_here_2 (definition, listeners);
+ scm_remember_upto_here_2 (hash1, hash2);
// TODO: hook up description, props read/written, grobs created
// etc. to provide automatic documentation.
}
-void
-Scheme_engraver::init_acknowledgers (SCM alist,
- SCM *hash)
+SCM
+Scheme_engraver::init_acknowledgers (SCM alist)
{
- *hash = scm_c_make_hash_table (7);
+ SCM hash = Scheme_hash_table::make_smob ();
for (SCM p = alist; scm_is_pair (p); p = scm_cdr (p))
{
SCM iface = scm_caar (p);
if (!(ly_is_procedure (proc) && ly_is_symbol (iface)))
continue;
- scm_hashq_set_x (*hash, iface, proc);
+ unsmob<Scheme_hash_table>(hash)->set (iface, proc);
}
+ return hash;
}
-// This is the easy way to do it, at the cost of too many invocations
-// of Scheme_engraver::acknowledge_grob. The clever dispatching of
-// acknowledgers is hardwired to have 1 method per engraver per
-// grob-type, which doesn't work for this case.
-void
-Scheme_engraver::acknowledge_grob (Grob_info info)
+SCM
+Scheme_engraver::get_listener_list () const
{
- acknowledge_grob_by_hash (info, interface_acknowledger_hash_);
+ return per_instance_listeners_;
}
void
-Scheme_engraver::acknowledge_end_grob (Grob_info info)
+Scheme_engraver::initialize ()
{
- acknowledge_grob_by_hash (info, interface_end_acknowledger_hash_);
+ if (!SCM_UNBNDP (initialize_function_))
+ scm_call_1 (initialize_function_, self_scm ());
}
void
-Scheme_engraver::acknowledge_grob_by_hash (Grob_info info,
- SCM iface_function_hash)
-{
- SCM meta = info.grob ()->get_property ("meta");
- SCM ifaces = scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta));
- for (SCM s = ifaces; scm_is_pair (s); s = scm_cdr (s))
- {
- SCM func = scm_hashq_ref (iface_function_hash,
- scm_car (s), SCM_BOOL_F);
-
- if (ly_is_procedure (func))
- scm_call_3 (func, self_scm (), info.grob ()->self_scm (),
- info.origin_translator ()->self_scm ());
- }
-}
-
-SCM
-Scheme_engraver::get_listener_list () const
+Scheme_engraver::finalize ()
{
- return per_instance_listeners_;
+ if (!SCM_UNBNDP (finalize_function_))
+ scm_call_1 (finalize_function_, self_scm ());
}
-#define DISPATCH(what) \
- void \
- Scheme_engraver::what () \
- { \
- if (what ## _function_ != SCM_BOOL_F) \
- scm_call_1 (what ## _function_, self_scm ()); \
- }
-
-DISPATCH (start_translation_timestep);
-DISPATCH (stop_translation_timestep);
-DISPATCH (initialize);
-DISPATCH (finalize);
-DISPATCH (process_music);
-DISPATCH (process_acknowledged);
-
void
Scheme_engraver::derived_mark () const
{
- scm_gc_mark (start_translation_timestep_function_);
- scm_gc_mark (stop_translation_timestep_function_);
+ for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
+ scm_gc_mark (precomputable_methods_[i]);
+
scm_gc_mark (initialize_function_);
scm_gc_mark (finalize_function_);
- scm_gc_mark (process_music_function_);
- scm_gc_mark (process_acknowledged_function_);
scm_gc_mark (per_instance_listeners_);
- scm_gc_mark (interface_acknowledger_hash_);
- scm_gc_mark (interface_end_acknowledger_hash_);
+ scm_gc_mark (interface_acknowledger_hash_[START]);
+ scm_gc_mark (interface_acknowledger_hash_[STOP]);
}
-
-ADD_ACKNOWLEDGER (Scheme_engraver, grob);
-ADD_END_ACKNOWLEDGER (Scheme_engraver, grob);
-
-ADD_TRANSLATOR_FAMILY (Scheme_engraver);
#include <cassert>
-const char * const Scheme_hash_table::type_p_name_ = 0;
-
SCM
Scheme_hash_table::make_smob ()
{
SCM
Scheme_hash_table::get (SCM k) const
{
- /* SCM_UNSPECIFIED will stick out like a sore thumb, hopefully.
+ /* SCM_UNDEFINED is the default for unset elements, but
+ scm_hashq_ref cannot return it, so we do it a bit more awkwardly.
*/
- return scm_hashq_ref (hash_tab (), k, SCM_UNSPECIFIED);
+ SCM handle = scm_hashq_get_handle (hash_tab (), k);
+ if (scm_is_pair (handle))
+ return scm_cdr (handle);
+ return SCM_UNDEFINED;
}
void
void
Score_engraver::finish (SCM)
{
- recurse_over_translators (context (), &Translator::finalize,
- &Translator_group::finalize,
- UP);
+ recurse_over_translators
+ (context (),
+ Callback0_wrapper::make_smob<Translator, &Translator::finalize> (),
+ Callback0_wrapper::make_smob<Translator_group, &Translator_group::finalize> (),
+ UP);
}
#define MUSIC_FONT "emmentaler-20"
SCM channel_mapping = context ()->get_property ("midiChannelMapping");
bool use_ports = scm_is_eq (channel_mapping, ly_symbol2scm ("voice"));
performance_->ports_ = use_ports;
- recurse_over_translators (context (),
- &Translator::finalize,
- &Translator_group::finalize,
- UP);
+ recurse_over_translators
+ (context (),
+ Callback0_wrapper::make_smob<Translator, &Translator::finalize> (),
+ Callback0_wrapper::make_smob<Translator_group, &Translator_group::finalize> (),
+ UP);
}
void
{
}
-const char Score::type_p_name_[] = "ly:score?";
+const char * const Score::type_p_name_ = "ly:score?";
SCM
Score::mark_smob () const
public:
TRANSLATOR_DECLARATIONS (Script_column_engraver);
protected:
- DECLARE_ACKNOWLEDGER (side_position);
+ void acknowledge_side_position (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
};
script_column_ = make_item ("ScriptColumn", SCM_EOL);
}
-ADD_ACKNOWLEDGER (Script_column_engraver, side_position);
+void
+Script_column_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Script_column_engraver, side_position);
+}
+
ADD_TRANSLATOR (Script_column_engraver,
/* doc */
"Find potentially colliding scripts and put them into a"
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (articulation);
- DECLARE_ACKNOWLEDGER (rhythmic_head);
- DECLARE_ACKNOWLEDGER (stem);
- DECLARE_ACKNOWLEDGER (stem_tremolo);
- DECLARE_ACKNOWLEDGER (tie);
- DECLARE_END_ACKNOWLEDGER (tie);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (inline_accidental);
+ void listen_articulation (Stream_event *);
+ void acknowledge_rhythmic_head (Grob_info);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_stem_tremolo (Grob_info);
+ void acknowledge_tie (Grob_info);
+ void acknowledge_end_tie (Grob_info);
+ void acknowledge_note_column (Grob_info);
+ void acknowledge_inline_accidental (Grob_info);
public:
TRANSLATOR_DECLARATIONS (Script_engraver);
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Script_engraver, articulation);
void
Script_engraver::listen_articulation (Stream_event *ev)
{
scripts_.clear ();
}
-ADD_ACKNOWLEDGER (Script_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Script_engraver, stem);
-ADD_ACKNOWLEDGER (Script_engraver, tie);
-ADD_END_ACKNOWLEDGER (Script_engraver, tie);
-ADD_ACKNOWLEDGER (Script_engraver, note_column);
-ADD_ACKNOWLEDGER (Script_engraver, stem_tremolo);
-ADD_ACKNOWLEDGER (Script_engraver, inline_accidental);
+
+void
+Script_engraver::boot ()
+{
+ ADD_LISTENER (Script_engraver, articulation);
+ ADD_ACKNOWLEDGER (Script_engraver, rhythmic_head);
+ ADD_ACKNOWLEDGER (Script_engraver, stem);
+ ADD_ACKNOWLEDGER (Script_engraver, tie);
+ ADD_END_ACKNOWLEDGER (Script_engraver, tie);
+ ADD_ACKNOWLEDGER (Script_engraver, note_column);
+ ADD_ACKNOWLEDGER (Script_engraver, stem_tremolo);
+ ADD_ACKNOWLEDGER (Script_engraver, inline_accidental);
+}
ADD_TRANSLATOR (Script_engraver,
/* doc */
public:
TRANSLATOR_DECLARATIONS (Script_row_engraver);
protected:
- DECLARE_ACKNOWLEDGER (accidental_placement);
- DECLARE_ACKNOWLEDGER (side_position);
+ void acknowledge_accidental_placement (Grob_info);
+ void acknowledge_side_position (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
};
script_row_ = make_item ("ScriptRow", SCM_EOL);
}
-ADD_ACKNOWLEDGER (Script_row_engraver, accidental_placement);
-ADD_ACKNOWLEDGER (Script_row_engraver, side_position);
+void
+Script_row_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Script_row_engraver, accidental_placement);
+ ADD_ACKNOWLEDGER (Script_row_engraver, side_position);
+}
+
ADD_TRANSLATOR (Script_row_engraver,
/* doc */
"Determine order in horizontal side position elements.",
Spacings current_spacings_;
Spacings last_spacings_;
- DECLARE_ACKNOWLEDGER (item);
- DECLARE_ACKNOWLEDGER (break_aligned);
+ void acknowledge_item (Grob_info);
+ void acknowledge_break_aligned (Grob_info);
void stop_translation_timestep ();
void start_translation_timestep ();
break_aligned_.clear ();
}
-ADD_ACKNOWLEDGER (Separating_line_group_engraver, item);
-ADD_ACKNOWLEDGER (Separating_line_group_engraver, break_aligned);
+
+void
+Separating_line_group_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Separating_line_group_engraver, item);
+ ADD_ACKNOWLEDGER (Separating_line_group_engraver, break_aligned);
+}
ADD_TRANSLATOR (Separating_line_group_engraver,
/* doc */
return skylines_[d];
}
-const char Skyline_pair::type_p_name_[] = "ly:skyline-pair?";
+const char * const Skyline_pair::type_p_name_ = "ly:skyline-pair?";
MAKE_SCHEME_CALLBACK (Skyline_pair, skyline, 2);
/****************************************************************/
-const char Skyline::type_p_name_[] = "ly:skyline?";
+const char * const Skyline::type_p_name_ = "ly:skyline?";
MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Skyline, get_touching_point, 3, 1, "")
SCM
protected:
Stream_event *slash_;
protected:
- DECLARE_TRANSLATOR_LISTENER (repeat_slash);
+ void listen_repeat_slash (Stream_event *);
void process_music ();
};
slash_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Slash_repeat_engraver, repeat_slash);
void
Slash_repeat_engraver::listen_repeat_slash (Stream_event *ev)
{
}
}
+void
+Slash_repeat_engraver::boot ()
+{
+ ADD_LISTENER (Slash_repeat_engraver, repeat_slash);
+}
+
ADD_TRANSLATOR (Slash_repeat_engraver,
/* doc */
"Make beat repeats.",
{
virtual void set_melisma (bool);
-protected:
- DECLARE_TRANSLATOR_LISTENER (slur);
- DECLARE_TRANSLATOR_LISTENER (note);
-
public:
SCM event_symbol ();
TRANSLATOR_DECLARATIONS (Slur_engraver);
+ TRANSLATOR_INHERIT (Slur_proto_engraver);
};
Slur_engraver::Slur_engraver () :
return ly_symbol2scm ("slur-event");
}
-IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, slur);
-void
-Slur_engraver::listen_slur (Stream_event *ev)
-{
- Slur_proto_engraver::listen_slur (ev);
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, note);
void
-Slur_engraver::listen_note (Stream_event *ev)
+Slur_engraver::set_melisma (bool m)
{
- Slur_proto_engraver::listen_note (ev);
+ context ()->set_property ("slurMelismaBusy", ly_bool2scm (m));
}
void
-Slur_engraver::set_melisma (bool m)
+Slur_engraver::boot ()
{
- context ()->set_property ("slurMelismaBusy", ly_bool2scm (m));
+ ADD_LISTENER (Slur_proto_engraver, slur);
+ ADD_LISTENER (Slur_proto_engraver, note);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, inline_accidental);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, fingering);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, note_column);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, script);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, text_script);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, dots);
+ ADD_END_ACKNOWLEDGER (Slur_proto_engraver, tie);
+ ADD_ACKNOWLEDGER (Slur_proto_engraver, tuplet_number);
}
-ADD_ACKNOWLEDGER (Slur_engraver, inline_accidental);
-ADD_ACKNOWLEDGER (Slur_engraver, fingering);
-ADD_ACKNOWLEDGER (Slur_engraver, note_column);
-ADD_ACKNOWLEDGER (Slur_engraver, script);
-ADD_ACKNOWLEDGER (Slur_engraver, text_script);
-ADD_ACKNOWLEDGER (Slur_engraver, dots);
-ADD_END_ACKNOWLEDGER (Slur_engraver, tie);
-ADD_ACKNOWLEDGER (Slur_engraver, tuplet_number);
ADD_TRANSLATOR (Slur_engraver,
/* doc */
"Build slur grobs from slur events.",
void process_music ();
void set_melisma (bool);
- DECLARE_TRANSLATOR_LISTENER (slur);
+ void listen_slur (Stream_event *);
private:
Stream_event *start_ev_;
Stream_event *now_stop_ev_;
now_stop_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Slur_performer, slur);
void
Slur_performer::listen_slur (Stream_event *ev)
{
now_stop_ev_ = ev;
}
+void
+Slur_performer::boot ()
+{
+ ADD_LISTENER (Slur_performer, slur);
+}
+
ADD_TRANSLATOR (Slur_performer,
/* doc */
"",
/****************************************************************/
-const char Source_file::type_p_name_[] = "ly:source-file?";
+const char * const Source_file::type_p_name_ = "ly:source-file?";
SCM
Source_file::mark_smob () const
TRANSLATOR_DECLARATIONS (Spacing_engraver);
protected:
- DECLARE_ACKNOWLEDGER (staff_spacing);
- DECLARE_ACKNOWLEDGER (note_spacing);
- DECLARE_ACKNOWLEDGER (rhythmic_head);
- DECLARE_ACKNOWLEDGER (rhythmic_grob);
- DECLARE_TRANSLATOR_LISTENER (spacing_section);
+ void acknowledge_staff_spacing (Grob_info);
+ void acknowledge_note_spacing (Grob_info);
+ void acknowledge_rhythmic_head (Grob_info);
+ void acknowledge_rhythmic_grob (Grob_info);
+ void listen_spacing_section (Stream_event *);
void start_translation_timestep ();
void stop_translation_timestep ();
start_section_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Spacing_engraver, spacing_section);
void
Spacing_engraver::listen_spacing_section (Stream_event *ev)
{
stopped_durations_.push_back (playing_durations_.get ());
}
-ADD_ACKNOWLEDGER (Spacing_engraver, staff_spacing);
-ADD_ACKNOWLEDGER (Spacing_engraver, note_spacing);
-ADD_ACKNOWLEDGER (Spacing_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Spacing_engraver, rhythmic_grob);
+
+void
+Spacing_engraver::boot ()
+{
+ ADD_LISTENER (Spacing_engraver, spacing_section);
+ ADD_ACKNOWLEDGER (Spacing_engraver, staff_spacing);
+ ADD_ACKNOWLEDGER (Spacing_engraver, note_spacing);
+ ADD_ACKNOWLEDGER (Spacing_engraver, rhythmic_head);
+ ADD_ACKNOWLEDGER (Spacing_engraver, rhythmic_grob);
+}
ADD_TRANSLATOR (Spacing_engraver,
/* doc */
{
public:
TRANSLATOR_DECLARATIONS (Span_arpeggio_engraver);
- DECLARE_ACKNOWLEDGER (arpeggio);
- DECLARE_ACKNOWLEDGER (note_column);
+ void acknowledge_arpeggio (Grob_info);
+ void acknowledge_note_column (Grob_info);
protected:
void process_acknowledged ();
note_columns_.clear ();
}
-ADD_ACKNOWLEDGER (Span_arpeggio_engraver, arpeggio);
-ADD_ACKNOWLEDGER (Span_arpeggio_engraver, note_column);
+void
+Span_arpeggio_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Span_arpeggio_engraver, arpeggio);
+ ADD_ACKNOWLEDGER (Span_arpeggio_engraver, note_column);
+}
+
ADD_TRANSLATOR (Span_arpeggio_engraver,
/* doc */
"Make arpeggios that span multiple staves.",
public:
TRANSLATOR_DECLARATIONS (Span_bar_engraver);
protected:
- DECLARE_ACKNOWLEDGER (bar_line);
+ void acknowledge_bar_line (Grob_info);
void stop_translation_timestep ();
void process_acknowledged ();
};
bars_.resize (0);
}
-ADD_ACKNOWLEDGER (Span_bar_engraver, bar_line);
+void
+Span_bar_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Span_bar_engraver, bar_line);
+}
+
ADD_TRANSLATOR (Span_bar_engraver,
/* doc */
"Make cross-staff bar lines: It catches all normal bar lines"
public:
TRANSLATOR_DECLARATIONS (Span_bar_stub_engraver);
protected:
- DECLARE_ACKNOWLEDGER (span_bar);
- DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
+ void acknowledge_span_bar (Grob_info);
+ void acknowledge_hara_kiri_group_spanner (Grob_info);
void process_acknowledged ();
void stop_translation_timestep ();
virtual void derived_mark () const;
axis_groups_ = axis_groups;
}
-ADD_ACKNOWLEDGER (Span_bar_stub_engraver, span_bar);
-ADD_ACKNOWLEDGER (Span_bar_stub_engraver, hara_kiri_group_spanner);
+void
+Span_bar_stub_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Span_bar_stub_engraver, span_bar);
+ ADD_ACKNOWLEDGER (Span_bar_stub_engraver, hara_kiri_group_spanner);
+}
+
ADD_TRANSLATOR (Span_bar_stub_engraver,
/* doc */
"Make stubs for span bars in all contexts that the span bars cross.",
TRANSLATOR_DECLARATIONS (Spanner_break_forbid_engraver);
vector<Spanner *> running_spanners_;
protected:
- DECLARE_ACKNOWLEDGER (unbreakable_spanner);
- DECLARE_END_ACKNOWLEDGER (unbreakable_spanner);
+ void acknowledge_unbreakable_spanner (Grob_info);
+ void acknowledge_end_unbreakable_spanner (Grob_info);
void process_music ();
};
{
}
-ADD_END_ACKNOWLEDGER (Spanner_break_forbid_engraver, unbreakable_spanner);
-ADD_ACKNOWLEDGER (Spanner_break_forbid_engraver, unbreakable_spanner);
+void
+Spanner_break_forbid_engraver::boot ()
+{
+ ADD_END_ACKNOWLEDGER (Spanner_break_forbid_engraver, unbreakable_spanner);
+ ADD_ACKNOWLEDGER (Spanner_break_forbid_engraver, unbreakable_spanner);
+}
+
ADD_TRANSLATOR (Spanner_break_forbid_engraver,
/* doc */
"Forbid breaks in certain spanners.",
return s->smobbed_copy ();
}
-const char Spring::type_p_name_[] = "ly:spring?";
+const char * const Spring::type_p_name_ = "ly:spring?";
{
public:
TRANSLATOR_DECLARATIONS (Staff_collecting_engraver);
- DECLARE_ACKNOWLEDGER (staff_symbol);
- DECLARE_END_ACKNOWLEDGER (staff_symbol);
+ void acknowledge_staff_symbol (Grob_info);
+ void acknowledge_end_staff_symbol (Grob_info);
};
Staff_collecting_engraver::Staff_collecting_engraver ()
#include "translator.icc"
-ADD_ACKNOWLEDGER (Staff_collecting_engraver, staff_symbol);
-ADD_END_ACKNOWLEDGER (Staff_collecting_engraver, staff_symbol);
+
+void
+Staff_collecting_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Staff_collecting_engraver, staff_symbol);
+ ADD_END_ACKNOWLEDGER (Staff_collecting_engraver, staff_symbol);
+}
ADD_TRANSLATOR (Staff_collecting_engraver,
/* doc */
int Staff_performer::channel_count_ = 0;
int Staff_performer::staff_performer_count_ = 0;
+void
+Staff_performer::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Staff_performer,
/* doc */
"",
void stop_translation_timestep ();
virtual ~Staff_symbol_engraver ();
- DECLARE_ACKNOWLEDGER (grob);
- DECLARE_TRANSLATOR_LISTENER (staff_span);
+ void acknowledge_grob (Grob_info);
+ void listen_staff_span (Stream_event *);
virtual void finalize ();
void process_music ();
virtual void derived_mark () const;
span_events_.set (0, 0);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Staff_symbol_engraver, staff_span);
void
Staff_symbol_engraver::listen_staff_span (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Staff_symbol_engraver, grob);
+
+void
+Staff_symbol_engraver::boot ()
+{
+ ADD_LISTENER (Staff_symbol_engraver, staff_span);
+ ADD_ACKNOWLEDGER (Staff_symbol_engraver, grob);
+}
ADD_TRANSLATOR (Staff_symbol_engraver,
/* doc */
vector<Grob *> lyrics_;
vector<Grob *> stanza_numbers_;
- DECLARE_ACKNOWLEDGER (lyric_syllable);
- DECLARE_ACKNOWLEDGER (stanza_number);
+ void acknowledge_lyric_syllable (Grob_info);
+ void acknowledge_stanza_number (Grob_info);
void stop_translation_timestep ();
};
lyrics_.clear ();
}
-ADD_ACKNOWLEDGER (Stanza_number_align_engraver, lyric_syllable);
-ADD_ACKNOWLEDGER (Stanza_number_align_engraver, stanza_number);
+
+void
+Stanza_number_align_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Stanza_number_align_engraver, lyric_syllable);
+ ADD_ACKNOWLEDGER (Stanza_number_align_engraver, stanza_number);
+}
ADD_TRANSLATOR (Stanza_number_align_engraver,
/* doc */
void process_music ();
virtual void derived_mark () const;
void stop_translation_timestep ();
- DECLARE_ACKNOWLEDGER (lyric_syllable);
+ void acknowledge_lyric_syllable (Grob_info);
};
void
#include "translator.icc"
-ADD_ACKNOWLEDGER (Stanza_number_engraver, lyric_syllable);
+void
+Stanza_number_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Stanza_number_engraver, lyric_syllable);
+}
+
ADD_TRANSLATOR (Stanza_number_engraver,
/* doc */
"Engrave stanza numbers.",
protected:
void make_stem (Grob_info, bool);
- DECLARE_TRANSLATOR_LISTENER (tremolo);
- DECLARE_TRANSLATOR_LISTENER (tuplet_span);
- DECLARE_ACKNOWLEDGER (rhythmic_head);
+ void listen_tremolo (Stream_event *);
+ void listen_tuplet_span (Stream_event *);
+ void acknowledge_rhythmic_head (Grob_info);
void stop_translation_timestep ();
void finalize ();
void kill_unused_flags ();
tremolo_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Stem_engraver, tuplet_span);
void
Stem_engraver::listen_tuplet_span (Stream_event *ev)
{
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Stem_engraver, tremolo);
void
Stem_engraver::listen_tremolo (Stream_event *ev)
{
ASSIGN_EVENT_ONCE (tremolo_ev_, ev);
}
-ADD_ACKNOWLEDGER (Stem_engraver, rhythmic_head);
+
+void
+Stem_engraver::boot ()
+{
+ ADD_LISTENER (Stem_engraver, tuplet_span);
+ ADD_LISTENER (Stem_engraver, tremolo);
+ ADD_ACKNOWLEDGER (Stem_engraver, rhythmic_head);
+}
ADD_TRANSLATOR (Stem_engraver,
/* doc */
return expr_;
}
-const char Stencil::type_p_name_[] = "ly:stencil?";
+const char * const Stencil::type_p_name_ = "ly:stencil?";
Interval
Stencil::extent (Axis a) const
protected:
Bracket_nesting_group *nesting_;
- DECLARE_ACKNOWLEDGER (system_start_delimiter);
- DECLARE_ACKNOWLEDGER (staff_symbol);
+ void acknowledge_system_start_delimiter (Grob_info);
+ void acknowledge_staff_symbol (Grob_info);
void process_music ();
virtual void finalize ();
nesting_->add_support (inf.grob ());
}
-ADD_ACKNOWLEDGER (System_start_delimiter_engraver, staff_symbol);
-ADD_ACKNOWLEDGER (System_start_delimiter_engraver, system_start_delimiter);
+
+void
+System_start_delimiter_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (System_start_delimiter_engraver, staff_symbol);
+ ADD_ACKNOWLEDGER (System_start_delimiter_engraver, system_start_delimiter);
+}
ADD_TRANSLATOR (System_start_delimiter_engraver,
/* doc */
TRANSLATOR_DECLARATIONS (Tab_note_heads_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (note);
- DECLARE_TRANSLATOR_LISTENER (string_number);
- DECLARE_TRANSLATOR_LISTENER (fingering);
+ void listen_note (Stream_event *);
+ void listen_string_number (Stream_event *);
+ void listen_fingering (Stream_event *);
void process_music ();
void stop_translation_timestep ();
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, note);
void
Tab_note_heads_engraver::listen_note (Stream_event *ev)
{
note_events_.push_back (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, string_number);
void
Tab_note_heads_engraver::listen_string_number (Stream_event *ev)
{
tabstring_events_.push_back (ev);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, fingering);
void
Tab_note_heads_engraver::listen_fingering (Stream_event *ev)
{
fingering_events_.clear ();
}
+void
+Tab_note_heads_engraver::boot ()
+{
+ ADD_LISTENER (Tab_note_heads_engraver, note);
+ ADD_LISTENER (Tab_note_heads_engraver, string_number);
+ ADD_LISTENER (Tab_note_heads_engraver, fingering);
+}
+
ADD_TRANSLATOR (Tab_note_heads_engraver,
/* doc */
"Generate one or more tablature note heads from event of type"
public:
TRANSLATOR_DECLARATIONS (Tab_staff_symbol_engraver);
protected:
- DECLARE_ACKNOWLEDGER (staff_symbol);
+ void acknowledge_staff_symbol (Grob_info);
};
void
#include "translator.icc"
-ADD_ACKNOWLEDGER (Tab_staff_symbol_engraver, staff_symbol);
+void
+Tab_staff_symbol_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Tab_staff_symbol_engraver, staff_symbol);
+}
+
ADD_TRANSLATOR (Tab_staff_symbol_engraver,
/* doc */
"Create a tablature staff symbol, but look at"
TRANSLATOR_DECLARATIONS (Tab_tie_follow_engraver);
protected:
- DECLARE_ACKNOWLEDGER (glissando);
- DECLARE_ACKNOWLEDGER (slur);
- DECLARE_ACKNOWLEDGER (tab_note_head);
+ void acknowledge_glissando (Grob_info);
+ void acknowledge_slur (Grob_info);
+ void acknowledge_tab_note_head (Grob_info);
void stop_translation_timestep ();
};
note_heads_.clear ();
}
-ADD_ACKNOWLEDGER (Tab_tie_follow_engraver, slur);
-ADD_ACKNOWLEDGER (Tab_tie_follow_engraver, glissando);
-ADD_ACKNOWLEDGER (Tab_tie_follow_engraver, tab_note_head);
+
+void
+Tab_tie_follow_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Tab_tie_follow_engraver, slur);
+ ADD_ACKNOWLEDGER (Tab_tie_follow_engraver, glissando);
+ ADD_ACKNOWLEDGER (Tab_tie_follow_engraver, tab_note_head);
+}
ADD_TRANSLATOR (Tab_tie_follow_engraver,
/* doc */
}
}
+void
+Tempo_performer::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Tempo_performer,
/* doc */
"",
void stop_translation_timestep ();
void process_music ();
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (text_script);
+ void acknowledge_note_column (Grob_info);
+ void listen_text_script (Stream_event *);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Text_engraver, text_script);
void
Text_engraver::listen_text_script (Stream_event *ev)
{
{
}
-ADD_ACKNOWLEDGER (Text_engraver, note_column);
+
+void
+Text_engraver::boot ()
+{
+ ADD_LISTENER (Text_engraver, text_script);
+ ADD_ACKNOWLEDGER (Text_engraver, note_column);
+}
ADD_TRANSLATOR (Text_engraver,
/* doc */
TRANSLATOR_DECLARATIONS (Text_spanner_engraver);
protected:
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (text_span);
- DECLARE_ACKNOWLEDGER (note_column);
+ void listen_text_span (Stream_event *);
+ void acknowledge_note_column (Grob_info);
void stop_translation_timestep ();
void process_music ();
event_drul_.set (0, 0);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Text_spanner_engraver, text_span);
void
Text_spanner_engraver::listen_text_span (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Text_spanner_engraver, note_column);
+
+void
+Text_spanner_engraver::boot ()
+{
+ ADD_LISTENER (Text_spanner_engraver, text_span);
+ ADD_ACKNOWLEDGER (Text_spanner_engraver, note_column);
+}
ADD_TRANSLATOR (Text_spanner_engraver,
/* doc */
void process_acknowledged ();
void stop_translation_timestep ();
void start_translation_timestep ();
- DECLARE_ACKNOWLEDGER (note_head);
- DECLARE_TRANSLATOR_LISTENER (tie);
+ void acknowledge_note_head (Grob_info);
+ void listen_tie (Stream_event *);
void process_music ();
void typeset_tie (Spanner *);
void report_unterminated_tie (Head_event_tuple const &);
event_processed_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tie_engraver, tie);
void
Tie_engraver::listen_tie (Stream_event *ev)
{
her->set_bound (RIGHT, right_head);
}
-ADD_ACKNOWLEDGER (Tie_engraver, note_head);
+void
+Tie_engraver::boot ()
+{
+ ADD_LISTENER (Tie_engraver, tie);
+ ADD_ACKNOWLEDGER (Tie_engraver, note_head);
+}
+
ADD_TRANSLATOR (Tie_engraver,
/* doc */
"Generate ties between note heads of equal pitch.",
void start_translation_timestep ();
virtual void acknowledge_audio_element (Audio_element_info);
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (tie);
+ void listen_tie (Stream_event *);
public:
TRANSLATOR_DECLARATIONS (Tie_performer);
};
event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tie_performer, tie);
void
Tie_performer::listen_tie (Stream_event *ev)
{
now_tied_heads_.clear ();
}
+void
+Tie_performer::boot ()
+{
+ ADD_LISTENER (Tie_performer, tie);
+}
+
ADD_TRANSLATOR (Tie_performer,
/* doc */
"Generate ties between note heads of equal pitch.",
void process_music ();
public:
TRANSLATOR_DECLARATIONS (Time_signature_engraver);
- DECLARE_TRANSLATOR_LISTENER (time_signature);
+ void listen_time_signature (Stream_event *);
};
void
last_time_fraction_ = SCM_BOOL_F;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Time_signature_engraver, time_signature);
void
Time_signature_engraver::listen_time_signature (Stream_event *ev)
{
time_cause_ = SCM_EOL;
}
+void
+Time_signature_engraver::boot ()
+{
+ ADD_LISTENER (Time_signature_engraver, time_signature);
+}
+
ADD_TRANSLATOR (Time_signature_engraver,
/* doc */
"Create a @ref{TimeSignature} whenever"
#include "translator.icc"
+void
+Time_signature_performer::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Time_signature_performer,
/* doc */
"",
#include "translator.icc"
+void
+Timing_translator::boot ()
+{
+
+}
+
ADD_TRANSLATOR (Timing_translator,
/* doc */
"This engraver adds the alias @code{Timing} to its containing"
#include "engraver.hh"
-const char * const Engraver_dispatch_list::type_p_name_ = 0;
-
void
Engraver_dispatch_list::apply (Grob_info gi)
{
- Translator *origin = gi.origin_translator ();
+ SCM origin = gi.origin_translator ()->self_scm ();
+ SCM grob = gi.grob ()->self_scm ();
for (vsize i = 0; i < dispatch_entries_.size (); i++)
{
- Engraver_dispatch_entry const &e (dispatch_entries_[i]);
- if (e.engraver_ == origin)
+ Method_instance const &e (dispatch_entries_[i]);
+ if (scm_is_eq (e.instance (), origin))
continue;
- (e.engraver_->*e.function_) (gi);
+ e (grob, origin);
}
}
SCM retval = Engraver_dispatch_list ().smobbed_copy ();
Engraver_dispatch_list *list = unsmob<Engraver_dispatch_list> (retval);
- Engraver_dispatch_entry entry;
- bool found = false;
for (SCM s = trans_list; scm_is_pair (s); s = scm_cdr (s))
{
- Engraver *eng
- = unsmob<Engraver> (scm_car (s));
+ Engraver *eng = unsmob<Engraver> (scm_car (s));
if (!eng)
continue;
- entry.engraver_ = eng;
for (SCM i = iface_list; scm_is_pair (i); i = scm_cdr (i))
{
- Translator::Grob_info_callback ptr
- = (start_end == START)
- ? eng->get_acknowledger (scm_car (i))
- : eng->get_end_acknowledger (scm_car (i));
+ SCM ptr = eng->get_acknowledger (scm_car (i), start_end);
- if (ptr)
- {
- entry.function_ = ptr;
- list->dispatch_entries_.push_back (entry);
- found = true;
- }
+ if (!SCM_UNBNDP (ptr))
+ list->dispatch_entries_.push_back (Method_instance (ptr, eng));
}
}
- return found ? retval : SCM_EOL;
+ return list->dispatch_entries_.empty () ? SCM_EOL : retval;
}
#include "warn.hh"
void
-translator_each (SCM list, Translator_method method)
+translator_each (SCM list, SCM method)
{
for (SCM p = list; scm_is_pair (p); p = scm_cdr (p))
- (unsmob<Translator> (scm_car (p))->*method) ();
+ scm_call_1 (method, scm_car (p));
}
void
g->connect_to_context (new_context);
g->unprotect ();
- recurse_over_translators (new_context,
- &Translator::initialize,
- &Translator_group::initialize,
- DOWN);
+ recurse_over_translators
+ (new_context,
+ Callback0_wrapper::make_smob<Translator, &Translator::initialize> (),
+ Callback0_wrapper::make_smob<Translator_group, &Translator_group::initialize> (),
+ DOWN);
}
SCM
if (tg && dir == DOWN)
{
tg->precomputed_translator_foreach (idx);
- tg->call_precomputed_self_method (idx);
}
for (SCM s = c->children_contexts (); scm_is_pair (s);
if (tg && dir == UP)
{
tg->precomputed_translator_foreach (idx);
- tg->call_precomputed_self_method (idx);
}
}
void
-recurse_over_translators (Context *c, Translator_method ptr,
- Translator_group_method tg_ptr, Direction dir)
+recurse_over_translators (Context *c, SCM ptr,
+ SCM tg_ptr, Direction dir)
{
- Translator_group *tg
- = dynamic_cast<Translator_group *> (c->implementation ());
+ Translator_group *tg = c->implementation ();
+ SCM tg_scm = tg ? tg->self_scm () : SCM_UNDEFINED;
if (tg && dir == DOWN)
{
- (tg->*tg_ptr) ();
+ scm_call_1 (tg_ptr, tg_scm);
translator_each (tg->get_simple_trans_list (), ptr);
}
translator_each (tg->get_simple_trans_list (),
ptr);
- (tg->*tg_ptr) ();
+ scm_call_1 (tg_ptr, tg_scm);
}
}
for (SCM s = simple_trans_list_; scm_is_pair (s); s = scm_cdr (s))
{
Translator *tr = unsmob<Translator> (scm_car (s));
- Translator::Callback ptrs[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
+ SCM ptrs[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
tr->fetch_precomputable_methods (ptrs);
assert (tr);
for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
{
- if (ptrs[i])
- precomputed_method_bindings_[i].push_back (Translator_method_binding (tr, ptrs[i]));
+ if (!SCM_UNBNDP (ptrs[i]))
+ precomputed_method_bindings_[i].push_back (Method_instance (ptrs[i], tr));
}
}
- fetch_precomputable_methods (precomputed_self_method_bindings_);
}
void
Translator_group::precomputed_translator_foreach (Translator_precompute_index idx)
{
- vector<Translator_method_binding> &bindings (precomputed_method_bindings_[idx]);
+ vector<Method_instance> &bindings (precomputed_method_bindings_[idx]);
for (vsize i = 0; i < bindings.size (); i++)
- bindings[i].invoke ();
-}
-
-void
-Translator_group::fetch_precomputable_methods (Translator_group_void_method ptrs[])
-{
- for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
- ptrs[i] = 0;
-}
-
-void
-Translator_group::call_precomputed_self_method (Translator_precompute_index idx)
-{
- if (precomputed_self_method_bindings_[idx])
- (*precomputed_self_method_bindings_[idx]) (this);
+ bindings[i]();
}
Translator_group::~Translator_group ()
}
-const char Translator_group::type_p_name_[] = "ly:translator-group?";
+const char * const Translator_group::type_p_name_ = "ly:translator-group?";
int
Translator_group::print_smob (SCM port, scm_print_state *) const
return daddy_context_->get_score_context ();
}
-const char Translator::type_p_name_[] = "ly:translator?";
+const char * const Translator::type_p_name_ = "ly:translator?";
bool
Translator::must_be_last () const
}
void
-add_acknowledger (Translator::Grob_info_callback ptr,
+add_acknowledger (SCM ptr,
char const *func_name,
- vector<Acknowledge_information> *ack_array)
+ SCM &ack_hash)
{
- Acknowledge_information inf;
- inf.function_ = ptr;
+ if (SCM_UNBNDP (ack_hash))
+ ack_hash = Scheme_hash_table::make_smob ();
string interface_name (func_name);
interface_name = replace_all (&interface_name, '_', '-');
interface_name += "-interface";
- /*
- this is only called during program init, so safe to use scm_gc_protect_object ()
- */
- inf.symbol_ = scm_gc_protect_object (ly_symbol2scm (interface_name.c_str ()));
- ack_array->push_back (inf);
+ unsmob<Scheme_hash_table> (ack_hash)
+ ->set (ly_symbol2scm (interface_name.c_str ()), ptr);
}
-Translator::Grob_info_callback
-generic_get_acknowledger (SCM sym, vector<Acknowledge_information> const *ack_array)
+SCM
+generic_get_acknowledger (SCM sym, SCM ack_hash)
{
- for (vsize i = 0; i < ack_array->size (); i++)
- {
- if (ack_array->at (i).symbol_ == sym)
- return ack_array->at (i).function_;
- }
- return 0;
+ if (SCM_UNBNDP (ack_hash))
+ return SCM_UNDEFINED;
+
+ return unsmob<Scheme_hash_table> (ack_hash)->get (sym);
}
Moment
}
}
-ADD_TRANSLATOR (Translator,
- /* doc */
- "Base class. Not instantiated.",
-
- /* create */
- "",
-
- /* read */
- "",
-
- /* write */
- ""
- );
+// Base class. Not instantiated. No ADD_TRANSLATOR call.
TRANSLATOR_DECLARATIONS (Trill_spanner_engraver);
protected:
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (trill_span);
- DECLARE_ACKNOWLEDGER (note_column);
+ void listen_trill_span (Stream_event *);
+ void acknowledge_note_column (Grob_info);
void stop_translation_timestep ();
void process_music ();
event_drul_.set (0, 0);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Trill_spanner_engraver, trill_span);
void
Trill_spanner_engraver::listen_trill_span (Stream_event *ev)
{
}
}
-ADD_ACKNOWLEDGER (Trill_spanner_engraver, note_column);
+
+void
+Trill_spanner_engraver::boot ()
+{
+ ADD_LISTENER (Trill_spanner_engraver, trill_span);
+ ADD_ACKNOWLEDGER (Trill_spanner_engraver, note_column);
+}
ADD_TRANSLATOR (Trill_spanner_engraver,
/* doc */
vector<Tuplet_description> stopped_tuplets_;
vector<Spanner *> last_tuplets_;
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (script);
- DECLARE_ACKNOWLEDGER (finger);
- DECLARE_ACKNOWLEDGER (string_number);
- DECLARE_TRANSLATOR_LISTENER (tuplet_span);
+ void acknowledge_note_column (Grob_info);
+ void acknowledge_script (Grob_info);
+ void acknowledge_finger (Grob_info);
+ void acknowledge_string_number (Grob_info);
+ void listen_tuplet_span (Stream_event *);
virtual void finalize ();
void start_translation_timestep ();
void process_music ();
};
-IMPLEMENT_TRANSLATOR_LISTENER (Tuplet_engraver, tuplet_span);
void
Tuplet_engraver::listen_tuplet_span (Stream_event *ev)
{
{
}
-ADD_ACKNOWLEDGER (Tuplet_engraver, note_column);
-ADD_ACKNOWLEDGER (Tuplet_engraver, script);
-ADD_ACKNOWLEDGER (Tuplet_engraver, finger);
-ADD_ACKNOWLEDGER (Tuplet_engraver, string_number);
+void
+Tuplet_engraver::boot ()
+{
+ ADD_LISTENER (Tuplet_engraver, tuplet_span);
+ ADD_ACKNOWLEDGER (Tuplet_engraver, note_column);
+ ADD_ACKNOWLEDGER (Tuplet_engraver, script);
+ ADD_ACKNOWLEDGER (Tuplet_engraver, finger);
+ ADD_ACKNOWLEDGER (Tuplet_engraver, string_number);
+}
+
ADD_TRANSLATOR (Tuplet_engraver,
/* doc */
"Catch tuplet events and generate appropriate bracket.",
TRANSLATOR_DECLARATIONS (Tweak_engraver);
protected:
- DECLARE_ACKNOWLEDGER (grob);
+ void acknowledge_grob (Grob_info);
};
Tweak_engraver::Tweak_engraver ()
}
}
-ADD_ACKNOWLEDGER (Tweak_engraver, grob);
+void
+Tweak_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Tweak_engraver, grob);
+}
+
ADD_TRANSLATOR (Tweak_engraver,
/* doc */
"Read the @code{tweaks} property from the originating event,"
public:
int print_smob (SCM, scm_print_state *) const;
SCM mark_smob () const;
- static const char type_p_name_[];
+ static const char * const type_p_name_;
private:
SCM object_;
public:
return 1;
}
-const char Undead::type_p_name_[] = "ly:undead?";
+const char * const Undead::type_p_name_ = "ly:undead?";
LY_DEFINE (ly_make_undead, "ly:make-undead",
1, 0, 0, (SCM object),
class Unpure_pure_call : public Smob1<Unpure_pure_call>
{
public:
- static const char * const type_p_name_; // = 0
// Smob procedures unfortunately can only take at most 3 SCM
// arguments. Otherwise we could use a "3, 0, 1" call signature and
// not require an argument count check of our own.
}
};
-const char * const Unpure_pure_call::type_p_name_ = 0;
-
SCM
Unpure_pure_container::pure_part () const
{
: scm2 ();
}
-const char Unpure_pure_container::type_p_name_[] = "ly:unpure-pure-container?";
+const char * const Unpure_pure_container::type_p_name_ = "ly:unpure-pure-container?";
LY_DEFINE (ly_make_unpure_pure_container, "ly:make-unpure-pure-container",
1, 1, 0, (SCM unpure, SCM pure),
public:
TRANSLATOR_DECLARATIONS (Vaticana_ligature_engraver);
-
+ TRANSLATOR_INHERIT (Gregorian_ligature_engraver);
protected:
virtual Spanner *create_ligature_spanner ();
virtual void transform_heads (Spanner *ligature,
vector<Grob_info> const &primitives);
- DECLARE_TRANSLATOR_LISTENER (pes_or_flexa);
- DECLARE_TRANSLATOR_LISTENER (ligature);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Vaticana_ligature_engraver, pes_or_flexa);
-void
-Vaticana_ligature_engraver::listen_pes_or_flexa (Stream_event *ev)
-{
- Gregorian_ligature_engraver::listen_pes_or_flexa (ev);
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Vaticana_ligature_engraver, ligature);
-void
-Vaticana_ligature_engraver::listen_ligature (Stream_event *ev)
-{
- Ligature_engraver::listen_ligature (ev);
-}
-
Vaticana_ligature_engraver::Vaticana_ligature_engraver ()
{
brew_ligature_primitive_proc
#endif
}
-ADD_ACKNOWLEDGER (Vaticana_ligature_engraver, rest);
-ADD_ACKNOWLEDGER (Vaticana_ligature_engraver, ligature_head);
+void
+Vaticana_ligature_engraver::boot ()
+{
+ ADD_LISTENER (Gregorian_ligature_engraver, pes_or_flexa);
+ ADD_LISTENER (Ligature_engraver, ligature);
+ ADD_ACKNOWLEDGER (Ligature_engraver, rest);
+ ADD_ACKNOWLEDGER (Ligature_engraver, ligature_head);
+}
+
ADD_TRANSLATOR (Vaticana_ligature_engraver,
/* doc */
"Handle ligatures by glueing special ligature heads"
public:
TRANSLATOR_DECLARATIONS (Vertical_align_engraver);
- DECLARE_ACKNOWLEDGER (axis_group);
+ void acknowledge_axis_group (Grob_info);
protected:
virtual void derived_mark () const;
bool top_level_;
};
-ADD_ACKNOWLEDGER (Vertical_align_engraver, axis_group);
+void
+Vertical_align_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Vertical_align_engraver, axis_group);
+}
+
ADD_TRANSLATOR (Vertical_align_engraver,
/* doc */
"Catch groups (staves, lyrics lines, etc.) and stack them"
TRANSLATOR_DECLARATIONS (Volta_engraver);
protected:
- DECLARE_ACKNOWLEDGER (bar_line);
+ void acknowledge_bar_line (Grob_info);
virtual void derived_mark () const;
void stop_translation_timestep ();
/*
TODO: should attach volta to paper-column if no bar is found.
*/
-ADD_ACKNOWLEDGER (Volta_engraver, bar_line);
+void
+Volta_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Volta_engraver, bar_line);
+}
+
ADD_TRANSLATOR (Volta_engraver,
/* doc */
"Make volta brackets.",
%}
-\version "2.19.41" % necessary for upgrading to future LilyPond versions.
+\version "2.19.43" % necessary for upgrading to future LilyPond versions.
\header{
title = "A scale in LilyPond"
%}
-\version "2.19.41" % necessary for upgrading to future LilyPond versions.
+\version "2.19.43" % necessary for upgrading to future LilyPond versions.
\header{
title = "A scale in LilyPond"
% portato ac:portatoFactor (default 3/4)
% tenuto ac:tenutoFactor (default 1/1 - by default, notes marked
% tenuto are not shortened)
-% * Appogiaturas are made to take half the value of the note following,
+% * Appoggiaturas are made to take half the value of the note following,
% without taking dots into account (so in \appoggiatura c8 d2. the c
% will take the time of a crotchet).
% * Trills and turns are expanded. The algorithm tries to choose notes
</rejectfont>
</selectfont>
+ <!--
+ LilyPond cannot handle OpenType/CFF Collection (OTC) fonts
+ (NotoSansCJK.ttc and SourceHanSans.ttc etc.).
+ This settings is a workaround that ignores some major OTC fonts
+ for avoiding errors.
+ TODO: Add OTC fonts support and remove this settings
+ -->
+
+ <selectfont>
+ <rejectfont>
+ <!--
+ Noto Sans CJK
+ https://www.google.com/get/noto/help/cjk/
+
+ `CJK OTF fonts with different default language' and
+ `Region specific OTF subsets' can be used.
+ Their file names are `NotoSans*.otf'.
+ -->
+ <glob>*/NotoSansCJK*.ttc</glob>
+
+ <!--
+ Source Han Sans
+ https://github.com/adobe-fonts/source-han-sans
+
+ `Language-specific OTFs' and
+ `Region-specific Subset OTFs' can be used.
+ Their file names are `SourceHanSans*.otf'.
+ -->
+ <glob>*/SourceHanSans*.ttc</glob>
+
+ <!--
+ Source Han Code JP
+ https://github.com/adobe-fonts/source-han-code-jp
+
+ `OTF' can be used.
+ Their file names are `SourceHanCodeJP-*.otf'.
+ -->
+ <glob>*/SourceHanCodeJP.ttc</glob>
+ </rejectfont>
+ </selectfont>
+
</fontconfig>
%%%%%%%%
%
-% Single Stroke for Short Appogiatura
+% Single Stroke for Short Appoggiatura
%
fet_beginchar ("grace dash (up)", "ugrace");
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: lilypond 2.19.41\n"
+"Project-Id-Version: lilypond 2.19.43\n"
"Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu."
"lilypond.bugs\n"
-"POT-Creation-Date: 2016-05-01 12:41+0100\n"
+"POT-Creation-Date: 2016-06-08 13:09+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "Unable to find instrument for ID=%s\n"
msgstr ""
-#: abc2ly.py:1389 convert-ly.py:85 lilypond-book.py:122 midi2ly.py:1044
+#: abc2ly.py:1389 convert-ly.py:85 lilypond-book.py:122 midi2ly.py:1046
#, python-format
msgid "%s [OPTION]... FILE"
msgstr ""
msgstr ""
#: abc2ly.py:1398 convert-ly.py:92 etf2ly.py:1208 lilypond-book.py:231
-#: midi2ly.py:1095 musicxml2ly.py:2590 main.cc:184
+#: midi2ly.py:1097 musicxml2ly.py:2590 main.cc:184
msgid "show version number and exit"
msgstr ""
#: abc2ly.py:1401 convert-ly.py:96 etf2ly.py:1204 lilypond-book.py:140
-#: midi2ly.py:1062 musicxml2ly.py:2572 main.cc:163
+#: midi2ly.py:1064 musicxml2ly.py:2572 main.cc:163
msgid "show this help and exit"
msgstr ""
-#: abc2ly.py:1404 etf2ly.py:1209 midi2ly.py:1071
+#: abc2ly.py:1404 etf2ly.py:1209 midi2ly.py:1073
msgid "write output to FILE"
msgstr ""
#. or if there is a LilyPond users list or forum in your language
#. "Report bugs in English via %s or in YOUR_LANG via URI"
#: abc2ly.py:1416 convert-ly.py:157 etf2ly.py:1218 lilypond-book.py:258
-#: midi2ly.py:1107 musicxml2ly.py:2674 main.cc:318
+#: midi2ly.py:1109 musicxml2ly.py:2674 main.cc:318
#, c-format, python-format
msgid "Report bugs via %s"
msgstr ""
msgid "Examples:"
msgstr ""
-#: convert-ly.py:79 etf2ly.py:1191 lilypond-book.py:115 midi2ly.py:81
+#: convert-ly.py:79 etf2ly.py:1191 lilypond-book.py:115 midi2ly.py:80
#, python-format
msgid "Copyright (c) %s by"
msgstr ""
-#: convert-ly.py:81 etf2ly.py:1193 lilypond-book.py:117 midi2ly.py:83
+#: convert-ly.py:81 etf2ly.py:1193 lilypond-book.py:117 midi2ly.py:82
msgid "Distributed under terms of the GNU General Public License."
msgstr ""
-#: convert-ly.py:82 etf2ly.py:1194 lilypond-book.py:118 midi2ly.py:84
+#: convert-ly.py:82 etf2ly.py:1194 lilypond-book.py:118 midi2ly.py:83
msgid "It comes with NO WARRANTY."
msgstr ""
msgid "make a numbered backup [default: filename.ext~]"
msgstr ""
-#: convert-ly.py:152 etf2ly.py:1212 lilypond-book.py:234 midi2ly.py:1096
+#: convert-ly.py:152 etf2ly.py:1212 lilypond-book.py:234 midi2ly.py:1098
#: main.cc:186
msgid "show warranty and copyright"
msgstr ""
"file.\n"
msgstr ""
-#: etf2ly.py:1210 midi2ly.py:1067 midi2ly.py:1072 musicxml2ly.py:2659
+#: etf2ly.py:1210 midi2ly.py:1069 midi2ly.py:1074 musicxml2ly.py:2659
#: main.cc:169 main.cc:181
msgid "FILE"
msgstr ""
msgid "write snippet output files with the same base name as their source file"
msgstr ""
-#: lilypond-book.py:223 midi2ly.py:1090 musicxml2ly.py:2596
+#: lilypond-book.py:223 midi2ly.py:1092 musicxml2ly.py:2596
msgid "be verbose"
msgstr ""
"Setting LilyPond's output to --verbose, implied by lilypond-book's setting"
msgstr ""
-#: midi2ly.py:90
+#: midi2ly.py:89
msgid "warning: "
msgstr ""
-#: midi2ly.py:93 midi2ly.py:1124
+#: midi2ly.py:92 midi2ly.py:1126
msgid "error: "
msgstr ""
-#: midi2ly.py:94
+#: midi2ly.py:93
msgid "Exiting... "
msgstr ""
-#: midi2ly.py:835
+#: midi2ly.py:834
msgid "found more than 5 voices on a staff, expect bad output"
msgstr ""
-#: midi2ly.py:1032
+#: midi2ly.py:1034
#, python-format
msgid "%s output to `%s'..."
msgstr ""
-#: midi2ly.py:1045
+#: midi2ly.py:1047
#, python-format
msgid "Convert %s to LilyPond input.\n"
msgstr ""
-#: midi2ly.py:1050
+#: midi2ly.py:1052
msgid "print absolute pitches"
msgstr ""
-#: midi2ly.py:1052 midi2ly.py:1080
+#: midi2ly.py:1054 midi2ly.py:1082
msgid "DUR"
msgstr ""
-#: midi2ly.py:1053
+#: midi2ly.py:1055
msgid "quantise note durations on DUR"
msgstr ""
-#: midi2ly.py:1056
+#: midi2ly.py:1058
msgid "debug printing"
msgstr ""
-#: midi2ly.py:1059
+#: midi2ly.py:1061
msgid "print explicit durations"
msgstr ""
-#: midi2ly.py:1064
+#: midi2ly.py:1066
msgid "prepend FILE to output"
msgstr ""
-#: midi2ly.py:1068
+#: midi2ly.py:1070
msgid "set key: ALT=+sharps|-flats; MINOR=1"
msgstr ""
-#: midi2ly.py:1069
+#: midi2ly.py:1071
msgid "ALT[:MINOR]"
msgstr ""
-#: midi2ly.py:1074
+#: midi2ly.py:1076
msgid "preview of first 4 bars"
msgstr ""
-#: midi2ly.py:1078
+#: midi2ly.py:1080
msgid "suppress progress messages and warnings about excess voices"
msgstr ""
-#: midi2ly.py:1079
+#: midi2ly.py:1081
msgid "quantise note starts on DUR"
msgstr ""
-#: midi2ly.py:1083
+#: midi2ly.py:1085
msgid "use s instead of r for rests"
msgstr ""
-#: midi2ly.py:1085
+#: midi2ly.py:1087
msgid "DUR*NUM/DEN"
msgstr ""
-#: midi2ly.py:1088
+#: midi2ly.py:1090
msgid "allow tuplet durations DUR*NUM/DEN"
msgstr ""
-#: midi2ly.py:1098
+#: midi2ly.py:1100
msgid "treat every text as a lyric"
msgstr ""
-#: midi2ly.py:1101
+#: midi2ly.py:1103
msgid "Examples"
msgstr ""
-#: midi2ly.py:1125
+#: midi2ly.py:1127
msgid "no files specified on command line."
msgstr ""
msgid "barcheck failed at: %s"
msgstr ""
-#: beam-engraver.cc:148
+#: beam-engraver.cc:147
msgid "already have a beam"
msgstr ""
-#: beam-engraver.cc:235
+#: beam-engraver.cc:234
msgid "unterminated beam"
msgstr ""
-#: beam-engraver.cc:282 chord-tremolo-engraver.cc:149
+#: beam-engraver.cc:281 chord-tremolo-engraver.cc:148
msgid "stem must have Rhythmic structure"
msgstr ""
-#: beam-engraver.cc:293
+#: beam-engraver.cc:292
msgid "stem does not fit in beam"
msgstr ""
-#: beam-engraver.cc:294
+#: beam-engraver.cc:293
msgid "beam was started here"
msgstr ""
msgid "none of these in my family"
msgstr ""
-#: chord-tremolo-engraver.cc:88
+#: chord-tremolo-engraver.cc:87
msgid "No tremolo to end"
msgstr ""
-#: chord-tremolo-engraver.cc:109
+#: chord-tremolo-engraver.cc:108
msgid "unterminated chord tremolo"
msgstr ""
msgid "need symbol argument for \\override and \\revert"
msgstr ""
-#: context.cc:143
+#: context.cc:147
#, c-format
msgid "cannot find or create new `%s'"
msgstr ""
-#: context.cc:222
+#: context.cc:226
#, c-format
msgid "cannot find or create `%s' called `%s'"
msgstr ""
-#: context.cc:453
+#: context.cc:457
#, c-format
msgid "cannot find or create: `%s'"
msgstr ""
-#: context.cc:467
+#: context.cc:471
#, c-format
msgid "cannot find or create new Bottom = \"%s\""
msgstr ""
msgid "dot `%s' not found"
msgstr ""
-#: dynamic-engraver.cc:169
+#: dynamic-engraver.cc:166
#, c-format
msgid ""
"unknown crescendo style: %s\n"
"defaulting to hairpin."
msgstr ""
-#: dynamic-engraver.cc:234 slur-proto-engraver.cc:159
+#: dynamic-engraver.cc:231 slur-proto-engraver.cc:159
#, c-format
msgid "unterminated %s"
msgstr ""
msgid "(De)crescendo with unspecified starting volume in MIDI."
msgstr ""
-#: episema-engraver.cc:75
+#: episema-engraver.cc:74
msgid "already have an episema"
msgstr ""
-#: episema-engraver.cc:88
+#: episema-engraver.cc:87
msgid "cannot find start of episema"
msgstr ""
-#: episema-engraver.cc:137
+#: episema-engraver.cc:136
msgid "unterminated episema"
msgstr ""
-#: extender-engraver.cc:169 extender-engraver.cc:178
+#: extender-engraver.cc:167 extender-engraver.cc:176
msgid "unterminated extender"
msgstr ""
msgid "Found infinity or nan in output. Substituting 0.0"
msgstr ""
-#: glissando-engraver.cc:158
+#: glissando-engraver.cc:157
msgid "unterminated glissando"
msgstr ""
msgid "decrescendo too small"
msgstr ""
-#: horizontal-bracket-engraver.cc:62
+#: horizontal-bracket-engraver.cc:61
msgid "do not have that many brackets"
msgstr ""
-#: horizontal-bracket-engraver.cc:71
+#: horizontal-bracket-engraver.cc:70
msgid "conflicting note group events"
msgstr ""
-#: hyphen-engraver.cc:104
+#: hyphen-engraver.cc:103
msgid "removing unterminated hyphen"
msgstr ""
-#: hyphen-engraver.cc:118
+#: hyphen-engraver.cc:117
msgid "unterminated hyphen; removing"
msgstr ""
msgid "position unknown"
msgstr ""
-#: key-engraver.cc:197
+#: key-engraver.cc:196
msgid "Incomplete keyAlterationOrder for key signature"
msgstr ""
msgid "alteration not found"
msgstr ""
-#: ligature-bracket-engraver.cc:72 ligature-engraver.cc:109
+#: ligature-bracket-engraver.cc:71 ligature-engraver.cc:109
msgid "cannot find start of ligature"
msgstr ""
-#: ligature-bracket-engraver.cc:85 ligature-engraver.cc:136
+#: ligature-bracket-engraver.cc:84 ligature-engraver.cc:136
msgid "already have a ligature"
msgstr ""
msgstr ""
#. FIXME: constant error message.
-#: mark-engraver.cc:150
+#: mark-engraver.cc:149
msgid "rehearsalMark must have integer value"
msgstr ""
-#: mark-engraver.cc:156
+#: mark-engraver.cc:155
msgid "mark label must be a markup object"
msgstr ""
-#: mensural-ligature-engraver.cc:100
+#: mensural-ligature-engraver.cc:93
msgid "ligature with less than 2 heads -> skipping"
msgstr ""
-#: mensural-ligature-engraver.cc:127
+#: mensural-ligature-engraver.cc:120
msgid "cannot determine pitch of ligature primitive -> skipping"
msgstr ""
-#: mensural-ligature-engraver.cc:141
+#: mensural-ligature-engraver.cc:134
msgid "single note ligature - skipping"
msgstr ""
-#: mensural-ligature-engraver.cc:152
+#: mensural-ligature-engraver.cc:145
msgid "prime interval within ligature -> skipping"
msgstr ""
-#: mensural-ligature-engraver.cc:163
+#: mensural-ligature-engraver.cc:156
msgid "mensural ligature: duration none of Mx, L, B, S -> skipping"
msgstr ""
-#: mensural-ligature-engraver.cc:206
+#: mensural-ligature-engraver.cc:199
msgid "semibrevis must be followed by another one -> skipping"
msgstr ""
-#: mensural-ligature-engraver.cc:216
+#: mensural-ligature-engraver.cc:209
msgid ""
"semibreves can only appear at the beginning of a ligature,\n"
"and there may be only zero or two of them"
msgstr ""
-#: mensural-ligature-engraver.cc:236
+#: mensural-ligature-engraver.cc:229
msgid ""
"invalid ligatura ending:\n"
"when the last note is a descending brevis,\n"
"or the ligatura must be LB or SSB"
msgstr ""
-#: mensural-ligature-engraver.cc:396
+#: mensural-ligature-engraver.cc:389
msgid "unexpected case fall-through"
msgstr ""
-#: midi-control-function-performer.cc:107 staff-performer.cc:153
+#: midi-control-function-performer.cc:107 staff-performer.cc:159
#, c-format
msgid "ignoring out-of-range value change for MIDI property `%s'"
msgstr ""
msgid "none of note heads `%s' or `%s' found"
msgstr ""
-#: note-heads-engraver.cc:76
+#: note-heads-engraver.cc:75
msgid "NoteEvent without pitch"
msgstr ""
msgid "program option -dpreview not supported by backend `%s'"
msgstr ""
-#: paper-column-engraver.cc:263
+#: paper-column-engraver.cc:261
msgid ""
"forced break was overridden by some other event, should you be using bar "
"checks?"
msgid "Conversion of string `%s' to UTF-16be failed: %s"
msgstr ""
-#: percent-repeat-engraver.cc:148
+#: percent-repeat-engraver.cc:147
msgid "unterminated percent repeat"
msgstr ""
msgid "MIDI output to `%s'..."
msgstr ""
-#: piano-pedal-engraver.cc:279
+#: pfb-scheme.cc:49 ttf.cc:512 ttf.cc:562
+msgid "font index must be non-negative, using index 0"
+msgstr ""
+
+#: pfb-scheme.cc:64 ttf.cc:480 ttf.cc:528
+#, c-format
+msgid "font index %d too large for font `%s', using index 0"
+msgstr ""
+
+#: piano-pedal-engraver.cc:276
#, c-format
msgid "expect 3 strings for piano pedals, found: %ld"
msgstr ""
-#: piano-pedal-engraver.cc:294 piano-pedal-engraver.cc:305
+#: piano-pedal-engraver.cc:291 piano-pedal-engraver.cc:302
#: piano-pedal-performer.cc:104
#, c-format
msgid "cannot find start of piano pedal: `%s'"
msgstr ""
-#: piano-pedal-engraver.cc:340
+#: piano-pedal-engraver.cc:337
#, c-format
msgid "cannot find start of piano pedal bracket: `%s'"
msgstr ""
msgid "rest `%s' not found"
msgstr ""
-#: score-engraver.cc:77
+#: score-engraver.cc:79
#, c-format
msgid "cannot find `%s'"
msgstr ""
-#: score-engraver.cc:79
+#: score-engraver.cc:81
msgid "Music font has not been installed properly."
msgstr ""
-#: score-engraver.cc:81
+#: score-engraver.cc:83
#, c-format
msgid "Search path `%s'"
msgstr ""
-#: score-engraver.cc:83
+#: score-engraver.cc:85
msgid "Aborting"
msgstr ""
msgstr ""
#. FIXME:
-#: script-engraver.cc:115
+#: script-engraver.cc:114
msgid "do not know how to interpret articulation:"
msgstr ""
-#: script-engraver.cc:116
+#: script-engraver.cc:115
msgid " scheme encoding: "
msgstr ""
msgid "expected to read %d characters, got %d"
msgstr ""
-#: staff-performer.cc:301
+#: staff-performer.cc:307
msgid "MIDI channel wrapped around"
msgstr ""
-#: staff-performer.cc:302
+#: staff-performer.cc:308
msgid "remapping modulo 16"
msgstr ""
msgid "Markup depth exceeds maximal value of %d; Markup: %s"
msgstr ""
-#: text-spanner-engraver.cc:72
+#: text-spanner-engraver.cc:71
msgid "cannot find start of text spanner"
msgstr ""
-#: text-spanner-engraver.cc:85
+#: text-spanner-engraver.cc:84
msgid "already have a text spanner"
msgstr ""
-#: text-spanner-engraver.cc:132
+#: text-spanner-engraver.cc:131
msgid "unterminated text spanner"
msgstr ""
-#: tie-engraver.cc:121
+#: tie-engraver.cc:120
msgid "unterminated tie"
msgstr ""
-#: tie-engraver.cc:377
+#: tie-engraver.cc:376
msgid "lonely tie"
msgstr ""
#.
#. OTOH, Tristan Keuris writes 8/20 in his Intermezzi.
#.
-#: time-signature-engraver.cc:95
+#: time-signature-engraver.cc:94
#, c-format
msgid "strange time signature found: %d/%d"
msgstr ""
msgid "cannot find: `%s'"
msgstr ""
-#: translator.cc:310
+#: translator.cc:305
#, c-format
msgid "Two simultaneous %s events, junking this one"
msgstr ""
-#: translator.cc:311
+#: translator.cc:306
#, c-format
msgid "Previous %s event here"
msgstr ""
-#: ttf.cc:480 ttf.cc:528
-#, c-format
-msgid "font index %d too large for font `%s', using index 0"
-msgstr ""
-
-#: ttf.cc:512 ttf.cc:562
-msgid "font index must be non-negative, using index 0"
-msgstr ""
-
-#: tuplet-engraver.cc:110
+#: tuplet-engraver.cc:109
msgid "No tuplet to end"
msgstr ""
-#: vaticana-ligature-engraver.cc:400
+#: vaticana-ligature-engraver.cc:384
#, c-format
msgid ""
"ignored prefix(es) `%s' of this head according to restrictions of the "
"selected ligature style"
msgstr ""
-#: vaticana-ligature-engraver.cc:466
+#: vaticana-ligature-engraver.cc:450
msgid ""
"Ambiguous use of dots in ligature: there are multiple dotted notes with the "
"same pitch. The ligature should be split."
msgstr ""
-#: vaticana-ligature-engraver.cc:524
+#: vaticana-ligature-engraver.cc:508
msgid ""
"This ligature has a dotted head followed by a non-dotted head. The ligature "
"should be split after the last dotted head before this head."
msgstr ""
-#: vaticana-ligature-engraver.cc:736
+#: vaticana-ligature-engraver.cc:720
#, c-format
msgid "Vaticana_ligature_engraver: setting `spacing-increment = %f': ptr =%ul"
msgstr ""
msgid "ascending vaticana style flexa"
msgstr ""
-#: vertical-align-engraver.cc:95
+#: vertical-align-engraver.cc:100
msgid "Ignoring Vertical_align_engraver in VerticalAxisGroup"
msgstr ""
msgid "cannot extract file matching ~a from ~a"
msgstr ""
-#: framework-ps.scm:347
+#: framework-ps.scm:353
#, scheme-format
msgid "do not know how to embed ~S=~S"
msgstr ""
-#: framework-ps.scm:372
+#: framework-ps.scm:378
#, scheme-format
msgid "do not know how to embed font ~s ~s ~s"
msgstr ""
-#: framework-ps.scm:754
+#: framework-ps.scm:760
msgid ""
"\n"
"The PostScript backend does not support the\n"
msgid "no \\version statement found, please add~afor future compatibility"
msgstr ""
-#: lily.scm:93
+#: lily.scm:94
msgid "call-after-session used after session start"
msgstr ""
-#: lily.scm:111
+#: lily.scm:112
msgid "define-session used after session start"
msgstr ""
-#: lily.scm:420
+#: lily.scm:122
+msgid "define-session-public used after session start"
+msgstr ""
+
+#: lily.scm:434
msgid "Using (ice-9 curried-definitions) module\n"
msgstr ""
-#: lily.scm:423
+#: lily.scm:437
msgid "Guile 1.8\n"
msgstr ""
-#: lily.scm:480
+#: lily.scm:494
#, scheme-format
msgid "cannot find: ~A"
msgstr ""
-#: lily.scm:910
+#: lily.scm:924
msgid "Success: compilation successfully completed"
msgstr ""
-#: lily.scm:911
+#: lily.scm:925
msgid "Compilation completed with warnings or errors"
msgstr ""
-#: lily.scm:972
+#: lily.scm:986
#, scheme-format
msgid "job ~a terminated with signal: ~a"
msgstr ""
-#: lily.scm:975
+#: lily.scm:989
#, scheme-format
msgid ""
"logfile ~a (exit ~a):\n"
"~a"
msgstr ""
-#: lily.scm:997 lily.scm:1086
+#: lily.scm:1011 lily.scm:1100
#, scheme-format
msgid "failed files: ~S"
msgstr ""
-#: lily.scm:1077
+#: lily.scm:1091
#, scheme-format
msgid "Redirecting output to ~a..."
msgstr ""
-#: lily.scm:1096
+#: lily.scm:1110
#, scheme-format
msgid "Invoking `~a'...\n"
msgstr ""
msgid "conflicting tag group ~a"
msgstr ""
-#: output-ps.scm:286 output-svg.scm:535
+#: output-ps.scm:290 output-svg.scm:539
#, scheme-format
msgid "unknown line-cap-style: ~S"
msgstr ""
-#: output-ps.scm:291 output-svg.scm:541
+#: output-ps.scm:295 output-svg.scm:545
#, scheme-format
msgid "unknown line-join-style: ~S"
msgstr ""
import sys
import string
import re
+import math
import lilylib as ly
+import warnings
+import utilities
_ = ly._
# Store previously converted pitch for \relative conversion as a global state variable
previous_pitch = None
relative_pitches = False
-
+whatOrnament = ""
+ly_dur = None # stores lilypond durations
def escape_instrument_string (input_string):
retstring = string.replace (input_string, "\"", "\\\"")
o.factor = self.factor
return o
-class Output_printer:
-
- """A class that takes care of formatting (eg.: indenting) a
+class Output_printer(object):
+ """
+ A class that takes care of formatting (eg.: indenting) a
Music expression as a .ly file.
-
"""
-
def __init__ (self):
self._line = ''
self._indent = 4
def set_file (self, file):
self._file = file
- def dump_version (self):
- self.newline ()
- self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
+ def dump_version (self, version):
+ self.print_verbatim ('\\version "' + version + '"')
self.newline ()
def get_indent (self):
def add_factor (self, factor):
self.override()
- self._output_state_stack[-1].factor *= factor
+ self._output_state_stack[-1].factor *= factor
def revert (self):
del self._output_state_stack[-1]
def unformatted_output (self, str):
# don't indent on \< and indent only once on <<
- self._nesting += ( str.count ('<')
+ self._nesting += (str.count ('<')
- str.count ('\<') - str.count ('<<')
- + str.count ('{') )
- self._nesting -= ( str.count ('>') - str.count ('\>') - str.count ('>>')
+ + str.count ('{'))
+ self._nesting -= (str.count ('>') - str.count ('\>') - str.count ('>>')
- str.count ('->') - str.count ('_>')
- str.count ('^>')
- + str.count ('}') )
+ + str.count ('}'))
self.print_verbatim (str)
def print_duration_string (self, str):
self.unformatted_output (str)
+# def print_note_color (self, object, rgb=None):
+# if rgb:
+# str = ("\\once\\override %s #'color = #(rgb-color %s # %s %s)" % (object, rgb[0], rgb[1], rgb[2]))
+# else:
+# str = "\\revert %s #'color" % object
+# self.newline()
+# self.add_word(str)
+# self.newline()
+
def add_word (self, str):
if (len (str) + 1 + len (self._line) > self._line_len):
self.newline()
self._skipspace = False
self.unformatted_output (str)
else:
- words = string.split (str)
+ # Avoid splitting quoted strings (e.g. "1. Wie") when indenting.
+ words = utilities.split_string_and_preserve_doublequoted_substrings(str)
for w in words:
self.add_word (w)
-
def close (self):
self.newline ()
self._file.close ()
class Duration:
- def __init__ (self):
+ def __init__(self):
self.duration_log = 0
self.dots = 0
- self.factor = Rational (1)
+ self.factor = Rational(1)
- def lisp_expression (self):
+ def lisp_expression(self):
return '(ly:make-duration %d %d %d %d)' % (self.duration_log,
self.dots,
- self.factor.numerator (),
- self.factor.denominator ())
+ self.factor.numerator(),
+ self.factor.denominator())
-
- def ly_expression (self, factor = None, scheme_mode = False):
+ def ly_expression(self, factor=None, scheme_mode=False):
+ global ly_dur # stores lilypond durations
if not factor:
factor = self.factor
longer_dict = {-1: "breve", -2: "longa"}
else:
longer_dict = {-1: "\\breve", -2: "\\longa"}
- str = longer_dict.get (self.duration_log, "1")
+ dur_str = longer_dict.get(self.duration_log, "1")
else:
- str = '%d' % (1 << self.duration_log)
- str += '.'*self.dots
+ dur_str = '%d' % (1 << self.duration_log)
+ dur_str += '.' * self.dots
- if factor <> Rational (1,1):
- if factor.denominator () <> 1:
- str += '*%d/%d' % (factor.numerator (), factor.denominator ())
+ if factor <> Rational(1, 1):
+ if factor.denominator() <> 1:
+ dur_str += '*%d/%d' % (factor.numerator(), factor.denominator())
else:
- str += '*%d' % factor.numerator ()
+ dur_str += '*%d' % factor.numerator()
- return str
+ if dur_str.isdigit():
+ ly_dur = int(dur_str)
+ # TODO: We need to deal with dotted notes and scaled durations
+ # otherwise ly_dur won't work in combination with tremolos.
+ return dur_str
- def print_ly (self, outputter):
- str = self.ly_expression (self.factor / outputter.duration_factor ())
- outputter.print_duration_string (str)
+ def print_ly(self, outputter):
+ dur_str = self.ly_expression(self.factor / outputter.duration_factor())
+ outputter.print_duration_string(dur_str)
def __repr__(self):
return self.ly_expression()
- def copy (self):
- d = Duration ()
+ def copy(self):
+ d = Duration()
d.dots = self.dots
d.duration_log = self.duration_log
d.factor = self.factor
return d
- def get_length (self):
- dot_fact = Rational( (1 << (1 + self.dots))-1,
+ def get_length(self):
+ dot_fact = Rational((1 << (1 + self.dots)) - 1,
1 << self.dots)
- log = abs (self.duration_log)
+ log = abs(self.duration_log)
dur = 1 << log
if self.duration_log < 0:
- base = Rational (dur)
+ base = Rational(dur)
else:
- base = Rational (1, dur)
+ base = Rational(1, dur)
return base * dot_fact * self.factor
-# implement the midi command line option '-m' and '--midi'
-# if TRUE add midi-block to .ly file (see below)
-def set_create_midi (option):
+def set_create_midi(option):
+ """
+ Implement the midi command line option '-m' and '--midi'.
+ If True, add midi-block to .ly file (see L{musicexp.Score.print_ly}).
+
+ @param option: Indicates whether the midi-block has to be added or not.
+ @type option: boolean
+ """
global midi_option
midi_option = option
def get_create_midi ():
+ """
+ Return, if exists the state of the midi-option.
+
+ @return: The state of the midi-option.
+ @rtype: boolean
+ """
try:
return midi_option
except:
return False
+# implement the command line option '--transpose'
+def set_transpose(option):
+ global transpose_option
+ transpose_option = option
+
+def get_transpose(optType):
+ try:
+ if(optType == "string"):
+ return '\\transpose c %s' % transpose_option
+ elif(optType == "integer"):
+ p = generic_tone_to_pitch(transpose_option)
+ return p.semitones()
+ except:
+ if(optType == "string"):
+ return ""
+ elif(optType == "integer"):
+ return 0
+
+# implement the command line option '--tab-clef'
+def set_tab_clef(option):
+ global tab_clef_option
+ tab_clef_option = option
+
+def get_tab_clef():
+ try:
+ return ("tab", tab_clef_option)[tab_clef_option == "tab" or tab_clef_option == "moderntab"]
+ except:
+ return "tab"
+
+# definitions of the command line option '--string-numbers'
+def set_string_numbers(option):
+ global string_numbers_option
+ string_numbers_option = option
+
+def get_string_numbers():
+ try:
+ return ("t", string_numbers_option)[string_numbers_option == "t" or string_numbers_option == "f"]
+ except:
+ return "t"
+
+def generic_tone_to_pitch (tone):
+ accidentals_dict = {
+ "" : 0,
+ "es" : -1,
+ "s" : -1,
+ "eses" : -2,
+ "ses" : -2,
+ "is" : 1,
+ "isis" : 2
+ }
+ p = Pitch ()
+ tone_ = tone.strip().lower()
+ p.octave = tone_.count("'") - tone_.count(",")
+ tone_ = tone_.replace(",","").replace("'","")
+ p.step = ((ord (tone_[0]) - ord ('a') + 5) % 7)
+ p.alteration = accidentals_dict.get(tone_[1:], 0)
+ return p
+
# Implement the different note names for the various languages
def pitch_generic (pitch, notenames, accidentals):
str = notenames[pitch.step]
ly.warning (_ ("Language does not support microtones contained in the piece"))
else:
try:
- str += {-0.5: accidentals[1], 0.5: accidentals[2]}[pitch.alteration-halftones]
+ str += {-0.5: accidentals[1], 0.5: accidentals[2]}[pitch.alteration - halftones]
except KeyError:
ly.warning (_ ("Language does not support microtones contained in the piece"))
return str
# global variable to hold the formatting function.
pitch_generating_function = pitch_general
-
class Pitch:
def __init__ (self):
self.alteration = 0
def transposed (self, interval):
c = self.copy ()
- c.alteration += interval.alteration
+ c.alteration += interval.alteration
c.step += interval.step
c.octave += interval.octave
c.normalize ()
- target_st = self.semitones() + interval.semitones()
+ target_st = self.semitones() + interval.semitones()
c.alteration += target_st - c.semitones()
return c
c.step += 7
c.octave -= 1
c.octave += c.step / 7
- c.step = c.step % 7
+ c.step = c.step % 7
def lisp_expression (self):
return '(ly:make-pitch %d %d %d)' % (self.octave,
p.alteration = self.alteration
p.step = self.step
p.octave = self.octave
+ p._force_absolute_pitch = self._force_absolute_pitch
return p
def steps (self):
- return self.step + self.octave *7
+ return self.step + self.octave * 7
def semitones (self):
- return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
+ return self.octave * 12 + [0, 2, 4, 5, 7, 9, 11][self.step] + self.alteration
+
+ def normalize_alteration (c):
+ if(c.alteration < 0 and [True, False, False, True, False, False, False][c.step]):
+ c.alteration += 1
+ c.step -= 1
+ elif(c.alteration > 0 and [False, False, True, False, False, False, True][c.step]):
+ c.alteration -= 1
+ c.step += 1
+ c.normalize ()
+
+ def add_semitones (self, number):
+ semi = number + self.alteration
+ self.alteration = 0
+ if(semi == 0):
+ return
+ sign = (1,-1)[semi < 0]
+ prev = self.semitones()
+ while abs((prev + semi) - self.semitones ()) > 1:
+ self.step += sign
+ self.normalize()
+ self.alteration += (prev + semi) - self.semitones ()
+ self.normalize_alteration ()
def ly_step_expression (self):
return pitch_generating_function (self)
str += self.relative_pitch ()
else:
str += self.absolute_pitch ()
-
return str
def print_ly (self, outputter):
props = self.get_properties ()
- return "(make-music '%s %s)" % (name, props)
+ return "(make-music '%s %s)" % (name, props)
def set_start (self, start):
self.start = start
return self
return None
- def print_comment (self, printer, text = None):
+ def print_comment (self, printer, text=None):
if not text:
text = self.comment
def get_subset_properties (self, predicate):
return ("'elements (list %s)"
% string.join (map (lambda x: x.lisp_expression(),
- filter ( predicate, self.elements))))
+ filter (predicate, self.elements))))
def get_neighbor (self, music, dir):
assert music.parent == self
idx = self.elements.index (music)
idx += dir
- idx = min (idx, len (self.elements) -1)
+ idx = min (idx, len (self.elements) - 1)
idx = max (idx, 0)
return self.elements[idx]
class SequentialMusic (NestedMusic):
def get_last_event_chord (self):
value = None
- at = len( self.elements ) - 1
+ at = len(self.elements) - 1
while (at >= 0 and
not isinstance (self.elements[at], ChordEvent) and
not isinstance (self.elements[at], BarLine)):
value = self.elements[at]
return value
- def print_ly (self, printer, newline = True):
+ def print_ly (self, printer, newline=True):
printer ('{')
if self.comment:
self.print_comment (printer)
props = self.get_subset_properties (pred)
- return "(make-music '%s %s)" % (name, props)
+ return "(make-music '%s %s)" % (name, props)
def set_start (self, start):
for e in self.elements:
self.lyrics_syllables = []
def print_ly (self, printer):
- printer.dump ("\lyricmode {")
- for l in self.lyrics_syllables:
- printer.dump ( "%s " % l )
- printer.dump ("}")
+ printer.dump (self.ly_expression ())
+ printer.newline()
+ printer.dump ('}')
+ printer.newline()
def ly_expression (self):
- lstr = "\lyricmode {\n "
+ lstr = "\lyricmode {\set ignoreMelismata = ##t"
for l in self.lyrics_syllables:
- lstr += l + " "
- lstr += "\n}"
+ lstr += l
+ #lstr += "\n}"
return lstr
-
class Header:
+
def __init__ (self):
self.header_fields = {}
+
def set_field (self, field, value):
self.header_fields[field] = value
- def print_ly (self, printer):
- printer.dump ("\header {")
- printer.newline ()
- for (k,v) in self.header_fields.items ():
+ def format_header_strings(self, key, value, printer):
+ printer.dump(key + ' = ')
+
+ # If a header item contains a line break, it is segmented. The
+ # substrings are formatted with the help of \markup, using
+ # \column and \line. An exception, however, are texidoc items,
+ # which should not contain LilyPond formatting commands.
+ if (key != 'texidoc') and ('\n' in value):
+ value = value.replace('"', '')
+ printer.dump(r'\markup \column {')
+ substrings = value.split('\n')
+ for s in substrings:
+ printer.newline()
+ printer.dump(r'\line { "' + s + '"}')
+ printer.dump('}')
+ printer.newline()
+ else:
+ printer.dump(value)
+ printer.newline()
+
+ def print_ly(self, printer):
+ printer.dump("\header {")
+ printer.newline()
+ for (k, v) in self.header_fields.items():
if v:
- printer.dump ('%s = %s' % (k,v))
- printer.newline ()
- printer.dump ("}")
- printer.newline ()
- printer.newline ()
+ self.format_header_strings(k, v, printer)
+ #printer.newline()
+ printer.dump("}")
+ printer.newline()
+ printer.newline()
class Paper:
- def __init__ (self):
+ def __init__(self):
self.global_staff_size = -1
# page size
self.page_width = -1
self.system_right_margin = -1
self.system_distance = -1
self.top_system_distance = -1
+ self.indent = 0
+ self.short_indent = 0
+ self.instrument_names = []
def print_length_field (self, printer, field, value):
if value >= 0:
printer.dump ("%s = %s\\cm" % (field, value))
printer.newline ()
+
+ def get_longest_instrument_name(self):
+ result = ''
+ for name in self.instrument_names:
+ lines = name.split('\n')
+ for line in lines:
+ if len(line) > len(result):
+ result = line
+ return result
+
def print_ly (self, printer):
if self.global_staff_size > 0:
printer.dump ('#(set-global-staff-size %s)' % self.global_staff_size)
printer.newline ()
printer.dump ('\\paper {')
printer.newline ()
+ printer.newline ()
self.print_length_field (printer, "paper-width", self.page_width)
self.print_length_field (printer, "paper-height", self.page_height)
self.print_length_field (printer, "top-margin", self.top_margin)
# system_right_margin in LilyPond?
self.print_length_field (printer, "between-system-space", self.system_distance)
self.print_length_field (printer, "page-top-space", self.top_system_distance)
+ # TODO: Compute the indentation with the instrument name lengths
+
+ # TODO: font width ?
+ char_per_cm = (len(self.get_longest_instrument_name()) * 13) / self.page_width
+ if (self.indent != 0):
+ self.print_length_field (printer, "indent", self.indent/char_per_cm)
+ if (self.short_indent != 0):
+ self.print_length_field (printer, "short-indent", self.short_indent/char_per_cm)
printer.dump ('}')
printer.newline ()
# Print all overrides and other settings needed by the
# articulations/ornaments before the note
+
for e in other_events:
e.print_before_note (printer)
global previous_pitch
pitches = []
basepitch = None
+ stem = None
for x in note_events:
+ if(x.associated_events):
+ for aev in x.associated_events:
+ if (isinstance(aev, StemEvent) and aev.value):
+ stem = aev
pitches.append (x.chord_element_ly ())
if not basepitch:
basepitch = previous_pitch
+ if stem:
+ printer (stem.ly_expression ())
printer ('<%s>' % string.join (pitches))
previous_pitch = basepitch
duration = self.get_duration ()
self.span_direction = 0 # start/stop
self.line_type = 'solid'
self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
- self.size = 0 # size of e.g. ocrave shift
+ self.size = 0 # size of e.g. octave shift
def wait_for_note (self):
return True
def get_properties(self):
1:'\\sustainOff'}.get (self.span_direction, '')
class TextSpannerEvent (SpanEvent):
+ def print_before_note (self, printer):
+ if hasattr(self, 'style') and self.style=="wave":
+ printer.dump("\once \override TextSpanner #'style = #'trill")
+ try:
+ x = {-1:'\\textSpannerDown', 0:'\\textSpannerNeutral', 1: '\\textSpannerUp'}.get(self.force_direction, '')
+ printer.dump (x)
+ except:
+ pass
+
+ def print_after_note (self, printer):
+ pass
+
def ly_expression (self):
- return {-1: '\\startTextSpan',
- 1:'\\stopTextSpan'}.get (self.span_direction, '')
+ global whatOrnament
+ if hasattr(self, 'style') and self.style=="ignore":
+ return ""
+ # if self.style=="wave":
+ if whatOrnament == "wave":
+ return {-1: '\\startTextSpan',
+ 1:'\\stopTextSpan'}.get (self.span_direction, '')
+ else:
+ if hasattr(self, 'style') and self.style=="stop" and whatOrnament != "trill": return ""
+ return {-1: '\\startTrillSpan',
+ 1:'\\stopTrillSpan'}.get (self.span_direction, '')
class BracketSpannerEvent (SpanEvent):
# Ligature brackets use prefix-notation!!!
def print_before_note (self, printer):
if self.span_direction == -1:
+ if self.force_direction == 1:
+ printer.dump("\once \override LigatureBracket #' direction = #UP")
+ elif self.force_direction == -1:
+ printer.dump("\once \override LigatureBracket #' direction = #DOWN")
printer.dump ('\[')
# the bracket after the last note
def print_after_note (self, printer):
def wait_for_note (self):
return False
def set_span_type (self, type):
- self.span_type = {'up': 1, 'down': -1}.get (type, 0)
+ self.span_type = {'up': 1, 'down':-1}.get (type, 0)
def ly_octave_shift_indicator (self):
# convert 8/15 to lilypond indicators (+-1/+-2)
try:
ly.warning (_ ("Invalid octave shift size found: %s. Using no shift.") % self.size)
value = 0
# negative values go up!
- value *= -1*self.span_type
+ value *= -1 * self.span_type
return value
def ly_expression (self):
dir = self.ly_octave_shift_indicator ()
if dir:
value = '\ottava #%s' % dir
return {
- -1: value,
+ - 1: value,
1: '\ottava #0'}.get (self.span_direction, '')
class TrillSpanEvent (SpanEvent):
class GlissandoEvent (SpanEvent):
def print_before_note (self, printer):
if self.span_direction == -1:
- style= {
+ style = {
"dashed" : "dashed-line",
"dotted" : "dotted-line",
"wavy" : "zigzag"
class HairpinEvent (SpanEvent):
def set_span_type (self, type):
- self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
+ self.span_type = {'crescendo' : 1, 'decrescendo' :-1, 'diminuendo' :-1 }.get (type, 0)
def hairpin_to_ly (self):
if self.span_direction == 1:
return '\!'
else:
return {1: '\<', -1: '\>'}.get (self.span_type, '')
+ def direction_mod (self):
+ return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
+
def ly_expression (self):
return self.hairpin_to_ly ()
def print_ly (self, printer):
val = self.hairpin_to_ly ()
if val:
- printer.dump (val)
+ # printer.dump (val)
+ printer.dump ('%s%s' % (self.direction_mod (), val))
def __init__ (self):
Event.__init__ (self)
self.type = None
+ self.force_direction = 0
def wait_for_note (self):
return True
def ly_expression (self):
else:
return
+ def direction_mod (self):
+ return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
+
def print_ly (self, printer):
if self.type:
- printer.dump ("\\%s" % self.type)
+ printer.dump ('%s\\%s' % (self.direction_mod (), self.type))
class MarkEvent (Event):
def __init__ (self, text="\\default"):
self.force_direction = None
self.markup = ''
def wait_for_note (self):
+ """ This is problematic: the lilypond-markup ^"text"
+ requires wait_for_note to be true. Otherwise the
+ compilation will fail. So we are forced to set return to True.
+ But in some cases this might lead to a wrong placement of the text.
+ In case of words like Allegro the text should be put in a '\tempo'-command.
+ In this case we don't want to wait for the next note.
+ In some other cases the text is supposed to be used in a '\mark\markup' construct.
+ We would not want to wait for the next note either.
+ There might be other problematic situations.
+ In the long run we should differentiate between various contexts in MusicXML, e.g.
+ the following markup should be interpreted as '\tempo "Allegretto"':
+ <direction placement="above">
+ <direction-type>
+ <words>Allegretto</words>
+ </direction-type>
+ <sound tempo="120"/>
+ </direction>
+ In the mean time arising problems have to be corrected manually after the conversion.
+ """
return True
def direction_mod (self):
+ """ 1: placement="above"; -1: placement="below"; 0: no placement attribute.
+ see musicxml_direction_to_indicator in musicxml2ly_conversion.py """
return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
def ly_expression (self):
- base_string = '%s\"%s\"'
+ # self.text will be enclosed by quotes, and the direction
+ # modifier must be separated from the opening quote by a space.
+ # This is so that subsequent line breaking for the output file
+ # using utilities.split_string_and_preserve_doublequoted_strings()
+ # properly detects the opening quote.
+ base_string = '%s \"%s\"'
if self.markup:
base_string = '%s\markup{ ' + self.markup + ' {%s} }'
return base_string % (self.direction_mod (), self.text)
return ''
class NoDirectionArticulationEvent (ArticulationEvent):
+
+ def is_breathing_sign(self):
+ return self.type == 'breathe'
+
+ def print_after_note(self, printer):
+ # The breathing sign should, according to current LilyPond
+ # praxis, be treated as an independent musical
+ # event. Consequently, it should be printed _after_ the note
+ # to which it is attached.
+ if self.is_breathing_sign():
+ printer.dump(r'\breathe')
+
def ly_expression (self):
- if self.type:
- return '\\%s' % self.type
+ if self.type and not self.is_breathing_sign():
+ return '\\%s' % self.type
else:
return ''
if self.frets <> 4:
val += "h:%s;" % self.frets
if self.barre and len (self.barre) >= 3:
- val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2])
+ val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2]+get_transpose("integer"))
have_fingering = False
for i in self.elements:
if len (i) > 1:
- val += "%s-%s" % (i[0], i[1])
+ val += "%s-%s" % (i[0], i[1]+(get_transpose("integer"),'')[isinstance(i[1],str)])
if len (i) > 2:
have_fingering = True
val += "-%s" % i[2]
else:
return ''
+class FretBoardNote (Music):
+ def __init__ (self):
+ Music.__init__ (self)
+ self.pitch = None
+ self.string = None
+ self.fingering = None
+ def ly_expression (self):
+ str = self.pitch.ly_expression()
+ if self.fingering:
+ str += "-%s" % self.fingering
+ if self.string:
+ str += "\%s" % self.string
+ return str
+
+class FretBoardEvent (NestedMusic):
+ def __init__ (self):
+ NestedMusic.__init__ (self)
+ self.duration = None
+ def print_ly (self, printer):
+ fretboard_notes = [n for n in self.elements if isinstance (n, FretBoardNote)]
+ if fretboard_notes:
+ notes = []
+ for n in fretboard_notes:
+ notes.append (n.ly_expression ())
+ contents = string.join (notes)
+ printer ('<%s>%s' % (contents,self.duration))
class FunctionWrapperEvent (Event):
- def __init__ (self, function_name = None):
+ def __init__ (self, function_name=None):
Event.__init__ (self)
self.function_name = function_name
def pre_note_ly (self, is_chord_element):
def __init__ (self):
FunctionWrapperEvent.__init__ (self, "parenthesize")
-class NotestyleEvent (Event):
+class StemEvent (Event):
+ """"
+ A class to take care of stem values (up, down, double, none)
+ """
+ def __init__ (self):
+ Event.__init__ (self)
+ self.value = None
+ def pre_chord_ly (self):
+ if self.value:
+ return "\\%s" % self.value
+ else:
+ return ''
+ def pre_note_ly (self, is_chord_element):
+ return ''
+ def ly_expression (self):
+ return self.pre_chord_ly ()
+
+class NotestyleEvent (Event): #class changed by DaLa: additional attribute color
def __init__ (self):
Event.__init__ (self)
self.style = None
self.filled = None
+ self.color = None
def pre_chord_ly (self):
+ return_string = ''
if self.style:
- return "\\once \\override NoteHead.style = #%s" % self.style
- else:
- return ''
+ return_string += " \\once \\override NoteHead #'style = #%s" % self.style
+ if self.color:
+ return_string += " \\once \\override NoteHead #'color = #(rgb-color %s %s %s)" % (self.color[0], self.color[1], self.color[2])
+ return return_string
def pre_note_ly (self, is_chord_element):
if self.style and is_chord_element:
return "\\tweak style #%s" % self.style
def ly_expression (self):
return self.pre_chord_ly ()
+class StemstyleEvent (Event): #class added by DaLa
+ def __init__ (self):
+ Event.__init__ (self)
+ self.color = None
+ def pre_chord_ly (self):
+ if self.color:
+ return "\\once \\override Stem #'color = #(rgb-color %s %s %s)" % (self.color[0], self.color[1], self.color[2])
+ else:
+ return ''
+ def pre_note_ly (self, is_chord_element):
+ return ''
+ def ly_expression (self):
+ return self.pre_chord_ly ()
+
class ChordPitch:
def __init__ (self):
def add_modification (self, mod):
self.modifications.append (mod)
def ly_expression (self):
+
if not self.root:
return ''
value = self.root.ly_expression ()
if self.duration:
value += self.duration.ly_expression ()
if self.kind:
- value += ":"
- value += self.kind
+ value = self.kind.format(value)
# First print all additions/changes, and only afterwards all subtractions
for m in self.modifications:
if m.type == 1:
return value
-class TremoloEvent (ArticulationEvent):
- def __init__ (self):
- Event.__init__ (self)
- self.bars = 0
-
- def ly_expression (self):
- str=''
- if self.bars and self.bars > 0:
- str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
- return str
+class TremoloEvent(ArticulationEvent):
+ def __init__(self):
+ Event.__init__(self)
+ self.strokes = 0
+
+ def ly_expression(self):
+ ly_str = ''
+ if self.strokes and int(self.strokes) > 0:
+ # ly_dur is a global variable defined in class Duration
+ # ly_dur stores the value of the reciprocal values of notes
+ # ly_dur is used here to check the current note duration
+ # if the duration is smaller than 8, e.g.
+ # quarter, half and whole notes,
+ # `:(2 ** (2 + number of tremolo strokes))'
+ # should be appended to the pitch and duration, e.g.
+ # 1 stroke: `c4:8' or `c2:8' or `c1:8'
+ # 2 strokes: `c4:16' or `c2:16' or `c1:16'
+ # ...
+ # else (if ly_dur is equal to or greater than 8):
+ # we need to make sure that the tremolo value that is to
+ # be appended to the pitch and duration is twice the
+ # duration (if there is only one tremolo stroke.
+ # Each additional stroke doubles the tremolo value, e.g.:
+ # 1 stroke: `c8:16', `c16:32', `c32:64', ...
+ # 2 strokes: `c8:32', `c16:64', `c32:128', ...
+ # ...
+ if ly_dur < 8:
+ ly_str += ':%s' % (2 ** (2 + int(self.strokes)))
+ else:
+ ly_str += ':%s' % (2 ** int((math.log(ly_dur, 2)) + int(self.strokes)))
+ return ly_str
class BendEvent (ArticulationEvent):
def __init__ (self):
def print_ly (self, printer):
for ev in self.associated_events:
ev.print_ly (printer)
+# if hasattr(self, 'color'):
+# printer.print_note_color("NoteHead", self.color)
+# printer.print_note_color("Stem", self.color)
+# printer.print_note_color("Beam", self.color)
if self.pitch:
self.pitch.print_ly (printer)
self.duration.print_ly (printer)
class NoteEvent(RhythmicEvent):
def __init__ (self):
RhythmicEvent.__init__ (self)
- self.pitch = None
+ #self.pitch = None
self.drum_type = None
self.cautionary = False
self.forced_accidental = False
def print_ly (self, printer):
for ev in self.associated_events:
ev.print_ly (printer)
+ if hasattr(self, 'color'):
+ printer.print_note_color("NoteHead", self.color)
+ printer.print_note_color("Stem", self.color)
+ printer.print_note_color("Beam", self.color)
+
if self.pitch:
self.pitch.print_ly (printer)
printer (self.pitch_mods ())
self.duration.print_ly (printer)
+# if hasattr(self, 'color'):
+# printer.print_note_color("NoteHead")
+# printer.print_note_color("Stem")
+# printer.print_note_color("Beam")
+
class KeySignatureChange (Music):
def __init__ (self):
Music.__init__ (self)
def format_non_standard_alteration (self, a):
alter_dict = { -2: ",DOUBLE-FLAT",
- -1.5: ",THREE-Q-FLAT",
- -1: ",FLAT",
- -0.5: ",SEMI-FLAT",
+ - 1.5: ",THREE-Q-FLAT",
+ - 1: ",FLAT",
+ - 0.5: ",SEMI-FLAT",
0: ",NATURAL",
0.5: ",SEMI-SHARP",
1: ",SHARP",
else:
return ''
+class ShiftDurations (MusicWrapper):
+ def __init__ (self):
+ MusicWrapper.__init__ (self)
+ self.params = [0,0]
+
+ def set_shift_durations_parameters(self, timeSigChange):
+ self.params = timeSigChange.get_shift_durations_parameters()
+
+ def print_ly (self, func):
+ func (' \\shiftDurations #%d #%d ' % tuple(self.params))
+ MusicWrapper.print_ly (self, func)
+
class TimeSignatureChange (Music):
def __init__ (self):
Music.__init__ (self)
- self.fractions = [4,4]
+ self.fractions = [4, 4]
self.style = None
+ # Used for the --time-signature option of musicxml2ly
+ self.originalFractions = [4, 4]
+
+ def get_fractions_ratio (self):
+ """
+ Calculate the ratio between the original time fraction and the new one.
+ Used for the "--time-signature" option.
+
+ @return: The ratio between the two time fractions.
+ @rtype: float
+ """
+ return (float(self.originalFractions[0])/self.originalFractions[1])*(float(self.fractions[1])/self.fractions[0])
+
+ def get_shift_durations_parameters (self):
+ dur = math.ceil(math.log(self.get_fractions_ratio(),2))
+ dots = (1/self.get_fractions_ratio())/(math.pow(2,-dur))
+ dots = int(math.log(2-dots,0.5))
+ return [dur, dots]
+
def format_fraction (self, frac):
if isinstance (frac, list):
l = [self.format_fraction (f) for f in frac]
# Print out the style if we have ome, but the '() should only be
# forced for 2/2 or 4/4, since in all other cases we'll get numeric
# signatures anyway despite the default 'C signature style!
- is_common_signature = self.fractions in ([2,2], [4,4], [4,2])
+ is_common_signature = self.fractions in ([2, 2], [4, 4], [4, 2])
if self.style:
if self.style == "common":
st = "\\defaultTimeSignature"
def octave_modifier (self):
return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
+
def clef_name (self):
return {('G', 2): "treble",
('G', 1): "french",
('F', 4): "bass",
('F', 5): "subbass",
("percussion", 2): "percussion",
- # Workaround: MuseScore uses PERC instead of percussion
+ # Workaround: MuseScore uses PERC instead of percussion
("PERC", 2): "percussion",
- ("TAB", 5): "tab"}.get ((self.type, self.position), None)
+ ("TAB", 5): get_tab_clef ()}.get ((self.type, self.position), None)
+
def ly_expression (self):
return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
printer.dump ("\\%s" % self.type)
class StaffGroup:
- def __init__ (self, command = "StaffGroup"):
+ def __init__ (self, command="StaffGroup"):
self.stafftype = command
self.id = None
self.instrument_name = None
+ self.sound = None
self.short_instrument_name = None
self.symbol = None
self.spanbar = None
for c in self.children:
if c:
c.print_ly (printer)
+ #Intention: I want to put the content of new StaffGroup in angled brackets (<< >>)
+ #printer.dump ("test")# test is printed twice at the end of a staffgroup with two staves.
+ #printer ("test") # test is printed twice at the end of a staffgroup with two staves.
+
def needs_with (self):
needs_with = False
needs_with |= self.spanbar == "no"
needs_with |= self.short_instrument_name != None
needs_with |= (self.symbol != None) and (self.symbol != "bracket")
return needs_with
+
def print_ly_context_mods (self, printer):
if self.instrument_name or self.short_instrument_name:
printer.dump ("\\consists \"Instrument_name_engraver\"")
for m in self.context_modifications:
printer.dump (m)
printer.dump ("}")
-
- def print_ly_chords (self,printer):
+ printer.newline ()
+ #print a single << after StaffGroup only when the with-block is not needed.
+ #This doesn't work. << is printed before and after StaffGroup!
+ #else:
+ # printer.dump (" <<")
+ #prints loads off << before and after StaffGroup and before \set Staff.instrumentName
+ #elif not needs_with:
+ # printer.dump (" <<")
+
+ def print_chords(self, printer):
try:
for [staff_id, voices] in self.part_information:
- for [v, lyrics, figuredbass, chordnames] in voices:
+ for [v, lyrics, figuredbass, chordnames, fretboards] in voices:
if chordnames:
- printer ('\context ChordNames = "%s" \\%s' % (chordnames, chordnames))
- printer.newline ()
+ printer ('\context ChordNames = "%s" {%s \\%s}' % (chordnames, get_transpose ("string"), chordnames))
+ printer.newline()
+ except TypeError:
+ return
+
+ def print_fretboards(self, printer):
+ try:
+ for [staff_id, voices] in self.part_information:
+ for [v, lyrics, figuredbass, chordnames, fretboards] in voices:
+ if fretboards:
+ printer ('\context FretBoards = "%s" {%s \\%s}' % (fretboards, get_transpose ("string"), fretboards))
+ printer.newline()
except TypeError:
return
def print_ly (self, printer):
- self.print_ly_chords (printer)
+ self.print_chords(printer)
+ self.print_fretboards(printer)
if self.stafftype:
printer.dump ("\\new %s" % self.stafftype)
self.print_ly_overrides (printer)
- printer.dump ("<<")
printer.newline ()
+ if self.stafftype:
+ printer.dump ("<<")
+ printer.newline ()
if self.stafftype and self.instrument_name:
printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
escape_instrument_string (self.instrument_name)))
printer.dump ("\\set %s.shortInstrumentName = %s" % (self.stafftype,
escape_instrument_string (self.short_instrument_name)))
printer.newline ()
+ if self.sound:
+ printer.dump(
+ r'\set {stafftype}.midiInstrument = #"{sound}"'.format(
+ stafftype=self.stafftype, sound=self.sound))
+ printer.newline ()
self.print_ly_contents (printer)
printer.newline ()
- printer.dump (">>")
- printer.newline ()
+ if self.stafftype:
+ printer.dump (">>")
+ printer.newline ()
class Staff (StaffGroup):
- def __init__ (self, command = "Staff"):
+ def __init__ (self, command="Staff"):
StaffGroup.__init__ (self, command)
self.is_group = False
self.part = None
self.voice_command = "Voice"
self.substafftype = None
+ self.sound = None
def needs_with (self):
return False
+
def print_ly_context_mods (self, printer):
+ #printer.dump ("test") #does nothing.
pass
def print_ly_contents (self, printer):
sub_staff_type = self.substafftype
if not sub_staff_type:
sub_staff_type = self.stafftype
+ #printer.dump ("test") #prints test in each staff after the definitions of the instrument name and before the definition of the contexts.
+ printer.newline()
for [staff_id, voices] in self.part_information:
+ # now comes the real staff definition:
if staff_id:
printer ('\\context %s = "%s" << ' % (sub_staff_type, staff_id))
else:
printer ('\\context %s << ' % sub_staff_type)
printer.newline ()
+ printer.dump("\mergeDifferentlyDottedOn\mergeDifferentlyHeadedOn")
+ printer.newline()
n = 0
nr_voices = len (voices)
- for [v, lyrics, figuredbass, chordnames] in voices:
+ for [v, lyrics, figuredbass, chordnames, fretboards] in voices:
n += 1
voice_count_text = ''
if nr_voices > 1:
- voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo',
- 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
- printer ('\\context %s = "%s" {%s \\%s }' % (self.voice_command, v, voice_count_text, v))
+ """
+The next line contains a bug: The voices might not appear in numerical order! Some voices might be missing e.g. if the xml file contains only voice one, three and four, this would result in: \voiceOne, \voiceTwo and \voiceThree. This causes wrong stem directions and collisions.
+ """
+ voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo', 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
+ printer ('\\context %s = "%s" {%s %s \\%s }' % (self.voice_command, v, get_transpose ("string"), voice_count_text, v))
printer.newline ()
-
+ lyrics_id = 1
for l in lyrics:
- printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
+ printer ('\\new Lyrics \\lyricsto "%s" { \\set stanza = "%s." \\%s }' % (v, lyrics_id, l))
+ lyrics_id += 1
printer.newline()
if figuredbass:
printer ('\context FiguredBass = "%s" \\%s' % (figuredbass, figuredbass))
printer ('>>')
+ #printer.dump ("test") #prints test after each definition of a context.
+ #printer.newline ()
+ #printer.dump ("test") #prints test after each definition of a context.
def print_ly (self, printer):
if self.part_information and len (self.part_information) > 1:
self.stafftype = "PianoStaff"
self.substafftype = "Staff"
+ #printer.dump ('test')
StaffGroup.print_ly (self, printer)
+
class TabStaff (Staff):
- def __init__ (self, command = "TabStaff"):
+ def __init__ (self, command="TabStaff"):
Staff.__init__ (self, command)
self.string_tunings = []
self.tablature_format = None
class DrumStaff (Staff):
- def __init__ (self, command = "DrumStaff"):
+ def __init__ (self, command="DrumStaff"):
Staff.__init__ (self, command)
self.drum_style_table = None
self.voice_command = "DrumVoice"
printer.dump ("}")
class RhythmicStaff (Staff):
- def __init__ (self, command = "RhythmicStaff"):
+ def __init__ (self, command="RhythmicStaff"):
Staff.__init__ (self, command)
+#Test
+#def print_staffgroup_closing_brackets (self, printer): #test see class Score / class Staff
+# printer.dump ("test")
+
class Score:
def __init__ (self):
+ """
+ Constructs a new Score object.
+ """
self.contents = None
self.create_midi = False
if self.contents:
self.contents.set_part_information (part_id, staves_info)
+ def set_tempo (self, tempo):
+ """
+ Set the tempo attribute of the Score.
+ This attribute can be used in L{print_ly} for the midi output (see L{musicxml.Sound}).
+
+ @param tempo: The value of the tempo, in beats per minute.
+ @type tempo: String
+ """
+ self.tempo = tempo
+ #Test
+# def print_staffgroup_closing_brackets (self, printer): #test see class Score / class Staff
+# printer.dump ("test")
+
def print_ly (self, printer):
- self.create_midi = get_create_midi ()
- printer.dump ("\\score {");
+ """
+ Print the content of the score to the printer, in lilypond format.
+
+ @param printer: A printer given to display correctly the output.
+ @type printer: L{Output_printer<musicexp.Output_printer>}
+ """
+ self.create_midi = get_create_midi()
+ printer.dump("\\score {")
+ printer.newline ()
+ #prints opening <<:
+ printer.dump ('<<')
printer.newline ()
if self.contents:
- self.contents.print_ly (printer);
- printer.dump ("\\layout {}");
+ self.contents.print_ly(printer)
+ #printer.dump ("test") prints test once before the >> of the score block, independent of the existence of a staffgroup.
+ #if StaffGroup == False: # True or False: nothing happens.
+ # printer.dump ('>>')
+ printer.dump ('>>')
printer.newline ()
- if not self.create_midi:
- printer.dump ("% To create MIDI output, uncomment the following line:");
- printer.newline ();
- printer.dump ("% ");
- printer.dump ("\\midi {}");
+ #StaffGroup.print_staffgroup_closing_brackets(self, printer) #TypeError: unbound method print_staffgroup_closing_brackets() must be called with StaffGroup instance as first argument (got Score instance instead)
+ #print_staffgroup_closing_brackets(self, printer) #NameError: global name 'print_staffgroup_closing_brackets' is not defined. prints test once before the >> of the score block, independent of the existence of a staffgroup.
+ printer.dump ("\\layout {}")
printer.newline ()
- printer.dump ("}");
+ # If the --midi option was not passed to musicxml2ly, that comments the "midi" line
+ if self.create_midi:
+ printer.dump ("}")
+ printer.newline()
+ printer.dump("\\score {")
+ printer.newline ()
+ printer.dump("\\unfoldRepeats \\articulate {")
+ printer.newline ()
+ self.contents.print_ly(printer)
+ printer.dump("}")
+ printer.newline ()
+ else:
+ printer.dump ("% To create MIDI output, uncomment the following line:")
+ printer.newline ()
+ printer.dump ("% ")
+ printer.dump ("\\midi {\\tempo 4 = "+self.tempo+" }")
+ printer.newline ()
+ printer.dump ("}")
printer.newline ()
-
def test_pitch ():
bflat = Pitch()
bflat.alteration = -1
- bflat.step = 6
+ bflat.step = 6
bflat.octave = -1
fifth = Pitch()
fifth.step = 4
print bflat.semitones()
- print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
+ print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
print bflat.semitones(), 'down'
tonic.step = 2
tonic.alteration = -2
n = KeySignatureChange()
- n.tonic=tonic.copy()
- n.scale = [0, 0, -2, 0, 0,-2,-2]
+ n.tonic = tonic.copy()
+ n.scale = [0, 0, -2, 0, 0, -2, -2]
evc.insert_around (None, n, 0)
m.insert_around (None, evc, 0)
expr = test_expr()
expr.set_start (Rational (0))
print expr.ly_expression()
- start = Rational (0,4)
- stop = Rational (4,2)
+ start = Rational (0, 4)
+ stop = Rational (4, 2)
def sub(x, start=start, stop=stop):
- ok = x.start >= start and x.start +x.get_length() <= stop
+ ok = x.start >= start and x.start + x.get_length() <= stop
return ok
print expr.lisp_sub_expression(sub)
-
import sys
import copy
import lilylib as ly
+import warnings
_ = ly._
-
-def escape_ly_output_string (input_string):
- return_string = input_string
- needs_quotes = not re.match (u"^[a-zA-ZäöüÜÄÖßñ]*$", return_string);
- if needs_quotes:
- return_string = "\"" + string.replace (return_string, "\"", "\\\"") + "\""
- return return_string
-
-
-def musicxml_duration_to_log (dur):
- return {'256th': 8,
- '128th': 7,
- '64th': 6,
- '32nd': 5,
- '16th': 4,
- 'eighth': 3,
- 'quarter': 2,
- 'half': 1,
- 'whole': 0,
- 'breve': -1,
- 'longa': -2,
- 'long': -2}.get (dur, 0)
-
-
-
-def interpret_alter_element (alter_elm):
- alter = 0
- if alter_elm:
- val = eval(alter_elm.get_text ())
- if type (val) in (int, float):
- alter = val
- return alter
+import musicexp
+import musicxml2ly_conversion
+import utilities
class Xml_node:
- def __init__ (self):
+
+ def __init__(self):
self._children = []
self._data = None
self._original = None
self._parent = None
self._attribute_dict = {}
- def get_parent (self):
+ def get_parent(self):
return self._parent
- def is_first (self):
- return self._parent.get_typed_children (self.__class__)[0] == self
+ def is_first(self):
+ return self._parent.get_typed_children(self.__class__)[0] == self
- def original (self):
+ def original(self):
return self._original
- def get_name (self):
+ def get_name(self):
return self._name
- def get_text (self):
+ def get_text(self):
if self._data:
return self._data
if not self._children:
return ''
- return ''.join ([c.get_text () for c in self._children])
+ return ''.join([c.get_text() for c in self._children])
- def message (self, msg):
- ly.warning (msg)
+ def message(self, msg):
+ ly.warning(msg)
p = self
while p:
- ly.progress (' In: <%s %s>\n' % (p._name, ' '.join (['%s=%s' % item for item in p._attribute_dict.items ()])))
- p = p.get_parent ()
+ ly.progress(' In: <%s %s>\n' %(p._name, ' '.join(['%s=%s' % item for item in p._attribute_dict.items()])))
+ p = p.get_parent()
- def dump (self, indent = ''):
- ly.debug_output ('%s<%s%s>' % (indent, self._name, ''.join ([' %s=%s' % item for item in self._attribute_dict.items ()])))
- non_text_children = [c for c in self._children if not isinstance (c, Hash_text)]
+ def dump(self, indent=''):
+ ly.debug_output('%s<%s%s>' %(indent, self._name, ''.join([' %s=%s' % item for item in self._attribute_dict.items()])))
+ non_text_children = [c for c in self._children if not isinstance(c, Hash_text)]
if non_text_children:
- ly.debug_output ('\n')
+ ly.debug_output('\n')
for c in self._children:
- c.dump (indent + " ")
+ c.dump(indent + " ")
if non_text_children:
- ly.debug_output (indent)
- ly.debug_output ('</%s>\n' % self._name)
+ ly.debug_output(indent)
+ ly.debug_output('</%s>\n' % self._name)
- def get_typed_children (self, klass):
+ def get_typed_children(self, klass):
if not klass:
return []
else:
return [c for c in self._children if isinstance(c, klass)]
- def get_named_children (self, nm):
- return self.get_typed_children (get_class (nm))
+ def get_named_children(self, nm):
+ return self.get_typed_children(get_class(nm))
- def get_named_child (self, nm):
- return self.get_maybe_exist_named_child (nm)
+ def get_named_child(self, nm):
+ return self.get_maybe_exist_named_child(nm)
- def get_children (self, predicate):
+ def get_children(self, predicate):
return [c for c in self._children if predicate(c)]
- def get_all_children (self):
+ def get_all_children(self):
return self._children
- def get_maybe_exist_named_child (self, name):
- return self.get_maybe_exist_typed_child (get_class (name))
+ def get_maybe_exist_named_child(self, name):
+ return self.get_maybe_exist_typed_child(get_class(name))
- def get_maybe_exist_typed_child (self, klass):
- cn = self.get_typed_children (klass)
- if len (cn)==0:
+ def get_maybe_exist_typed_child(self, klass):
+ cn = self.get_typed_children(klass)
+ if len(cn) == 0:
return None
- elif len (cn) == 1:
- return cn[0]
else:
- raise "More than 1 child", klass
-
- def get_unique_typed_child (self, klass):
+ try:
+ assert len(cn) == 1
+ return cn[0]
+ except:
+ msg = ' '.join(
+ ['more than one child of class ',
+ klass.__name__,
+ '...all but the first will be ignored!'])
+ warnings.warn(msg)
+ return cn[0]
+
+ def get_unique_typed_child(self, klass):
cn = self.get_typed_children(klass)
- if len (cn) <> 1:
- ly.error (self.__dict__)
- raise 'Child is not unique for', (klass, 'found', cn)
+ if len(cn) <> 1:
+ ly.error(self.__dict__)
+ raise 'Child is not unique for',(klass, 'found', cn)
return cn[0]
- def get_named_child_value_number (self, name, default):
- n = self.get_maybe_exist_named_child (name)
+ def get_named_child_value_number(self, name, default):
+ n = self.get_maybe_exist_named_child(name)
if n:
- return string.atoi (n.get_text())
+ return int(n.get_text())
else:
return default
-class Music_xml_node (Xml_node):
- def __init__ (self):
- Xml_node.__init__ (self)
- self.duration = Rational (0)
- self.start = Rational (0)
+class Music_xml_node(Xml_node):
+ def __init__(self):
+ Xml_node.__init__(self)
+ self.duration = Rational(0)
+ self.start = Rational(0)
+ self.converted = False
self.voice_id = None;
-class Work (Xml_node):
- def get_work_information (self, tag):
- wt = self.get_maybe_exist_named_child (tag)
+
+class Music_xml_spanner(Music_xml_node):
+
+ def get_type(self):
+ if hasattr(self, 'type'):
+ return self.type
+ else:
+ return 0
+
+ def get_size(self):
+ if hasattr(self, 'size'):
+ return int(self.size)
+ else:
+ return 0
+
+
+class Measure_element(Music_xml_node):
+
+ def get_voice_id(self):
+ voice_id = self.get_maybe_exist_named_child('voice')
+ if voice_id:
+ return voice_id.get_text()
+ else:
+ return None
+
+ def is_first(self):
+ # Look at all measure elements(previously we had self.__class__, which
+ # only looked at objects of the same type!
+ cn = self._parent.get_typed_children(Measure_element)
+ # But only look at the correct voice; But include Attributes, too, which
+ # are not tied to any particular voice
+ cn = [c for c in cn if(c.get_voice_id() == self.get_voice_id()) or isinstance(c, Attributes)]
+ return cn[0] == self
+
+
+class Work(Xml_node):
+
+ def get_work_information(self, tag):
+ wt = self.get_maybe_exist_named_child(tag)
if wt:
- return wt.get_text ()
+ return wt.get_text()
else:
return ''
- def get_work_title (self):
- return self.get_work_information ('work-title')
- def get_work_number (self):
- return self.get_work_information ('work-number')
- def get_opus (self):
- return self.get_work_information ('opus')
+ def get_work_title(self):
+ return self.get_work_information('work-title')
-class Identification (Xml_node):
- def get_rights (self):
- rights = self.get_named_children ('rights')
+ def get_work_number(self):
+ return self.get_work_information('work-number')
+
+ # def get_opus(self):
+ # return self.get_work_information('opus')
+
+
+class Identification(Xml_node):
+
+ def get_rights(self):
+ rights = self.get_named_children('rights')
ret = []
for r in rights:
- ret.append (r.get_text ())
- return string.join (ret, "\n")
+ text = r.get_text()
+ # if this Xml_node has an attribute, such as 'type="words"',
+ # include it in the header. Otherwise, it is assumed that
+ # the text contents of this node looks something like this:
+ # 'Copyright: X.Y.' and thus already contains the relevant
+ # information.
+ if hasattr(r, 'type'):
+ rights_type = r.type.title() # capitalize first letter
+ result = ''.join([rights_type, ': ', text])
+ ret.append(result)
+ else:
+ ret.append(text)
+ return string.join(ret, "\n")
- # get contents of the source-element (usually used for publishing information). (These contents are saved in a custom variable named "source" in the header of the .ly file.)
- def get_source (self):
- source = self.get_named_children ('source')
+ # get contents of the source-element(usually used for publishing information).(These contents are saved in a custom variable named "source" in the header of the .ly file.)
+ def get_source(self):
+ source = self.get_named_children('source')
ret = []
for r in source:
- ret.append (r.get_text ())
- return string.join (ret, "\n")
+ ret.append(r.get_text())
+ return string.join(ret, "\n")
- def get_creator (self, type):
- creators = self.get_named_children ('creator')
+ def get_creator(self, type):
+ creators = self.get_named_children('creator')
# return the first creator tag that has the particular type
for i in creators:
- if hasattr (i, 'type') and i.type == type:
- return i.get_text ()
+ if hasattr(i, 'type') and i.type == type:
+ return i.get_text()
return None
- def get_composer (self):
- c = self.get_creator ('composer')
+ def get_composer(self):
+ c = self.get_creator('composer')
if c:
return c
- creators = self.get_named_children ('creator')
+ creators = self.get_named_children('creator')
# return the first creator tag that has no type at all
for i in creators:
- if not hasattr (i, 'type'):
- return i.get_text ()
+ if not hasattr(i, 'type'):
+ return i.get_text()
return None
- def get_arranger (self):
- return self.get_creator ('arranger')
- def get_editor (self):
- return self.get_creator ('editor')
- def get_poet (self):
- v = self.get_creator ('lyricist')
+
+ def get_arranger(self):
+ return self.get_creator('arranger')
+
+ def get_editor(self):
+ return self.get_creator('editor')
+
+ def get_poet(self):
+ v = self.get_creator('lyricist')
if v:
return v
- v = self.get_creator ('poet')
+ v = self.get_creator('poet')
return v
- def get_encoding_information (self, type):
- enc = self.get_named_children ('encoding')
+ def get_encoding_information(self, type):
+ enc = self.get_named_children('encoding')
if enc:
- children = enc[0].get_named_children (type)
+ children = enc[0].get_named_children(type)
if children:
- return children[0].get_text ()
+ return children[0].get_text()
else:
return None
- def get_encoding_software (self):
- return self.get_encoding_information ('software')
- def get_encoding_date (self):
- return self.get_encoding_information ('encoding-date')
- def get_encoding_person (self):
- return self.get_encoding_information ('encoder')
- def get_encoding_description (self):
- return self.get_encoding_information ('encoding-description')
-
- def get_encoding_software_list (self):
- enc = self.get_named_children ('encoding')
+ def get_encoding_software(self):
+ return self.get_encoding_information('software')
+
+ def get_encoding_date(self):
+ return self.get_encoding_information('encoding-date')
+
+ def get_encoding_person(self):
+ return self.get_encoding_information('encoder')
+
+ def get_encoding_description(self):
+ return self.get_encoding_information('encoding-description')
+
+ def get_encoding_software_list(self):
+ enc = self.get_named_children('encoding')
software = []
for e in enc:
- softwares = e.get_named_children ('software')
+ softwares = e.get_named_children('software')
for s in softwares:
- software.append (s.get_text ())
+ software.append(s.get_text())
return software
- def get_file_description (self):
- misc = self.get_named_children ('miscellaneous')
+ def get_file_description(self):
+ misc = self.get_named_children('miscellaneous')
for m in misc:
- misc_fields = m.get_named_children ('miscellaneous-field')
+ misc_fields = m.get_named_children('miscellaneous-field')
for mf in misc_fields:
- if hasattr (mf, 'name') and mf.name == 'description':
- return mf.get_text ()
+ if hasattr(mf, 'name') and mf.name == 'description':
+ return mf.get_text()
return None
-class Duration (Music_xml_node):
- def get_length (self):
- dur = int (self.get_text ()) * Rational (1,4)
+
+class Credit(Xml_node):
+
+ def get_type(self):
+ type = self.get_maybe_exist_named_child('credit-type')
+ if(type != None):
+ return type.get_text()
+ else:
+ return None
+
+ def find_type(self, credits):
+ sizes = self.get_font_sizes(credits)
+ sizes.sort(reverse=True)
+ ys = self.get_default_ys(credits)
+ ys.sort(reverse=True)
+ xs = self.get_default_xs(credits)
+ xs.sort(reverse=True)
+
+ # Words child of the self credit-element
+ words = self.get_maybe_exist_named_child('credit-words')
+ size = None
+ x = None
+ y = None
+ halign = None
+ valign = None
+ justify = None
+ if(words != None):
+ if hasattr(words, 'font-size'):
+ size = utilities.string_to_integer(getattr(words, 'font-size'))
+ if hasattr(words, 'default-x'):
+ x = round(float(getattr(words, 'default-x')))
+ if hasattr(words, 'default-y'):
+ y = round(float(getattr(words, 'default-y')))
+ if hasattr(words, 'halign'):
+ halign = getattr(words, 'halign')
+ if hasattr(words, 'valign'):
+ valign = getattr(words, 'valign')
+ if hasattr(words, 'justify'):
+ justify = getattr(words, 'justify')
+ if(size and size == max(sizes) and y and y == max(ys) and(justify or halign) and(justify == 'center' or halign == 'center')):
+ return 'title'
+ elif((y and y > min(ys) and y < max(ys)) and((justify or halign) and(justify == 'center' or halign == 'center'))):
+ return 'subtitle'
+ elif((justify or halign) and(justify == 'left' or halign == 'left') and(not(x) or x == min(xs))):
+ return 'lyricist'
+ elif((justify or halign) and(justify == 'right' or halign == 'right') and(not(x) or x == max(xs))):
+ return 'composer'
+ elif(size and size == min(sizes) and y == min(ys)):
+ return 'rights'
+ # Special cases for Finale NotePad
+ elif((valign and(valign == 'top')) and(y and y == ys[1])):
+ return 'subtitle'
+ elif((valign and(valign == 'top')) and(x and x == min(xs))):
+ return 'lyricist'
+ elif((valign and(valign == 'top')) and(y and y == min(ys))):
+ return 'rights'
+ # Other special cases
+ elif((valign and(valign == 'bottom'))):
+ return 'rights'
+ elif(len([item for item in range(len(ys)) if ys[item] == y]) == 2):
+ # The first one is the composer, the second one is the lyricist
+ return 'composer'
+
+ return None # no type recognized
+
+ def get_font_sizes(self, credits):
+ sizes = []
+ for cred in credits:
+ words = cred.get_maybe_exist_named_child('credit-words')
+ if((words != None) and hasattr(words, 'font-size')):
+ sizes.append(getattr(words, 'font-size'))
+ return map(utilities.string_to_integer, sizes)
+
+ def get_default_xs(self, credits):
+ default_xs = []
+ for cred in credits:
+ words = cred.get_maybe_exist_named_child('credit-words')
+ if((words != None) and hasattr(words, 'default-x')):
+ default_xs.append(getattr(words, 'default-x'))
+ return map(round, map(float, default_xs))
+
+ def get_default_ys(self, credits):
+ default_ys = []
+ for cred in credits:
+ words = cred.get_maybe_exist_named_child('credit-words')
+ if((words != None) and hasattr(words, 'default-y')):
+ default_ys.append(getattr(words, 'default-y'))
+ return map(round, map(float, default_ys))
+
+ def get_text(self):
+ words = self.get_maybe_exist_named_child('credit-words')
+ if(words != None):
+ return words.get_text()
+ else:
+ return ''
+
+
+class Duration(Music_xml_node):
+
+ def get_length(self):
+ dur = int(self.get_text()) * Rational(1, 4)
return dur
-class Hash_comment (Music_xml_node):
- pass
-class Hash_text (Music_xml_node):
- def dump (self, indent = ''):
- ly.debug_output ('%s' % string.strip (self._data))
-
-class Pitch (Music_xml_node):
- def get_step (self):
- ch = self.get_unique_typed_child (get_class (u'step'))
- step = ch.get_text ().strip ()
+
+class Hash_text(Music_xml_node):
+
+ def dump(self, indent=''):
+ ly.debug_output('%s' % string.strip(self._data))
+
+
+class Pitch(Music_xml_node):
+
+ def get_step(self):
+ ch = self.get_unique_typed_child(get_class(u'step'))
+ step = ch.get_text().strip()
return step
- def get_octave (self):
- ch = self.get_unique_typed_child (get_class (u'octave'))
- octave = ch.get_text ().strip ()
- return int (octave)
-
- def get_alteration (self):
- ch = self.get_maybe_exist_typed_child (get_class (u'alter'))
- return interpret_alter_element (ch)
-
-class Unpitched (Music_xml_node):
- def get_step (self):
- ch = self.get_unique_typed_child (get_class (u'display-step'))
- step = ch.get_text ().strip ()
+
+ def get_octave(self):
+ ch = self.get_unique_typed_child(get_class(u'octave'))
+ octave = ch.get_text().strip()
+ return int(octave)
+
+ def get_alteration(self):
+ ch = self.get_maybe_exist_typed_child(get_class(u'alter'))
+ return utilities.interpret_alter_element(ch)
+
+ def to_lily_object(self):
+ p = musicexp.Pitch()
+ p.alteration = self.get_alteration()
+ p.step = musicxml2ly_conversion.musicxml_step_to_lily(self.get_step())
+ p.octave = self.get_octave() - 4
+ return p
+
+
+class Unpitched(Music_xml_node):
+
+ def get_step(self):
+ ch = self.get_unique_typed_child(get_class(u'display-step'))
+ step = ch.get_text().strip()
return step
- def get_octave (self):
- ch = self.get_unique_typed_child (get_class (u'display-octave'))
+ def get_octave(self):
+ ch = self.get_unique_typed_child(get_class(u'display-octave'))
if ch:
- octave = ch.get_text ().strip ()
- return int (octave)
+ octave = ch.get_text().strip()
+ return int(octave)
else:
return None
+ def to_lily_object(self):
+ p = None
+ step = self.get_step()
+ if step:
+ p = musicexp.Pitch()
+ p.step = musicxml2ly_conversion.musicxml_step_to_lily(step)
+ octave = self.get_octave()
+ if octave and p:
+ p.octave = octave - 4
+ return p
+
+
class Measure_element (Music_xml_node):
def get_voice_id (self):
voice = self.get_maybe_exist_named_child ('voice')
else:
return self.voice_id;
- def is_first (self):
- # Look at all measure elements (previously we had self.__class__, which
- # only looked at objects of the same type!
- cn = self._parent.get_typed_children (Measure_element)
- # But only look at the correct voice; But include Attributes, too, which
- # are not tied to any particular voice
- cn = [c for c in cn if (c.get_voice_id () == self.get_voice_id ()) or isinstance (c, Attributes)]
- return cn[0] == self
-class Attributes (Measure_element):
- def __init__ (self):
- Measure_element.__init__ (self)
+class Attributes(Measure_element):
+
+ def __init__(self):
+ Measure_element.__init__(self)
self._dict = {}
self._original_tag = None
self._time_signature_cache = None
- def is_first (self):
- cn = self._parent.get_typed_children (self.__class__)
+ def is_first(self):
+ cn = self._parent.get_typed_children(self.__class__)
if self._original_tag:
return cn[0] == self._original_tag
else:
return cn[0] == self
- def set_attributes_from_previous (self, dict):
- self._dict.update (dict)
+ def set_attributes_from_previous(self, dict):
+ self._dict.update(dict)
- def read_self (self):
- for c in self.get_all_children ():
+ def read_self(self):
+ for c in self.get_all_children():
self._dict[c.get_name()] = c
- def get_named_attribute (self, name):
- return self._dict.get (name)
+ def get_named_attribute(self, name):
+ return self._dict.get(name)
- def single_time_sig_to_fraction (self, sig):
- if len (sig) < 2:
+ def single_time_sig_to_fraction(self, sig):
+ if len(sig) < 2:
return 0
n = 0
for i in sig[0:-1]:
n += i
- return Rational (n, sig[-1])
+ return Rational(n, sig[-1])
- def get_measure_length (self):
- sig = self.get_time_signature ()
- if not sig or len (sig) == 0:
+ def get_measure_length(self):
+ sig = self.get_time_signature()
+ if not sig or len(sig) == 0:
return 1
- if isinstance (sig[0], list):
+ if isinstance(sig[0], list):
# Complex compound time signature
l = 0
for i in sig:
- l += self.single_time_sig_to_fraction (i)
+ l += self.single_time_sig_to_fraction(i)
return l
else:
- # Simple (maybe compound) time signature of the form (beat, ..., type)
- return self.single_time_sig_to_fraction (sig)
+ # Simple(maybe compound) time signature of the form(beat, ..., type)
+ return self.single_time_sig_to_fraction(sig)
return 0
- def get_time_signature (self):
- "Return time sig as a (beat, beat-type) tuple. For compound signatures,"
- "return either (beat, beat,..., beat-type) or ((beat,..., type), "
+ def get_time_signature(self):
+ "Return time sig as a(beat, beat-type) tuple. For compound signatures,"
+ "return either(beat, beat,..., beat-type) or((beat,..., type), "
"(beat,..., type), ...)."
if self._time_signature_cache:
return self._time_signature_cache
try:
- mxl = self.get_named_attribute ('time')
+ mxl = self.get_named_attribute('time')
if not mxl:
return None
- if mxl.get_maybe_exist_named_child ('senza-misura'):
+ if mxl.get_maybe_exist_named_child('senza-misura'):
# TODO: Handle pieces without a time signature!
- ly.warning (_ ("Senza-misura time signatures are not yet supported!"))
- return (4, 4)
+ ly.warning(_("Senza-misura time signatures are not yet supported!"))
+ return(4, 4)
else:
signature = []
current_sig = []
- for i in mxl.get_all_children ():
- if isinstance (i, Beats):
- beats = string.split (i.get_text ().strip (), "+")
- current_sig = [int (j) for j in beats]
- elif isinstance (i, BeatType):
- current_sig.append (int (i.get_text ()))
- signature.append (current_sig)
+ for i in mxl.get_all_children():
+ if isinstance(i, Beats):
+ beats = string.split(i.get_text().strip(), "+")
+ current_sig = [int(j) for j in beats]
+ elif isinstance(i, BeatType):
+ current_sig.append(int(i.get_text()))
+ signature.append(current_sig)
current_sig = []
- if isinstance (signature[0], list) and len (signature) == 1:
+ if isinstance(signature[0], list) and len(signature) == 1:
signature = signature[0]
self._time_signature_cache = signature
return signature
- except (KeyError, ValueError):
- self.message (_ ("Unable to interpret time signature! Falling back to 4/4."))
- return (4, 4)
+ except(KeyError, ValueError):
+ self.message(_("Unable to interpret time signature! Falling back to 4/4."))
+ return(4, 4)
- # returns clef information in the form ("cleftype", position, octave-shift)
- def get_clef_information (self):
+ # returns clef information in the form("cleftype", position, octave-shift)
+ def get_clef_information(self):
clefinfo = ['G', 2, 0]
- mxl = self.get_named_attribute ('clef')
+ mxl = self.get_named_attribute('clef')
if not mxl:
return clefinfo
- sign = mxl.get_maybe_exist_named_child ('sign')
+ sign = mxl.get_maybe_exist_named_child('sign')
if sign:
clefinfo[0] = sign.get_text()
- line = mxl.get_maybe_exist_named_child ('line')
+ line = mxl.get_maybe_exist_named_child('line')
if line:
- clefinfo[1] = string.atoi (line.get_text ())
- octave = mxl.get_maybe_exist_named_child ('clef-octave-change')
+ clefinfo[1] = int(line.get_text())
+ octave = mxl.get_maybe_exist_named_child('clef-octave-change')
if octave:
- clefinfo[2] = string.atoi (octave.get_text ())
+ clefinfo[2] = int(octave.get_text())
return clefinfo
- def get_key_signature (self):
- "return (fifths, mode) tuple if the key signatures is given as "
+ def get_key_signature(self):
+ "return(fifths, mode) tuple if the key signatures is given as "
"major/minor in the Circle of fifths. Otherwise return an alterations"
"list of the form [[step,alter<,octave>], [step,alter<,octave>], ...], "
"where the octave values are optional."
- key = self.get_named_attribute ('key')
+ key = self.get_named_attribute('key')
if not key:
return None
- fifths_elm = key.get_maybe_exist_named_child ('fifths')
+ fifths_elm = key.get_maybe_exist_named_child('fifths')
if fifths_elm:
- mode_node = key.get_maybe_exist_named_child ('mode')
+ mode_node = key.get_maybe_exist_named_child('mode')
mode = None
if mode_node:
- mode = mode_node.get_text ()
+ mode = mode_node.get_text()
if not mode or mode == '':
mode = 'major'
- fifths = int (fifths_elm.get_text ())
+ fifths = int(fifths_elm.get_text())
# TODO: Shall we try to convert the key-octave and the cancel, too?
- return (fifths, mode)
+ return(fifths, mode)
else:
alterations = []
current_step = 0
- for i in key.get_all_children ():
- if isinstance (i, KeyStep):
- current_step = i.get_text ().strip ()
- elif isinstance (i, KeyAlter):
- alterations.append ([current_step, interpret_alter_element (i)])
- elif isinstance (i, KeyOctave):
+ for i in key.get_all_children():
+ if isinstance(i, KeyStep):
+ current_step = i.get_text().strip()
+ elif isinstance(i, KeyAlter):
+ alterations.append([current_step, utilities.interpret_alter_element(i)])
+ elif isinstance(i, KeyOctave):
nr = -1
- if hasattr (i, 'number'):
- nr = int (i.number)
- if (nr > 0) and (nr <= len (alterations)):
+ if hasattr(i, 'number'):
+ nr = int(i.number)
+ if(nr > 0) and(nr <= len(alterations)):
# MusicXML Octave 4 is middle C -> shift to 0
- alterations[nr-1].append (int (i.get_text ())-4)
+ alterations[nr - 1].append(int(i.get_text()) - 4)
else:
- i.message (_ ("Key alteration octave given for a "
- "non-existing alteration nr. %s, available numbers: %s!") % (nr, len(alterations)))
+ i.message(_("Key alteration octave given for a "
+ "non-existing alteration nr. %s, available numbers: %s!") %(nr, len(alterations)))
return alterations
- def get_transposition (self):
- return self.get_named_attribute ('transpose')
+ def get_transposition(self):
+ return self.get_named_attribute('transpose')
+
+
+class Barline(Measure_element):
+
+ def to_lily_object(self):
+ # retval contains all possible markers in the order:
+ # 0..bw_ending, 1..bw_repeat, 2..barline, 3..fw_repeat, 4..fw_ending
+ retval = {}
+ bartype_element = self.get_maybe_exist_named_child("bar-style")
+ repeat_element = self.get_maybe_exist_named_child("repeat")
+ ending_element = self.get_maybe_exist_named_child("ending")
+
+ bartype = None
+ if bartype_element:
+ bartype = bartype_element.get_text()
+
+ if repeat_element and hasattr(repeat_element, 'direction'):
+ repeat = musicxml2ly_conversion.RepeatMarker()
+ repeat.direction = {"forward":-1, "backward": 1}.get(
+ repeat_element.direction, 0)
+
+ if((repeat_element.direction == "forward" and bartype == "heavy-light") or
+ (repeat_element.direction == "backward" and bartype == "light-heavy")):
+ bartype = None
+ if hasattr(repeat_element, 'times'):
+ try:
+ repeat.times = int(repeat_element.times)
+ except ValueError:
+ repeat.times = 2
+ repeat.event = self
+ if repeat.direction == -1:
+ retval[3] = repeat
+ else:
+ retval[1] = repeat
+
+ if ending_element and hasattr(ending_element, 'type'):
+ ending = musicxml2ly_conversion.EndingMarker()
+ ending.direction = {"start":-1, "stop": 1, "discontinue": 1}.get(
+ ending_element.type, 0)
+ ending.event = self
+ if ending.direction == -1:
+ retval[4] = ending
+ else:
+ retval[0] = ending
+ # TODO. ending number=""
-class KeyAlter (Music_xml_node):
- pass
-class KeyStep (Music_xml_node):
- pass
-class KeyOctave (Music_xml_node):
- pass
+ if bartype:
+ b = musicexp.BarLine()
+ b.type = bartype
+ retval[2] = b
+ return retval.values()
-class Barline (Measure_element):
- pass
-class BarStyle (Music_xml_node):
- pass
-class Partial (Measure_element):
- def __init__ (self, partial):
- Measure_element.__init__ (self)
+
+class Partial(Measure_element):
+ def __init__(self, partial):
+ Measure_element.__init__(self)
self.partial = partial
-class Note (Measure_element):
- def __init__ (self):
- Measure_element.__init__ (self)
+
+class Stem(Music_xml_node):
+
+ stem_value_dict = {
+ 'down': 'stemDown',
+ 'up': 'stemUp',
+ 'double': None, # TODO: Implement
+ 'none': 'stemNeutral'
+ }
+
+ def to_stem_event(self):
+ values = []
+ value = self.stem_value_dict.get(self.get_text(), None)
+ stem_value = musicexp.StemEvent()
+ if value:
+ stem_value.value = value
+ values.append(stem_value)
+ return values
+
+ def to_stem_style_event(self):
+ styles = []
+ style_elm = musicexp.StemstyleEvent()
+ if hasattr(self, 'color'):
+ style_elm.color = utilities.hex_to_color(getattr(self, 'color'))
+ if(style_elm.color != None):
+ styles.append(style_elm)
+ return styles
+
+
+class Notehead(Music_xml_node):
+
+ notehead_styles_dict = {
+ 'slash': '\'slash',
+ 'triangle': '\'triangle',
+ 'diamond': '\'diamond',
+ 'square': '\'la', # TODO: Proper squared note head
+ 'cross': None, # TODO: + shaped note head
+ 'x': '\'cross',
+ 'circle-x': '\'xcircle',
+ 'inverted triangle': None, # TODO: Implement
+ 'arrow down': None, # TODO: Implement
+ 'arrow up': None, # TODO: Implement
+ 'slashed': None, # TODO: Implement
+ 'back slashed': None, # TODO: Implement
+ 'normal': None,
+ 'cluster': None, # TODO: Implement
+ 'none': '#f',
+ 'do': '\'do',
+ 're': '\'re',
+ 'mi': '\'mi',
+ 'fa': '\'fa',
+ 'so': None,
+ 'la': '\'la',
+ 'ti': '\'ti',
+ }
+
+ def to_lily_object(self): #function changed: additionally processcolor attribute
+ styles = []
+
+ # Notehead style
+ key = self.get_text().strip()
+ style = self.notehead_styles_dict.get(key, None)
+ event = musicexp.NotestyleEvent()
+ if style:
+ event.style = style
+ if hasattr(self, 'filled'):
+ event.filled =(getattr(self, 'filled') == "yes")
+ if hasattr(self, 'color'):
+ event.color = utilities.hex_to_color(getattr(self, 'color'))
+ if event.style or(event.filled != None) or(event.color != None):
+ styles.append(event)
+ # parentheses
+ if hasattr(self, 'parentheses') and(self.parentheses == "yes"):
+ styles.append(musicexp.ParenthesizeEvent())
+
+ return styles
+
+
+class Note(Measure_element):
+
+ drumtype_dict = {
+ 'Acoustic Snare Drum': 'acousticsnare',
+ 'Side Stick': 'sidestick',
+ 'Open Triangle': 'opentriangle',
+ 'Mute Triangle': 'mutetriangle',
+ 'Tambourine': 'tambourine',
+ 'Bass Drum': 'bassdrum',
+ }
+
+ def __init__(self):
+ Measure_element.__init__(self)
self.instrument_name = ''
self._after_grace = False
- def is_grace (self):
- return self.get_maybe_exist_named_child (u'grace')
- def is_after_grace (self):
+ self._duration = 1
+
+ def is_grace(self):
+ return self.get_maybe_exist_named_child(u'grace')
+
+ def is_after_grace(self):
if not self.is_grace():
return False;
- gr = self.get_maybe_exist_typed_child (Grace)
- return self._after_grace or hasattr (gr, 'steal-time-previous');
+ gr = self.get_maybe_exist_typed_child(Grace)
+ return self._after_grace or hasattr(gr, 'steal-time-previous');
- def get_duration_log (self):
- ch = self.get_maybe_exist_named_child (u'type')
+ def get_duration_log(self):
+ ch = self.get_maybe_exist_named_child(u'type')
if ch:
- log = ch.get_text ().strip()
- return musicxml_duration_to_log (log)
- elif self.get_maybe_exist_named_child (u'grace'):
+ log = ch.get_text().strip()
+ return utilities.musicxml_duration_to_log(log)
+ elif self.get_maybe_exist_named_child(u'grace'):
# FIXME: is it ok to default to eight note for grace notes?
return 3
else:
return None
- def get_duration_info (self):
- log = self.get_duration_log ()
+ def get_duration_info(self):
+ log = self.get_duration_log()
if log != None:
- dots = len (self.get_typed_children (Dot))
- return (log, dots)
+ dots = len(self.get_typed_children(Dot))
+ return(log, dots)
else:
return None
- def get_factor (self):
+ def get_factor(self):
return 1
- def get_pitches (self):
- return self.get_typed_children (get_class (u'pitch'))
+ def get_pitches(self):
+ return self.get_typed_children(get_class(u'pitch'))
+
+ def set_notehead_style(self, event):
+ noteheads = self.get_named_children('notehead')
+ for nh in noteheads:
+ styles = nh.to_lily_object()
+ for style in styles:
+ event.add_associated_event(style)
+
+ def set_stem_directions(self, event):
+ stems = self.get_named_children('stem')
+ for stem in stems:
+ values = stem.to_stem_event()
+ for v in values:
+ event.add_associated_event(v)
+
+ def set_stem_style(self, event):
+ stems = self.get_named_children('stem')
+ for stem in stems:
+ styles = stem.to_stem_style_event()
+ for style in styles:
+ event.add_associated_event(style)
+
+ def initialize_duration(self):
+ from musicxml2ly_conversion import rational_to_lily_duration
+ from musicexp import Duration
+ # if the note has no Type child, then that method returns None. In that case,
+ # use the <duration> tag instead. If that doesn't exist, either -> Error
+ dur = self.get_duration_info()
+ if dur:
+ d = Duration()
+ d.duration_log = dur[0]
+ d.dots = dur[1]
+ # Grace notes by specification have duration 0, so no time modification
+ # factor is possible. It even messes up the output with *0/1
+ if not self.get_maybe_exist_typed_child(Grace):
+ d.factor = self._duration / d.get_length()
+ return d
+ else:
+ if self._duration > 0:
+ return rational_to_lily_duration(self._duration)
+ else:
+ self.message(
+ _("Encountered note at %s without type and duration(=%s)") \
+ %(mxl_note.start, mxl_note._duration))
+ return None
+
+ def initialize_pitched_event(self):
+ mxl_pitch = self.get_maybe_exist_typed_child(Pitch)
+ pitch = mxl_pitch.to_lily_object()
+ event = musicexp.NoteEvent()
+ event.pitch = pitch
+ acc = self.get_maybe_exist_named_child('accidental')
+ if acc:
+ # let's not force accs everywhere.
+ event.cautionary = acc.cautionary
+ # TODO: Handle editorial accidentals
+ # TODO: Handle the level-display setting for displaying brackets/parentheses
+ return event
+
+ def initialize_unpitched_event(self):
+ # Unpitched elements have display-step and can also have
+ # display-octave.
+ unpitched = self.get_maybe_exist_typed_child(Unpitched)
+ event = musicexp.NoteEvent()
+ event.pitch = unpitched.to_lily_object()
+ return event
+
+ def initialize_rest_event(self, convert_rest_positions=True):
+ # rests can have display-octave and display-step, which are
+ # treated like an ordinary note pitch
+ rest = self.get_maybe_exist_typed_child(Rest)
+ event = musicexp.RestEvent()
+ if convert_rest_positions:
+ pitch = rest.to_lily_object()
+ event.pitch = pitch
+ return event
+
+ def initialize_drum_event(self):
+ event = musicexp.NoteEvent()
+ drum_type = self.drumtype_dict.get(self.instrument_name)
+ if drum_type:
+ event.drum_type = drum_type
+ else:
+ self.message(
+ _("drum %s type unknown, please add to instrument_drumtype_dict")
+ % n.instrument_name)
+ event.drum_type = 'acousticsnare'
+ return event
+
+ def to_lily_object(self,
+ convert_stem_directions=True,
+ convert_rest_positions=True):
+ pitch = None
+ duration = None
+ event = None
+
+ if self.get_maybe_exist_typed_child(Pitch):
+ event = self.initialize_pitched_event()
+ elif self.get_maybe_exist_typed_child(Unpitched):
+ event = self.initialize_unpitched_event()
+ elif self.get_maybe_exist_typed_child(Rest):
+ event = self.initialize_rest_event(convert_rest_positions)
+ elif self.instrument_name:
+ event = self.initialize_drum_event()
+ else:
+ self.message(_("cannot find suitable event"))
+
+ if event:
+ event.duration = self.initialize_duration()
+
+ self.set_notehead_style(event)
+ self.set_stem_style(event)
+ if convert_stem_directions:
+ self.set_stem_directions(event)
-class Part_list (Music_xml_node):
- def __init__ (self):
- Music_xml_node.__init__ (self)
+ return event
+
+
+class Part_list(Music_xml_node):
+
+ def __init__(self):
+ Music_xml_node.__init__(self)
self._id_instrument_name_dict = {}
- def generate_id_instrument_dict (self):
+ def generate_id_instrument_dict(self):
## not empty to make sure this happens only once.
mapping = {1: 1}
- for score_part in self.get_named_children ('score-part'):
- for instr in score_part.get_named_children ('score-instrument'):
+ for score_part in self.get_named_children('score-part'):
+ for instr in score_part.get_named_children('score-instrument'):
id = instr.id
- name = instr.get_named_child ("instrument-name")
- mapping[id] = name.get_text ()
+ name = instr.get_named_child("instrument-name")
+ mapping[id] = name.get_text()
self._id_instrument_name_dict = mapping
- def get_instrument (self, id):
+ def get_instrument(self, id):
if not self._id_instrument_name_dict:
self.generate_id_instrument_dict()
- instrument_name = self._id_instrument_name_dict.get (id)
+ instrument_name = self._id_instrument_name_dict.get(id)
if instrument_name:
return instrument_name
else:
- ly.warning (_ ("Unable to find instrument for ID=%s\n") % id)
+ ly.warning(_("Unable to find instrument for ID=%s\n") % id)
return "Grand Piano"
-class Part_group (Music_xml_node):
- pass
-class Score_part (Music_xml_node):
- pass
-class Measure (Music_xml_node):
- def __init__ (self):
- Music_xml_node.__init__ (self)
+class Measure(Music_xml_node):
+
+ def __init__(self):
+ Music_xml_node.__init__(self)
self.partial = 0
- def is_implicit (self):
- return hasattr (self, 'implicit') and self.implicit == 'yes'
- def get_notes (self):
- return self.get_typed_children (get_class (u'note'))
-class Syllabic (Music_xml_node):
- def continued (self):
+ def is_implicit(self):
+ return hasattr(self, 'implicit') and self.implicit == 'yes'
+
+ def get_notes(self):
+ return self.get_typed_children(get_class(u'note'))
+
+
+class Syllabic(Music_xml_node):
+
+ def continued(self):
text = self.get_text()
- return (text == "begin") or (text == "middle")
-class Elision (Music_xml_node):
- pass
-class Extend (Music_xml_node):
- pass
-class Text (Music_xml_node):
- pass
+ return(text == "begin") or(text == "middle")
+
+ def begin(self):
+ return(text == "begin")
+
+ def middle(self):
+ return(text == "middle")
-class Lyric (Music_xml_node):
- def get_number (self):
- if hasattr (self, 'number'):
+ def end(self):
+ return(text == "end")
+
+
+class Lyric(Music_xml_node):
+
+ def number(self):
+ """
+ Return the number attribute(if it exists) of the lyric element.
+
+ @rtype: number
+ @return: The value of the number attribute
+ """
+ if hasattr(self, 'number'):
return self.number
else:
return -1
+
+class Sound(Music_xml_node):
+
+ def get_tempo(self):
+ """
+ Return the tempo attribute(if it exists) of the sound element.
+ This attribute can be used by musicxml2ly for the midi output(see L{musicexp.Score}).
+
+ @rtype: string
+ @return: The value of the tempo attribute
+ """
+ if hasattr(self, 'tempo'):
+ return self.tempo
+ else:
+ return None
+
+
+class Notations(Music_xml_node):
+
+ def get_tie(self):
+ ts = self.get_named_children('tied')
+ starts = [t for t in ts if t.type == 'start']
+ if starts:
+ return starts[0]
+ else:
+ return None
+
+ def get_tuplets(self):
+ return self.get_typed_children(Tuplet)
+
+
+class Time_modification(Music_xml_node):
+
+ def get_fraction(self):
+ b = self.get_maybe_exist_named_child('actual-notes')
+ a = self.get_maybe_exist_named_child('normal-notes')
+ return(int(a.get_text()), int(b.get_text()))
+
+ def get_normal_type(self):
+ tuplet_type = self.get_maybe_exist_named_child('normal-type')
+ if tuplet_type:
+ dots = self.get_named_children('normal-dot')
+ log = utilities.musicxml_duration_to_log(tuplet_type.get_text().strip())
+ return(log , len(dots))
+ else:
+ return None
+
+
+class Accidental(Music_xml_node):
+
+ def __init__(self):
+ Music_xml_node.__init__(self)
+ self.editorial = False
+ self.cautionary = False
+
+
+class Tuplet(Music_xml_spanner):
+
+ def duration_info_from_tuplet_note(self, tuplet_note):
+ tuplet_type = tuplet_note.get_maybe_exist_named_child('tuplet-type')
+ if tuplet_type:
+ dots = tuplet_note.get_named_children('tuplet-dot')
+ log = utilities.musicxml_duration_to_log(tuplet_type.get_text().strip())
+ return(log, len(dots))
+ else:
+ return None
+
+ # Return tuplet note type as(log, dots)
+ def get_normal_type(self):
+ tuplet = self.get_maybe_exist_named_child('tuplet-normal')
+ if tuplet:
+ return self.duration_info_from_tuplet_note(tuplet)
+ else:
+ return None
+
+ def get_actual_type(self):
+ tuplet = self.get_maybe_exist_named_child('tuplet-actual')
+ if tuplet:
+ return self.duration_info_from_tuplet_note(tuplet)
+ else:
+ return None
+
+ def get_tuplet_note_count(self, tuplet_note):
+ if tuplet_note:
+ tuplet_nr = tuplet_note.get_maybe_exist_named_child('tuplet-number')
+ if tuplet_nr:
+ return int(tuplet_nr.get_text())
+ return None
+
+ def get_normal_nr(self):
+ return self.get_tuplet_note_count(self.get_maybe_exist_named_child('tuplet-normal'))
+
+ def get_actual_nr(self):
+ return self.get_tuplet_note_count(self.get_maybe_exist_named_child('tuplet-actual'))
+
+
+class Slur(Music_xml_spanner):
+
+ def get_type(self):
+ return self.type
+
+
+class Tied(Music_xml_spanner):
+
+ def get_type(self):
+ return self.type
+
+
+class Beam(Music_xml_spanner):
+ def get_type(self):
+ return self.get_text()
+ def is_primary(self):
+ if hasattr(self, 'number'):
+ return self.number == "1"
+ else:
+ return True
+
+class Octave_shift(Music_xml_spanner):
+ # default is 8 for the octave-shift!
+ def get_size(self):
+ if hasattr(self, 'size'):
+ return int(self.size)
+ else:
+ return 8
+
+
+# Rests in MusicXML are <note> blocks with a <rest> inside. This class is only
+# for the inner <rest> element, not the whole rest block.
+class Rest(Music_xml_node):
+
+ def __init__(self):
+ Music_xml_node.__init__(self)
+ self._is_whole_measure = False
+
+ def is_whole_measure(self):
+ return self._is_whole_measure
+
+ def get_step(self):
+ ch = self.get_maybe_exist_typed_child(get_class(u'display-step'))
+ if ch:
+ return ch.get_text().strip()
+ else:
+ return None
+
+ def get_octave(self):
+ ch = self.get_maybe_exist_typed_child(get_class(u'display-octave'))
+ if ch:
+ oct = ch.get_text().strip()
+ return int(oct)
+ else:
+ return None
+
+ def to_lily_object(self):
+ p = None
+ step = self.get_step()
+ if step:
+ p = musicexp.Pitch()
+ p.step = musicxml2ly_conversion.musicxml_step_to_lily(step)
+ octave = self.get_octave()
+ if octave and p:
+ p.octave = octave - 4
+ return p
+
+
+class Bend(Music_xml_node):
+
+ def bend_alter(self):
+ alter = self.get_maybe_exist_named_child('bend-alter')
+ return utilities.interpret_alter_element(alter)
+
+
+class ChordPitch(Music_xml_node):
+
+ def step_class_name(self):
+ return u'root-step'
+
+ def alter_class_name(self):
+ return u'root-alter'
+
+ def get_step(self):
+ ch = self.get_unique_typed_child(get_class(self.step_class_name()))
+ return ch.get_text().strip()
+
+ def get_alteration(self):
+ ch = self.get_maybe_exist_typed_child(get_class(self.alter_class_name()))
+ return utilities.interpret_alter_element(ch)
+
+
+class Bass(ChordPitch):
+
+ def step_class_name(self):
+ return u'bass-step'
+
+ def alter_class_name(self):
+ return u'bass-alter'
+
+
+class ChordModification(Music_xml_node):
+
+ def get_type(self):
+ ch = self.get_maybe_exist_typed_child(get_class(u'degree-type'))
+ return {'add': 1, 'alter': 1, 'subtract':-1}.get(ch.get_text().strip(), 0)
+
+ def get_value(self):
+ ch = self.get_maybe_exist_typed_child(get_class(u'degree-value'))
+ value = 0
+ if ch:
+ value = int(ch.get_text().strip())
+ return value
+
+ def get_alter(self):
+ ch = self.get_maybe_exist_typed_child(get_class(u'degree-alter'))
+ return utilities.interpret_alter_element(ch)
+
+
+class Frame(Music_xml_node):
+
+ def get_frets(self):
+ return self.get_named_child_value_number('frame-frets', 4)
+
+ def get_strings(self):
+ return self.get_named_child_value_number('frame-strings', 6)
+
+ def get_first_fret(self):
+ return self.get_named_child_value_number('first-fret', 1)
+
+
+class Frame_Note(Music_xml_node):
+
+ def get_string(self):
+ return self.get_named_child_value_number('string', 1)
+
+ def get_fret(self):
+ return self.get_named_child_value_number('fret', 0)
+
+ def get_fingering(self):
+ return self.get_named_child_value_number('fingering', -1)
+
+ def get_barre(self):
+ n = self.get_maybe_exist_named_child('barre')
+ if n:
+ return getattr(n, 'type', '')
+ else:
+ return ''
+
+
class Musicxml_voice:
- def __init__ (self):
+
+ def __init__(self):
self._elements = []
self._staves = {}
self._start_staff = None
self._lyrics = []
self._has_lyrics = False
- def add_element (self, e):
- self._elements.append (e)
- if (isinstance (e, Note)
- and e.get_maybe_exist_typed_child (Staff)):
- name = e.get_maybe_exist_typed_child (Staff).get_text ()
+ def add_element(self, e):
+ self._elements.append(e)
+ if(isinstance(e, Note)
+ and e.get_maybe_exist_typed_child(Staff)):
+ name = e.get_maybe_exist_typed_child(Staff).get_text()
- if not self._start_staff and not e.get_maybe_exist_typed_child (Grace):
+ if not self._start_staff and not e.get_maybe_exist_typed_child(Grace):
self._start_staff = name
self._staves[name] = True
- lyrics = e.get_typed_children (Lyric)
+ lyrics = e.get_typed_children(Lyric)
if not self._has_lyrics:
- self.has_lyrics = len (lyrics) > 0
+ self.has_lyrics = len(lyrics) > 0
for l in lyrics:
- nr = l.get_number()
- if (nr > 0) and not (nr in self._lyrics):
- self._lyrics.append (nr)
+ nr = l.number
+ if(nr > 0) and not(nr in self._lyrics):
+ self._lyrics.append(nr)
- def insert (self, idx, e):
- self._elements.insert (idx, e)
+ def insert(self, idx, e):
+ self._elements.insert(idx, e)
- def get_lyrics_numbers (self):
- if (len (self._lyrics) == 0) and self._has_lyrics:
+ def get_lyrics_numbers(self):
+ if(len(self._lyrics) == 0) and self._has_lyrics:
#only happens if none of the <lyric> tags has a number attribute
return [1]
else:
return self._lyrics
-def graces_to_aftergraces (pending_graces):
- for gr in pending_graces:
- gr._when = gr._prev_when
- gr._measure_position = gr._prev_measure_position
- gr._after_grace = True
-
+class Part(Music_xml_node):
-class Part (Music_xml_node):
- def __init__ (self):
- Music_xml_node.__init__ (self)
+ def __init__(self):
+ Music_xml_node.__init__(self)
self._voices = {}
self._staff_attributes_dict = {}
- def get_part_list (self):
+ def get_part_list(self):
n = self
while n and n.get_name() != 'score-partwise':
n = n._parent
- return n.get_named_child ('part-list')
+ return n.get_named_child('part-list')
- def interpret (self):
+ def graces_to_aftergraces(self, pending_graces):
+ for gr in pending_graces:
+ gr._when = gr._prev_when
+ gr._measure_position = gr._prev_measure_position
+ gr._after_grace = True
+
+ def interpret(self):
"""Set durations and starting points."""
"""The starting point of the very first note is 0!"""
- part_list = self.get_part_list ()
+ part_list = self.get_part_list()
- now = Rational (0)
- factor = Rational (1)
+ now = Rational(0)
+ factor = Rational(1)
attributes_dict = {}
attributes_object = None
- measures = self.get_typed_children (Measure)
- last_moment = Rational (-1)
- last_measure_position = Rational (-1)
- measure_position = Rational (0)
+ measures = self.get_typed_children(Measure)
+ last_moment = Rational(-1)
+ last_measure_position = Rational(-1)
+ measure_position = Rational(0)
measure_start_moment = now
is_first_measure = True
previous_measure = None
# implicit measures are used for artificial measures, e.g. when
# a repeat bar line splits a bar into two halves. In this case,
# don't reset the measure position to 0. They are also used for
- # upbeats (initial value of 0 fits these, too).
+ # upbeats(initial value of 0 fits these, too).
# Also, don't reset the measure position at the end of the loop,
- # but rather when starting the next measure (since only then do we
+ # but rather when starting the next measure(since only then do we
# know if the next measure is implicit and continues that measure)
- if not m.is_implicit ():
+ if not m.is_implicit():
# Warn about possibly overfull measures and reset the position
if attributes_object and previous_measure and previous_measure.partial == 0:
- length = attributes_object.get_measure_length ()
+ length = attributes_object.get_measure_length()
new_now = measure_start_moment + length
if now <> new_now:
problem = 'incomplete'
problem = 'overfull'
## only for verbose operation.
if problem <> 'incomplete' and previous_measure:
- previous_measure.message ('%s measure? Expected: %s, Difference: %s' % (problem, now, new_now - now))
+ previous_measure.message('%s measure? Expected: %s, Difference: %s' %(problem, now, new_now - now))
now = new_now
measure_start_moment = now
- measure_position = Rational (0)
+ measure_position = Rational(0)
voice_id = None;
assign_to_next_voice = []
# figured bass has a duration, but applies to the next note
# and should not change the current measure position!
- if isinstance (n, FiguredBass):
- n._divisions = factor.denominator ()
+ if isinstance(n, FiguredBass):
+ n._divisions = factor.denominator()
n._when = now
n._measure_position = measure_position
continue
- if isinstance (n, Hash_text):
+ if isinstance(n, Hash_text):
continue
- dur = Rational (0)
+ dur = Rational(0)
if n.__class__ == Attributes:
- n.set_attributes_from_previous (attributes_dict)
- n.read_self ()
- attributes_dict = n._dict.copy ()
+ n.set_attributes_from_previous(attributes_dict)
+ n.read_self()
+ attributes_dict = n._dict.copy()
attributes_object = n
- factor = Rational (1,
- int (attributes_dict.get ('divisions').get_text ()))
+ factor = Rational(1,
+ int(attributes_dict.get('divisions').get_text()))
- if (n.get_maybe_exist_typed_child (Duration)):
- mxl_dur = n.get_maybe_exist_typed_child (Duration)
- dur = mxl_dur.get_length () * factor
+ if(n.get_maybe_exist_typed_child(Duration)):
+ mxl_dur = n.get_maybe_exist_typed_child(Duration)
+ dur = mxl_dur.get_length() * factor
if n.get_name() == 'backup':
- dur = - dur
+ dur = -dur
# reset all graces before the backup to after-graces:
- graces_to_aftergraces (pending_graces)
+ self.graces_to_aftergraces(pending_graces)
pending_graces = []
- if n.get_maybe_exist_typed_child (Grace):
- dur = Rational (0)
+ if n.get_maybe_exist_typed_child(Grace):
+ dur = Rational(0)
- rest = n.get_maybe_exist_typed_child (Rest)
- if (rest
+ rest = n.get_maybe_exist_typed_child(Rest)
+ if(rest
and attributes_object
- and attributes_object.get_measure_length () == dur):
+ and attributes_object.get_measure_length() == dur):
rest._is_whole_measure = True
- if (dur > Rational (0)
- and n.get_maybe_exist_typed_child (Chord)):
+ if(dur > Rational(0)
+ and n.get_maybe_exist_typed_child(Chord)):
now = last_moment
measure_position = last_measure_position
# For all grace notes, store the previous note, in case need
# to turn the grace note into an after-grace later on!
- if isinstance(n, Note) and n.is_grace ():
+ if isinstance(n, Note) and n.is_grace():
n._prev_when = last_moment
n._prev_measure_position = last_measure_position
# After-graces are placed at the same position as the previous note
- if isinstance(n, Note) and n.is_after_grace ():
+ if isinstance(n, Note) and n.is_after_grace():
# TODO: We should do the same for grace notes at the end of
# a measure with no following note!!!
n._when = last_moment
n._measure_position = last_measure_position
- elif isinstance(n, Note) and n.is_grace ():
- pending_graces.append (n)
- elif (dur > Rational (0)):
+ elif isinstance(n, Note) and n.is_grace():
+ pending_graces.append(n)
+ elif(dur > Rational(0)):
pending_graces = [];
n._duration = dur
- if dur > Rational (0):
+ if dur > Rational(0):
last_moment = now
last_measure_position = measure_position
now += dur
measure_position += dur
- elif dur < Rational (0):
+ elif dur < Rational(0):
# backup element, reset measure position
now += dur
measure_position += dur
last_moment = now
last_measure_position = measure_position
if n._name == 'note':
- instrument = n.get_maybe_exist_named_child ('instrument')
+ instrument = n.get_maybe_exist_named_child('instrument')
if instrument:
- n.instrument_name = part_list.get_instrument (instrument.id)
+ n.instrument_name = part_list.get_instrument(instrument.id)
# reset all graces at the end of the measure to after-graces:
- graces_to_aftergraces (pending_graces)
+ self.graces_to_aftergraces(pending_graces)
pending_graces = []
# Incomplete first measures are not padded, but registered as partial
if is_first_measure:
is_first_measure = False
# upbeats are marked as implicit measures
- if attributes_object and m.is_implicit ():
- length = attributes_object.get_measure_length ()
+ if attributes_object and m.is_implicit():
+ length = attributes_object.get_measure_length()
measure_end = measure_start_moment + length
if measure_end <> now:
m.partial = now
previous_measure = m
# modify attributes so that only those applying to the given staff remain
- def extract_attributes_for_staff (part, attr, staff):
- attributes = copy.copy (attr)
+ def extract_attributes_for_staff(part, attr, staff):
+ attributes = copy.copy(attr)
attributes._children = [];
- attributes._dict = attr._dict.copy ()
+ attributes._dict = attr._dict.copy()
attributes._original_tag = attr
# copy only the relevant children over for the given staff
if staff == "None":
staff = "1"
for c in attr._children:
- if (not (hasattr (c, 'number') and (c.number != staff)) and
- not (isinstance (c, Hash_text))):
- attributes._children.append (c)
+ if(not(hasattr(c, 'number') and(c.number != staff)) and
+ not(isinstance(c, Hash_text))):
+ attributes._children.append(c)
if not attributes._children:
return None
else:
return attributes
- def extract_voices (part):
+ def extract_voices(part):
+ # The last indentified voice
+ last_voice = None
+
voices = {}
- measures = part.get_typed_children (Measure)
+ measures = part.get_typed_children(Measure)
elements = []
for m in measures:
if m.partial > 0:
- elements.append (Partial (m.partial))
- elements.extend (m.get_all_children ())
+ elements.append(Partial(m.partial))
+ elements.extend(m.get_all_children())
# make sure we know all voices already so that dynamics, clefs, etc.
# can be assigned to the correct voices
voice_to_staff_dict = {}
for n in elements:
- voice_id = n.get_maybe_exist_named_child (u'voice')
+ voice_id = n.get_maybe_exist_named_child(u'voice')
vid = None
if voice_id:
- vid = voice_id.get_text ()
- elif isinstance (n, Note):
+ vid = voice_id.get_text()
+ elif isinstance(n, Note):
# TODO: Check whether we shall really use "None" here, or
# rather use "1" as the default?
- vid = "None"
+ if n.get_maybe_exist_named_child(u'chord'):
+ vid = last_voice
+ else:
+ vid = "1"
+
+ if(vid != None):
+ last_voice = vid
- staff_id = n.get_maybe_exist_named_child (u'staff')
+ staff_id = n.get_maybe_exist_named_child(u'staff')
sid = None
if staff_id:
- sid = staff_id.get_text ()
+ sid = staff_id.get_text()
else:
# TODO: Check whether we shall really use "None" here, or
# rather use "1" as the default?
# If this is changed, need to change the corresponding
# check in extract_attributes_for_staff, too.
sid = "None"
- if vid and not voices.has_key (vid):
+ if vid and not voices.has_key(vid):
voices[vid] = Musicxml_voice()
- if vid and sid and not n.get_maybe_exist_typed_child (Grace):
- if not voice_to_staff_dict.has_key (vid):
+ if vid and sid and not n.get_maybe_exist_typed_child(Grace):
+ if not voice_to_staff_dict.has_key(vid):
voice_to_staff_dict[vid] = sid
- # invert the voice_to_staff_dict into a staff_to_voice_dict (since we
+
+ # invert the voice_to_staff_dict into a staff_to_voice_dict(since we
# need to assign staff-assigned objects like clefs, times, etc. to
# all the correct voices. This will never work entirely correct due
# to staff-switches, but that's the best we can do!
staff_to_voice_dict = {}
- for (v,s) in voice_to_staff_dict.items ():
- if not staff_to_voice_dict.has_key (s):
+ for(v, s) in voice_to_staff_dict.items():
+ if not staff_to_voice_dict.has_key(s):
staff_to_voice_dict[s] = [v]
else:
- staff_to_voice_dict[s].append (v)
-
+ staff_to_voice_dict[s].append(v)
start_attr = None
assign_to_next_note = []
id = None
for n in elements:
- voice_id = n.get_maybe_exist_typed_child (get_class ('voice'))
+ voice_id = n.get_maybe_exist_typed_child(get_class('voice'))
if voice_id:
- id = voice_id.get_text ()
+ id = voice_id.get_text()
else:
- id = "None"
+ if n.get_maybe_exist_typed_child(get_class('chord')):
+ id = last_voice
+ else:
+ id = "1"
+
+ if(id != "None"):
+ last_voice = id
# We don't need backup/forward any more, since we have already
# assigned the correct onset times.
# TODO: Let Grouping through. Also: link, print, bokmark sound
- if not (isinstance (n, Note) or isinstance (n, Attributes) or
- isinstance (n, Direction) or isinstance (n, Partial) or
- isinstance (n, Barline) or isinstance (n, Harmony) or
- isinstance (n, FiguredBass) or isinstance (n, Print)):
+ if not(isinstance(n, Note) or isinstance(n, Attributes) or
+ isinstance(n, Direction) or isinstance(n, Partial) or
+ isinstance(n, Barline) or isinstance(n, Harmony) or
+ isinstance(n, FiguredBass) or isinstance(n, Print)):
continue
- if isinstance (n, Attributes) and not start_attr:
+ if isinstance(n, Attributes) and not start_attr:
start_attr = n
continue
- if isinstance (n, Attributes):
+ if isinstance(n, Attributes):
# assign these only to the voices they really belong to!
- for (s, vids) in staff_to_voice_dict.items ():
- staff_attributes = part.extract_attributes_for_staff (n, s)
+ for(s, vids) in staff_to_voice_dict.items():
+ staff_attributes = part.extract_attributes_for_staff(n, s)
if staff_attributes:
for v in vids:
- voices[v].add_element (staff_attributes)
+ voices[v].add_element(staff_attributes)
continue
- if isinstance (n, Partial) or isinstance (n, Barline) or isinstance (n, Print):
- for v in voices.keys ():
- voices[v].add_element (n)
+ if isinstance(n, Partial) or isinstance(n, Barline) or isinstance(n, Print):
+ for v in voices.keys():
+ voices[v].add_element(n)
continue
- if isinstance (n, Direction):
- if (n.voice_id):
- voices[n.voice_id].add_element (n)
+ if isinstance(n, Direction):
+ staff_id = n.get_maybe_exist_named_child(u'staff')
+ if staff_id:
+ staff_id = staff_id.get_text()
+ if staff_id:
+ dir_voices = staff_to_voice_dict.get(staff_id, voices.keys())
else:
- assign_to_next_note.append (n)
+ dir_voices = voices.keys()
+ for v in dir_voices:
+ voices[v].add_element(n)
continue
- if isinstance (n, Harmony) or isinstance (n, FiguredBass):
+ if isinstance(n, Harmony) or isinstance(n, FiguredBass):
# store the harmony or figured bass element until we encounter
# the next note and assign it only to that one voice.
- assign_to_next_note.append (n)
+ assign_to_next_note.append(n)
continue
- if hasattr (n, 'print-object') and getattr (n, 'print-object') == "no":
+ if hasattr(n, 'print-object') and getattr(n, 'print-object') == "no":
#Skip this note.
pass
else:
for i in assign_to_next_note:
- voices[id].add_element (i)
+ voices[id].add_element(i)
assign_to_next_note = []
- voices[id].add_element (n)
+ voices[id].add_element(n)
# Assign all remaining elements from assign_to_next_note to the voice
# of the previous note:
for i in assign_to_next_note:
- voices[id].add_element (i)
+ voices[id].add_element(i)
assign_to_next_note = []
if start_attr:
- for (s, vids) in staff_to_voice_dict.items ():
- staff_attributes = part.extract_attributes_for_staff (start_attr, s)
- staff_attributes.read_self ()
+ for(s, vids) in staff_to_voice_dict.items():
+ staff_attributes = part.extract_attributes_for_staff(start_attr, s)
+ staff_attributes.read_self()
part._staff_attributes_dict[s] = staff_attributes
for v in vids:
- voices[v].insert (0, staff_attributes)
+ voices[v].insert(0, staff_attributes)
voices[v]._elements[0].read_self()
part._voices = voices
- def get_voices (self):
+ def get_voices(self):
return self._voices
- def get_staff_attributes (self):
- return self._staff_attributes_dict
-
-class Notations (Music_xml_node):
- def get_tie (self):
- ts = self.get_named_children ('tied')
- starts = [t for t in ts if t.type == 'start']
- if starts:
- return starts[0]
- else:
- return None
-
- def get_tuplets (self):
- return self.get_typed_children (Tuplet)
-
-class Time_modification(Music_xml_node):
- def get_fraction (self):
- b = self.get_maybe_exist_named_child ('actual-notes')
- a = self.get_maybe_exist_named_child ('normal-notes')
- return (int(a.get_text ()), int (b.get_text ()))
-
- def get_normal_type (self):
- tuplet_type = self.get_maybe_exist_named_child ('normal-type')
- if tuplet_type:
- dots = self.get_named_children ('normal-dot')
- log = musicxml_duration_to_log (tuplet_type.get_text ().strip ())
- return (log , len (dots))
- else:
- return None
+ def get_staff_attributes(self):
+ return self._staff_attributes_dict
-class Accidental (Music_xml_node):
- def __init__ (self):
- Music_xml_node.__init__ (self)
- self.editorial = False
- self.cautionary = False
-
-class Music_xml_spanner (Music_xml_node):
- def get_type (self):
- if hasattr (self, 'type'):
- return self.type
- else:
- return 0
- def get_size (self):
- if hasattr (self, 'size'):
- return string.atoi (self.size)
- else:
- return 0
-class Wedge (Music_xml_spanner):
+class BarStyle(Music_xml_node):
pass
-class Tuplet (Music_xml_spanner):
- def duration_info_from_tuplet_note (self, tuplet_note):
- tuplet_type = tuplet_note.get_maybe_exist_named_child ('tuplet-type')
- if tuplet_type:
- dots = tuplet_note.get_named_children ('tuplet-dot')
- log = musicxml_duration_to_log (tuplet_type.get_text ().strip ())
- return (log, len (dots))
- else:
- return None
-
- # Return tuplet note type as (log, dots)
- def get_normal_type (self):
- tuplet = self.get_maybe_exist_named_child ('tuplet-normal')
- if tuplet:
- return self.duration_info_from_tuplet_note (tuplet)
- else:
- return None
+class BeatType(Music_xml_node):
+ pass
- def get_actual_type (self):
- tuplet = self.get_maybe_exist_named_child ('tuplet-actual')
- if tuplet:
- return self.duration_info_from_tuplet_note (tuplet)
- else:
- return None
+class BeatUnit(Music_xml_node):
+ pass
- def get_tuplet_note_count (self, tuplet_note):
- if tuplet_note:
- tuplet_nr = tuplet_note.get_maybe_exist_named_child ('tuplet-number')
- if tuplet_nr:
- return int (tuplet_nr.get_text ())
- return None
- def get_normal_nr (self):
- return self.get_tuplet_note_count (self.get_maybe_exist_named_child ('tuplet-normal'))
- def get_actual_nr (self):
- return self.get_tuplet_note_count (self.get_maybe_exist_named_child ('tuplet-actual'))
+class BeatUnitDot(Music_xml_node):
+ pass
-class Bracket (Music_xml_spanner):
+class Beats(Music_xml_node):
pass
-class Dashes (Music_xml_spanner):
+class Bracket(Music_xml_spanner):
pass
-class Slur (Music_xml_spanner):
- def get_type (self):
- return self.type
+class Chord(Music_xml_node):
+ pass
-class Beam (Music_xml_spanner):
- def get_type (self):
- return self.get_text ()
- def is_primary (self):
- if hasattr (self, 'number'):
- return self.number == "1"
- else:
- return True
+class Dashes(Music_xml_spanner):
+ pass
-class Wavy_line (Music_xml_spanner):
+class DirType(Music_xml_node):
pass
-class Pedal (Music_xml_spanner):
+class Direction(Music_xml_node):
pass
-class Glissando (Music_xml_spanner):
+class Dot(Music_xml_node):
pass
-class Slide (Music_xml_spanner):
+class Elision(Music_xml_node):
pass
-class Octave_shift (Music_xml_spanner):
- # default is 8 for the octave-shift!
- def get_size (self):
- if hasattr (self, 'size'):
- return string.atoi (self.size)
- else:
- return 8
+class Extend(Music_xml_node):
+ pass
-class Chord (Music_xml_node):
+class FiguredBass(Music_xml_node):
pass
-class Dot (Music_xml_node):
+class Glissando(Music_xml_spanner):
pass
-# Rests in MusicXML are <note> blocks with a <rest> inside. This class is only
-# for the inner <rest> element, not the whole rest block.
-class Rest (Music_xml_node):
- def __init__ (self):
- Music_xml_node.__init__ (self)
- self._is_whole_measure = False
- def is_whole_measure (self):
- return self._is_whole_measure
- def get_step (self):
- ch = self.get_maybe_exist_typed_child (get_class (u'display-step'))
- if ch:
- return ch.get_text ().strip ()
- else:
- return None
- def get_octave (self):
- ch = self.get_maybe_exist_typed_child (get_class (u'display-octave'))
- if ch:
- oct = ch.get_text ().strip ()
- return int (oct)
- else:
- return None
+class Grace(Music_xml_node):
+ pass
-class Type (Music_xml_node):
+class Harmony(Music_xml_node):
pass
-class Grace (Music_xml_node):
+
+class Hash_comment(Music_xml_node):
pass
-class Staff (Music_xml_node):
+
+class KeyAlter(Music_xml_node):
pass
class Direction (Measure_element):
pass
-class DirType (Music_xml_node):
+
+class KeyOctave(Music_xml_node):
pass
-class Bend (Music_xml_node):
- def bend_alter (self):
- alter = self.get_maybe_exist_named_child ('bend-alter')
- return interpret_alter_element (alter)
+class KeyStep(Music_xml_node):
+ pass
-class Words (Music_xml_node):
+class Part_group(Music_xml_node):
pass
-class Harmony (Music_xml_node):
+class Pedal(Music_xml_spanner):
pass
-class ChordPitch (Music_xml_node):
- def step_class_name (self):
- return u'root-step'
- def alter_class_name (self):
- return u'root-alter'
- def get_step (self):
- ch = self.get_unique_typed_child (get_class (self.step_class_name ()))
- return ch.get_text ().strip ()
- def get_alteration (self):
- ch = self.get_maybe_exist_typed_child (get_class (self.alter_class_name ()))
- return interpret_alter_element (ch)
-
-class Root (ChordPitch):
+class PerMinute(Music_xml_node):
pass
-class Bass (ChordPitch):
- def step_class_name (self):
- return u'bass-step'
- def alter_class_name (self):
- return u'bass-alter'
+class Print(Music_xml_node):
+ pass
-class ChordModification (Music_xml_node):
- def get_type (self):
- ch = self.get_maybe_exist_typed_child (get_class (u'degree-type'))
- return {'add': 1, 'alter': 1, 'subtract': -1}.get (ch.get_text ().strip (), 0)
- def get_value (self):
- ch = self.get_maybe_exist_typed_child (get_class (u'degree-value'))
- value = 0
- if ch:
- value = int (ch.get_text ().strip ())
- return value
- def get_alter (self):
- ch = self.get_maybe_exist_typed_child (get_class (u'degree-alter'))
- return interpret_alter_element (ch)
-
-
-class Frame (Music_xml_node):
- def get_frets (self):
- return self.get_named_child_value_number ('frame-frets', 4)
- def get_strings (self):
- return self.get_named_child_value_number ('frame-strings', 6)
- def get_first_fret (self):
- return self.get_named_child_value_number ('first-fret', 1)
-
-class Frame_Note (Music_xml_node):
- def get_string (self):
- return self.get_named_child_value_number ('string', 1)
- def get_fret (self):
- return self.get_named_child_value_number ('fret', 0)
- def get_fingering (self):
- return self.get_named_child_value_number ('fingering', -1)
- def get_barre (self):
- n = self.get_maybe_exist_named_child ('barre')
- if n:
- return getattr (n, 'type', '')
- else:
- return ''
+class Root(ChordPitch):
+ pass
-class FiguredBass (Music_xml_node):
+class Score_part(Music_xml_node):
pass
-class Beats (Music_xml_node):
+class Slide(Music_xml_spanner):
pass
-class BeatType (Music_xml_node):
+class Staff(Music_xml_node):
pass
-class BeatUnit (Music_xml_node):
+class Text(Music_xml_node):
pass
-class BeatUnitDot (Music_xml_node):
+class Type(Music_xml_node):
pass
-class PerMinute (Music_xml_node):
+class Wavy_line(Music_xml_spanner):
pass
-class Print (Music_xml_node):
+class Wedge(Music_xml_spanner):
pass
+class Words(Music_xml_node):
+ pass
## need this, not all classes are instantiated
'bend' : Bend,
'bracket' : Bracket,
'chord': Chord,
+ 'credit': Credit,
'dashes' : Dashes,
'degree' : ChordModification,
'dot': Dot,
'measure': Measure,
'notations': Notations,
'note': Note,
+ 'notehead': Notehead,
'octave-shift': Octave_shift,
'part': Part,
- 'part-group': Part_group,
+ 'part-group': Part_group,
'part-list': Part_list,
'pedal': Pedal,
'per-minute': PerMinute,
'score-part': Score_part,
'slide': Slide,
'slur': Slur,
+ 'sound': Sound,
'staff': Staff,
+ 'stem': Stem,
'syllabic': Syllabic,
'text': Text,
'time-modification': Time_modification,
+ 'tied': Tied,
'tuplet': Tuplet,
'type': Type,
'unpitched': Unpitched,
'work': Work,
}
-def name2class_name (name):
- name = name.replace ('-', '_')
- name = name.replace ('#', 'hash_')
+def name2class_name(name):
+ name = name.replace('-', '_')
+ name = name.replace('#', 'hash_')
name = name[0].upper() + name[1:].lower()
- return str (name)
+ return str(name)
-def get_class (name):
- classname = class_dict.get (name)
+def get_class(name):
+ classname = class_dict.get(name)
if classname:
return classname
else:
- class_name = name2class_name (name)
- klass = new.classobj (class_name, (Music_xml_node,) , {})
+ class_name = name2class_name(name)
+ klass = new.classobj(class_name,(Music_xml_node,) , {})
class_dict[name] = klass
return klass
-def lxml_demarshal_node (node):
+def lxml_demarshal_node(node):
name = node.tag
# Ignore comment nodes, which are also returned by the etree parser!
if name is None or node.__class__.__name__ == "_Comment":
return None
- klass = get_class (name)
+ klass = get_class(name)
py_node = klass()
py_node._original = node
py_node._name = name
py_node._data = node.text
- py_node._children = [lxml_demarshal_node (cn) for cn in node.getchildren()]
- py_node._children = filter (lambda x: x, py_node._children)
+ py_node._children = [lxml_demarshal_node(cn) for cn in node.getchildren()]
+ py_node._children = filter(lambda x: x, py_node._children)
for c in py_node._children:
c._parent = py_node
- for (k, v) in node.items ():
+ for(k, v) in node.items():
py_node.__dict__[k] = v
py_node._attribute_dict[k] = v
return py_node
-def minidom_demarshal_node (node):
+def minidom_demarshal_node(node):
name = node.nodeName
- klass = get_class (name)
- py_node = klass ()
+ klass = get_class(name)
+ py_node = klass()
py_node._name = name
- py_node._children = [minidom_demarshal_node (cn) for cn in node.childNodes]
+ py_node._children = [minidom_demarshal_node(cn) for cn in node.childNodes]
for c in py_node._children:
c._parent = py_node
if node.attributes:
- for (nm, value) in node.attributes.items ():
+ for(nm, value) in node.attributes.items():
py_node.__dict__[nm] = value
py_node._attribute_dict[nm] = value
return py_node
-if __name__ == '__main__':
+if __name__ == '__main__':
import lxml.etree
- tree = lxml.etree.parse ('beethoven.xml')
- mxl_tree = lxml_demarshal_node (tree.getroot ())
- ks = class_dict.keys ()
- ks.sort ()
- print '\n'.join (ks)
+ tree = lxml.etree.parse('beethoven.xml')
+ mxl_tree = lxml_demarshal_node(tree.getroot())
+ ks = class_dict.keys()
+ ks.sort()
+ print '\n'.join(ks)
--- /dev/null
+# -*- coding: utf-8 -*-
+from rational import *
+import lilylib as ly
+import musicexp
+_ = ly._
+
+def rational_to_lily_duration(rational_len):
+ d = musicexp.Duration()
+
+ rational_len.normalize_self()
+ d_log = {1: 0, 2: 1, 4:2, 8:3, 16:4, 32:5, 64:6, 128:7, 256:8, 512:9}.get(rational_len.denominator(), -1)
+
+ # Duration of the form 1/2^n or 3/2^n can be converted to a simple lilypond duration
+ dots = {1: 0, 3: 1, 7: 2, 15: 3, 31: 4, 63: 5, 127: 6}.get(rational_len.numerator(), -1)
+ if(d_log >= dots >= 0):
+ # account for the dots!
+ d.duration_log = d_log - dots
+ d.dots = dots
+ elif(d_log >= 0):
+ d.duration_log = d_log
+ d.factor = Rational(rational_len.numerator())
+ else:
+ ly.warning(_("Encountered rational duration with denominator %s, "
+ "unable to convert to lilypond duration") %
+ rational_len.denominator())
+ # TODO: Test the above error message
+ return None
+
+ return d
+
+def musicxml_step_to_lily(step):
+ if step:
+ return (ord(step) - ord('A') + 7 - 2) % 7
+ else:
+ return None
+
+class Marker(musicexp.Music):
+ def __init__(self):
+ self.direction = 0
+ self.event = None
+ def print_ly(self, printer):
+ ly.warning(_("Encountered unprocessed marker %s\n") % self)
+ pass
+ def ly_expression(self):
+ return ""
+
+class RepeatMarker(Marker):
+ def __init__(self):
+ Marker.__init__(self)
+ self.times = 0
+
+class EndingMarker(Marker):
+ pass
--- /dev/null
+# -*- coding: utf-8 -*-
+import re
+import string
+
+def string_to_number(s):
+ try:
+ return int(s)
+ except ValueError:
+ return float(s)
+
+def string_to_integer(s):
+ num = string_to_number(s)
+ if isinstance(num, int):
+ return num
+ else:
+ return int(num)
+
+def escape_ly_output_string (input_string):
+ return_string = input_string
+ needs_quotes = not re.match (u"^[a-zA-ZäöüÜÄÖßñ]*$", return_string);
+ if needs_quotes:
+ return_string = "\"" + string.replace (return_string, "\"", "\\\"") + "\""
+ return return_string
+
+def interpret_alter_element (alter_elm):
+ alter = 0
+ if alter_elm:
+ val = eval(alter_elm.get_text ())
+ if type (val) in (int, float):
+ alter = val
+ return alter
+
+def musicxml_duration_to_log (dur):
+ return {'256th': 8,
+ '128th': 7,
+ '64th': 6,
+ '32nd': 5,
+ '16th': 4,
+ 'eighth': 3,
+ 'quarter': 2,
+ 'half': 1,
+ 'whole': 0,
+ 'breve':-1,
+ 'longa':-2,
+ 'long':-2}.get (dur, 0)
+
+def hexcolorval_to_nr (hex_val):
+ try:
+ v = int (hex_val, 16)
+ if v == 255:
+ v = 256
+ return v / 256.
+ except ValueError:
+ return 0.
+
+def hex_to_color(hex_val):
+ res = re.match (
+ r'#([0-9a-f][0-9a-f]|)([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$',
+ hex_val,
+ re.IGNORECASE)
+ if res:
+ return map(lambda x: hexcolorval_to_nr (x), res.group (2, 3, 4))
+ else:
+ return None
+
+def split_string_and_preserve_doublequoted_substrings(value):
+ import shlex
+ lex = shlex.shlex(value)
+ lex.quotes = '"'
+ lex.whitespace_split = True
+ lex.commenters = ''
+ return list(lex)
+
+def musicxml_sound_to_lilypond_midi_instrument(sound):
+ sounds = {
+ "brass.french-horn": 'french horn',
+ "brass.group": 'brass section',
+ "brass.group.synth": 'synthbrass 1',
+ "brass.trombone": 'trombone',
+ "brass.trombone.alto": 'trombone',
+ "brass.trombone.bass": 'trombone',
+ "brass.trombone.contrabass": 'trombone',
+ "brass.trombone.tenor": 'trombone',
+ "brass.trumpet": 'trumpet',
+ "brass.trumpet.baroque": 'trumpet',
+ "brass.trumpet.bass": 'trumpet',
+ "brass.trumpet.bflat": 'trumpet',
+ "brass.trumpet.c": 'trumpet',
+ "brass.trumpet.d": 'trumpet',
+ "brass.trumpet.piccolo": 'trumpet',
+ "brass.trumpet.pocket": 'trumpet',
+ "brass.trumpet.slide": 'trumpet',
+ "brass.trumpet.tenor": 'trumpet',
+ "brass.tuba": 'tuba',
+ "brass.tuba.bass": 'tuba',
+ "brass.tuba.subcontrabass": 'tuba',
+ "brass.wagner-tuba": 'french horn',
+ "drum.timpani": 'timpani',
+ "drum.tom-tom": 'melodic tom',
+ "drum.tom-tom.synth": 'synth drum',
+ "effect.applause": 'applause',
+ "effect.bass-string-slap": 'slap bass 1',
+ "effect.bird": 'bird tweet',
+ "effect.bird.tweet": 'bird tweet',
+ "effect.breath": 'breath noise',
+ "effect.guitar-fret": 'guitar fret noise',
+ "effect.gunshot": 'gunshot',
+ "effect.helicopter": 'helicopter',
+ "effect.metronome-click": 'woodblock',
+ "effect.rain": 'fx1 (rain)',
+ "effect.seashore": 'seashore',
+ "effect.telephone-ring": 'telephone ring',
+ "keyboard.accordion": 'accordion',
+ "keyboard.bandoneon": 'accordion',
+ "keyboard.celesta": 'celesta',
+ "keyboard.clavichord": 'clav',
+ "keyboard.concertina": 'concertina',
+ "keyboard.harpsichord": 'harpsichord',
+ "keyboard.ondes-martenot": 'ocarina',
+ "keyboard.organ": 'church organ',
+ "keyboard.organ.drawbar": 'drawbar organ',
+ "keyboard.organ.percussive": 'percussive organ',
+ "keyboard.organ.pipe": 'church organ',
+ "keyboard.organ.reed": 'reed organ',
+ "keyboard.piano": 'acoustic grand',
+ "keyboard.piano.electric": 'electric piano 1',
+ "keyboard.piano.grand": 'acoustic grand',
+ "keyboard.piano.honky-tonk": 'honky-tonk',
+ "metal.bells.agogo": 'agogo',
+ "metal.bells.tinklebell": 'tinkle bell',
+ "metal.cymbal.reverse": 'reverse cymbal',
+ "pitched-percussion.glockenspiel": 'glockenspiel',
+ "pitched-percussion.glockenspiel.alto": 'glockenspiel',
+ "pitched-percussion.glockenspiel.soprano": 'glockenspiel',
+ "pitched-percussion.hammer-dulcimer": 'dulcimer',
+ "pitched-percussion.kalimba": 'kalimba',
+ "pitched-percussion.marimba": 'marimba',
+ "pitched-percussion.marimba.bass": 'marimba',
+ "pitched-percussion.music-box": 'music box',
+ "pitched-percussion.tubular-bells": 'tubular bells',
+ "pitched-percussion.vibraphone": 'vibraphone',
+ "pitched-percussion.xylophone": 'xylophone',
+ "pitched-percussion.xylophone.alto": 'xylophone',
+ "pitched-percussion.xylophone.bass": 'xylophone',
+ "pitched-percussion.xylophone.soprano": 'xylophone',
+ "pitched-percussion.xylorimba": 'xylophone',
+ "pluck.banjo": 'banjo',
+ "pluck.banjo.tenor": 'banjo',
+ "pluck.bass": 'acoustic bass',
+ "pluck.bass.acoustic": 'acoustic bass',
+ "pluck.bass.electric": 'electric bass',
+ "pluck.bass.fretless": 'fretless bass',
+ "pluck.bass.synth": 'synth bass 1',
+ "pluck.dulcimer": 'dulcimer',
+ "pluck.guitar": 'acoustic guitar (nylon)',
+ "pluck.guitar.acoustic": 'acoustic guitar (nylon)',
+ "pluck.guitar.electric": 'electric guitar (jazz)',
+ "pluck.guitar.nylon-string": 'acoustic guitar (nylon)',
+ "pluck.guitar.steel-string": 'acoustic guitar (steel)',
+ "pluck.harp": 'orchestral harp',
+ "pluck.lute": 'acoustic guitar (nylon)',
+ "pluck.shamisen": 'shamisen',
+ "pluck.sitar": 'sitar',
+ "strings.cello": 'cello',
+ "strings.cello.piccolo": 'cello',
+ "strings.contrabass": 'contrabass',
+ "strings.fiddle": 'fiddle',
+ "strings.group.synth": 'synth strings 1',
+ "strings.viola": 'viola',
+ "strings.violin": 'violin',
+ "synth.effects.atmosphere": 'fx 4 (atmosphere)',
+ "synth.effects.brightness": 'fx 5 (brightness)',
+ "synth.effects.crystal": 'fx 3 (crystal)',
+ "synth.effects.echoes": 'fx 7 echoes',
+ "synth.effects.goblins": 'fx 6 goblins',
+ "synth.effects.rain": 'fx 1 rain',
+ "synth.effects.sci-fi": 'fx 8 sci-fi',
+ "synth.effects.soundtrack": 'fx 2 (soundtrack)',
+ "synth.pad.bowed": 'pad 5 bowed',
+ "synth.pad.choir": 'pad 4 choir',
+ "synth.pad.halo": 'pad 7 halo',
+ "synth.pad.metallic": 'pad 6 metallic',
+ "synth.pad.polysynth": 'pad 3 polysynth',
+ "synth.pad.sweep": 'pad 8 sweep',
+ "synth.pad.warm": 'pad 2 warm',
+ "synth.tone.sawtooth": 'lead 1 (square)',
+ "synth.tone.square": 'lead 2 (sawtooth)',
+ "voice.aa": 'choir aahs',
+ "voice.alto": 'choir aahs',
+ "voice.aw": 'choir aahs',
+ "voice.baritone": 'choir aahs',
+ "voice.bass": 'choir aahs',
+ "voice.child": 'choir aahs',
+ "voice.countertenor": 'choir aahs',
+ "voice.doo": 'choir aahs',
+ "voice.ee": 'choir aahs',
+ "voice.female": 'choir aahs',
+ "voice.kazoo": 'choir aahs',
+ "voice.male": 'choir aahs',
+ "voice.mezzo-soprano": 'choir aahs',
+ "voice.mm": 'choir aahs',
+ "voice.oo": 'voice oohs',
+ "voice.soprano": 'choir aahs',
+ "voice.synth": 'synth voice',
+ "wind.flutes.blown-bottle": 'blown bottle',
+ "wind.flutes.calliope": 'lead 3 (calliope)',
+ "wind.flutes.flute": 'flute',
+ "wind.flutes.flute.alto": 'flute',
+ "wind.flutes.flute.bass": 'flute',
+ "wind.flutes.flute.contra-alto": 'flute',
+ "wind.flutes.flute.contrabass": 'flute',
+ "wind.flutes.flute.double-contrabass": 'flute',
+ "wind.flutes.flute.piccolo": 'flute',
+ "wind.flutes.flute.subcontrabass": 'flute',
+ "wind.flutes.ocarina": 'ocarina',
+ "wind.flutes.recorder": 'recorder',
+ "wind.flutes.recorder.alto": 'recorder',
+ "wind.flutes.recorder.bass": 'recorder',
+ "wind.flutes.recorder.contrabass": 'recorder',
+ "wind.flutes.recorder.descant": 'recorder',
+ "wind.flutes.recorder.garklein": 'recorder',
+ "wind.flutes.recorder.great-bass": 'recorder',
+ "wind.flutes.recorder.sopranino": 'recorder',
+ "wind.flutes.recorder.soprano": 'recorder',
+ "wind.flutes.recorder.tenor": 'recorder',
+ "wind.flutes.shakuhachi": 'shakuhachi',
+ "wind.flutes.whistle": 'whistle',
+ "wind.flutes.whistle.alto": 'whistle',
+ "wind.pipes.bagpipes": 'bagpipe',
+ "wind.reed.basset-horn": 'clarinet',
+ "wind.reed.bassoon": 'bassoon',
+ "wind.reed.clarinet": 'clarinet',
+ "wind.reed.clarinet.a": 'clarinet',
+ "wind.reed.clarinet.alto": 'clarinet',
+ "wind.reed.clarinet.bass": 'clarinet',
+ "wind.reed.clarinet.basset": 'clarinet',
+ "wind.reed.clarinet.bflat": 'clarinet',
+ "wind.reed.clarinet.contra-alto": 'clarinet',
+ "wind.reed.clarinet.contrabass": 'clarinet',
+ "wind.reed.clarinet.eflat": 'clarinet',
+ "wind.reed.clarinet.piccolo.aflat": 'clarinet',
+ "wind.reed.contrabass": 'contrabass',
+ "wind.reed.contrabassoon": 'bassoon',
+ "wind.reed.english-horn": 'oboe',
+ "wind.reed.harmonica": 'harmonica',
+ "wind.reed.harmonica.bass": 'harmonica',
+ "wind.reed.oboe": 'oboe',
+ "wind.reed.oboe.bass": 'oboe',
+ "wind.reed.oboe.piccolo": 'oboe',
+ "wind.reed.oboe-da-caccia": 'oboe',
+ "wind.reed.oboe-damore": 'oboe',
+ "wind.reed.saxophone": 'alto sax',
+ "wind.reed.saxophone.alto": 'alto sax',
+ "wind.reed.saxophone.baritone": 'baritone sax',
+ "wind.reed.saxophone.bass": 'baritone sax',
+ "wind.reed.saxophone.contrabass": 'baritone sax',
+ "wind.reed.saxophone.melody": 'soprano sax',
+ "wind.reed.saxophone.mezzo-soprano": 'soprano sax',
+ "wind.reed.saxophone.sopranino": 'soprano sax',
+ "wind.reed.saxophone.sopranissimo": 'soprano sax',
+ "wind.reed.saxophone.soprano": 'soprano, sax',
+ "wind.reed.saxophone.subcontrabass": 'baritone sax',
+ "wind.reed.saxophone.tenor": 'tenor sax',
+ "wind.reed.shenai": 'shanai',
+ "wood.temple-block": 'wood block',
+ "wood.wood-block": 'wood block',
+ }
+ return sounds.get(sound, 'acoustic grand')
;; for define-safe-public when byte-compiling using Guile V2
(use-modules (scm safe-utility-defs) (ice-9 receive))
+(define-session-public chordmodifiers '())
+
(define-public (construct-chord-elements root duration modifications)
"Build a chord on root using modifiers in @var{modifications}.
@code{NoteEvents} have duration @var{duration}.
(if (not (equal? #f (object-property symbol 'translation-doc)))
- (ly:error (_ "symbol ~S redefined" symbol)))
+ (ly:error (_ "symbol ~S redefined") symbol))
(set-object-property! symbol 'translation-type? type?)
(set-object-property! symbol 'translation-doc description)
((ly:make-event-class class)
(ly:error (_ "Cannot redefine event class `~S'") class))
((not parentclass)
- (ly:error (_ "Undefined parent event class `~S'" parentclass)))
+ (ly:error (_ "Undefined parent event class `~S'") parentclass))
(else
(hashq-set! ancestor-lookup
class
(define (pitch= pitch1 pitch2)
(and (= (ly:pitch-notename pitch1) (ly:pitch-notename pitch2))
(= (ly:pitch-alteration pitch1) (ly:pitch-alteration pitch2))))
- (let* ((pitches (ly:parser-lookup 'pitchnames))
- (result (rassoc ly-pitch pitches pitch=)))
+ (let* ((result (rassoc ly-pitch pitchnames pitch=)))
(and result (car result))))
(define-public (octave->lily-string pitch)
num den
(new-line->lily-string))
(format #f
- "\\time #'~a ~a/~a~a"
+ ;; This is silly but the latter will also work for #f
+ ;; and other
+ (if (key-list? structure)
+ "\\time ~{~a~^,~} ~a/~a~a"
+ "\\time #'~a ~a/~a~a")
structure num den
(new-line->lily-string)))))
;;; Variable declaration
-(define-public pitchnames '())
-(define-public default-language "")
-(define-public previous-pitchnames #f)
+(define-session-public pitchnames '())
+(define-session-public default-language "")
+(define-session-public previous-pitchnames #f)
-(define-public language-pitch-names
+;;; A bit out of place, but we don't have a good place elsewhere in
+;;; scm since it is only filled in ly/drumpitch-init.ly and we need it
+;;; in (scm lily) in order to access it in ly/parser.yy.
+(define-session-public drumPitchNames '())
+
+(define-session-public language-pitch-names
`(
;; Language: Nederlands --------------------------------------------;
;; Dutch note names -- LilyPond's default language.
((and file-name (string-endswith downcase-file-name ".ttf"))
(ly:ttf->pfa file-name))
((and file-name (string-endswith downcase-file-name ".ttc"))
- (ly:ttf->pfa file-name font-index))
+ ;; TODO: distinguish files which have extension `*.ttc'
+ ;; whether TrueType Collection (TTC) fonts
+ ;; or OpenType/CFF Collection (OTC) fonts.
+ (ly:ttf->pfa file-name font-index)) ;; TTC fonts
((and file-name (string-endswith downcase-file-name ".otf"))
(ps-embed-cff (ly:otf->cff file-name) name 0))
+ ((and file-name (string-endswith downcase-file-name ".otc"))
+ ;; The files which have the extension `*.otc' are OTC fonts.
+ (ps-embed-cff (ly:otf->cff file-name font-index) name 0)) ;; OTC fonts
(else
(ly:warning (_ "do not know how to embed ~S=~S") name file-name)
""))))
;;
(define lilypond-declarations '())
+(define lilypond-exports '())
(define after-session-hook (make-hook))
(define-public (call-after-session thunk)
(ly:error (_ "call-after-session used after session start")))
(add-hook! after-session-hook thunk #t))
-(defmacro-public define-session (name value)
+(define (make-session-variable name value)
+ (if (ly:undead? lilypond-declarations)
+ (ly:error (_ "define-session used after session start")))
+ (let ((var (module-make-local-var! (current-module) name)))
+ (if (variable-bound? var)
+ (ly:error (_ "symbol ~S redefined") name))
+ (variable-set! var value)
+ var))
+
+(defmacro define-session (name value)
"This defines a variable @var{name} with the starting value
@var{value} that is reinitialized at the start of each session.
A@tie{}session basically corresponds to one LilyPond file on the
them. It is an error to call @code{define-session} after the first
session has started."
(define (add-session-variable name value)
- (if (ly:undead? lilypond-declarations)
- (ly:error (_ "define-session used after session start")))
- (let ((var (make-variable value)))
- (module-add! (current-module) name var)
- (set! lilypond-declarations (cons var lilypond-declarations))))
+ (set! lilypond-declarations
+ (cons (make-session-variable name value) lilypond-declarations)))
`(,add-session-variable ',name ,value))
-(defmacro-public define-session-public (name value)
- "Like @code{define-session}, but also exports @var{name}."
+(defmacro define-session-public (name value)
+ "Like @code{define-session}, but also exports @var{name} into parser modules."
+ (define (add-session-variable name value)
+ (set! lilypond-exports
+ (acons name (make-session-variable name value) lilypond-exports)))
`(begin
- (define-session ,name ,value)
+ ;; this is a bit icky: we place the variable right into every
+ ;; parser module so that both set! and define will affect the
+ ;; original variable in the (lily) module. However, we _also_
+ ;; export it normally from (lily) for the sake of other modules
+ ;; not sharing the name space of the parser.
+ (,add-session-variable ',name ,value)
(export ,name)))
(define (session-terminate)
(module-add! (current-module) (car p) var))))
(ly:get-undead lilypond-declarations)))
(begin
+ ;; import all public session variables natively into parser
+ ;; module. That makes them behave identically under define/set!
+ (for-each (lambda (v)
+ (module-add! (current-module) (car v) (cdr v)))
+ lilypond-exports)
+ ;; Initialize first session
(thunk)
+ ;; lilypond-exports is no longer needed since we will grab its
+ ;; values from (current-module).
+ (set! lilypond-exports #f)
(set! lilypond-interfaces
(filter (lambda (m) (eq? 'interface (module-kind m)))
(module-uses (current-module))))
(ly:in-event-class? cause t))
point-and-click))))
(let* ((location (ly:input-file-line-char-column music-origin))
+ (raw-file (car location))
+ (file (if (is-absolute? raw-file)
+ raw-file
+ (string-append (ly-getcwd) "/" raw-file)))
(x-ext (ly:grob-extent grob grob X))
(y-ext (ly:grob-extent grob grob Y)))
;; Backslashes are not valid
;; file URI path separators.
(ly:string-percent-encode
- (ly:string-substitute "\\" "/" (car location)))
+ (ly:string-substitute "\\" "/" file))
(cadr location)
(caddr location)
(else (any (lambda (t)
(ly:in-event-class? cause t))
point-and-click)))
- (let* ((location (ly:input-file-line-char-column music-origin)))
-
+ (let* ((location (ly:input-file-line-char-column music-origin))
+ (raw-file (car location))
+ (file (if (is-absolute? raw-file)
+ raw-file
+ (string-append (ly-getcwd) "/" raw-file))))
+
(ly:format "<a style=\"color:inherit;\" xlink:href=\"textedit://~a:~a:~a:~a\">\n"
;; Backslashes are not valid
;; file URI path separators.
(ly:string-percent-encode
- (ly:string-substitute "\\" "/" (car location)))
-
+ (ly:string-substitute "\\" "/" file))
+
(cadr location)
(caddr location)
(1+ (cadddr location))))))))
getTrans("PDF of lilypond-book regtests for ", lang)+version)
def make_doctarball_links(name, version, lang):
- url = depth + "download/binaries/documentation/lilypond-"
+ url = depth + "downloads/binaries/documentation/lilypond-"
# ugly FIXME, but proper build number support isn't Critical.
url += version + "-1"
url += ".documentation.tar.bz2"
@relocate-preamble@
"""
-import midi
import lilylib as ly
global _;_=ly._
return dump_track (self.voices, i)
def convert_midi (in_file, out_file):
+ global midi
+ import midi
+
global clocks_per_1, clocks_per_4, key
global start_quant_clocks
global duration_quant_clocks
import zipfile
import tempfile
import StringIO
+import warnings
"""
@relocate-preamble@
import lilylib as ly
_ = ly._
+import utilities
+import musicxml2ly_conversion
import musicxml
import musicexp
from rational import Rational
+lilypond_version = "@TOPLEVEL_VERSION@"
+
# Store command-line options in a global variable, so we can access them everywhere
options = None
class Conversion_Settings:
def __init__(self):
self.ignore_beaming = False
+ self.convert_stem_directions = False
+ self.convert_rest_positions = True
-conversion_settings = Conversion_Settings ()
+conversion_settings = Conversion_Settings()
# Use a global variable to store the setting needed inside a \layout block.
# whenever we need to change a setting or add/remove an engraver, we can access
# this layout and add the corresponding settings
-layout_information = musicexp.Layout ()
+layout_information = musicexp.Layout()
+# Use a global variable to store the setting needed inside a \paper block.
+paper = musicexp.Paper()
needed_additional_definitions = []
additional_definitions = {
-
"tuplet-note-wrapper": """ % a formatter function, which is simply a wrapper around an existing
% tuplet formatter function. It takes the value returned by the given
% function and appends a note of given length.
- #(define ((tuplet-number::append-note-wrapper function note) grob)
+ #(define-public ((tuplet-number::append-note-wrapper function note) grob)
(let* ((txt (if function (function grob) #f)))
(if txt
(markup txt #:fontsize -5 #:note note UP)
""",
}
-def round_to_two_digits (val):
- return round (val * 100) / 100
+def round_to_two_digits(val):
+ return round(val * 100) / 100
-def extract_paper_information (tree):
- paper = musicexp.Paper ()
- defaults = tree.get_maybe_exist_named_child ('defaults')
+def extract_paper_information(score_partwise):
+ defaults = score_partwise.get_maybe_exist_named_child('defaults')
if not defaults:
return None
tenths = -1
- scaling = defaults.get_maybe_exist_named_child ('scaling')
+ scaling = defaults.get_maybe_exist_named_child('scaling')
+ default_tenths_to_millimeters_ratio = 0.175
+ default_staff_size = 20
if scaling:
- mm = scaling.get_named_child ('millimeters')
- mm = string.atof (mm.get_text ())
- tn = scaling.get_maybe_exist_named_child ('tenths')
- tn = string.atof (tn.get_text ())
+ mm = scaling.get_named_child('millimeters')
+ mm = float(mm.get_text())
+ tn = scaling.get_maybe_exist_named_child('tenths')
+ tn = float(tn.get_text())
+ # The variable 'tenths' is actually a ratio, NOT the value of <tenths>.
+ # TODO: rename and replace.
tenths = mm / tn
- paper.global_staff_size = mm * 72.27 / 25.4
- # We need the scaling (i.e. the size of staff tenths for everything!
+ ratio = tenths / default_tenths_to_millimeters_ratio
+ staff_size = default_staff_size * ratio
+
+ if 1 < staff_size < 100:
+ paper.global_staff_size = staff_size
+ else:
+ msg = "paper.global_staff_size {} is too large, using defaults=20".format(
+ staff_size)
+ warnings.warn(msg)
+ paper.global_staff_size = 20
+
+ # We need the scaling(i.e. the size of staff tenths for everything!
if tenths < 0:
return None
- def from_tenths (txt):
- return round_to_two_digits (string.atof (txt) * tenths / 10)
- def set_paper_variable (varname, parent, element_name):
- el = parent.get_maybe_exist_named_child (element_name)
+ def from_tenths(txt):
+ return round_to_two_digits(float(txt) * tenths / 10)
+ def set_paper_variable(varname, parent, element_name):
+ el = parent.get_maybe_exist_named_child(element_name)
if el: # Convert to cm from tenths
- setattr (paper, varname, from_tenths (el.get_text ()))
+ setattr(paper, varname, from_tenths(el.get_text()))
- pagelayout = defaults.get_maybe_exist_named_child ('page-layout')
+ pagelayout = defaults.get_maybe_exist_named_child('page-layout')
if pagelayout:
# TODO: How can one have different margins for even and odd pages???
- set_paper_variable ("page_height", pagelayout, 'page-height')
- set_paper_variable ("page_width", pagelayout, 'page-width')
-
- pmargins = pagelayout.get_named_children ('page-margins')
- for pm in pmargins:
- set_paper_variable ("left_margin", pm, 'left-margin')
- set_paper_variable ("right_margin", pm, 'right-margin')
- set_paper_variable ("bottom_margin", pm, 'bottom-margin')
- set_paper_variable ("top_margin", pm, 'top-margin')
-
- systemlayout = defaults.get_maybe_exist_named_child ('system-layout')
+ set_paper_variable("page_height", pagelayout, 'page-height')
+ set_paper_variable("page_width", pagelayout, 'page-width')
+
+ if conversion_settings.convert_page_margins:
+ pmargins = pagelayout.get_named_children('page-margins')
+ for pm in pmargins:
+ set_paper_variable("left_margin", pm, 'left-margin')
+ set_paper_variable("right_margin", pm, 'right-margin')
+ set_paper_variable("bottom_margin", pm, 'bottom-margin')
+ set_paper_variable("top_margin", pm, 'top-margin')
+
+ systemlayout = defaults.get_maybe_exist_named_child('system-layout')
if systemlayout:
- sl = systemlayout.get_maybe_exist_named_child ('system-margins')
+ sl = systemlayout.get_maybe_exist_named_child('system-margins')
if sl:
- set_paper_variable ("system_left_margin", sl, 'left-margin')
- set_paper_variable ("system_right_margin", sl, 'right-margin')
- set_paper_variable ("system_distance", systemlayout, 'system-distance')
- set_paper_variable ("top_system_distance", systemlayout, 'top-system-distance')
+ set_paper_variable("system_left_margin", sl, 'left-margin')
+ set_paper_variable("system_right_margin", sl, 'right-margin')
+ set_paper_variable("system_distance", systemlayout, 'system-distance')
+ set_paper_variable("top_system_distance", systemlayout, 'top-system-distance')
- stafflayout = defaults.get_named_children ('staff-layout')
+ stafflayout = defaults.get_named_children('staff-layout')
for sl in stafflayout:
- nr = getattr (sl, 'number', 1)
- dist = sl.get_named_child ('staff-distance')
+ nr = getattr(sl, 'number', 1)
+ dist = sl.get_named_child('staff-distance')
#TODO: the staff distance needs to be set in the Staff context!!!
# TODO: Finish appearance?, music-font?, word-font?, lyric-font*, lyric-language*
- appearance = defaults.get_named_child ('appearance')
+ appearance = defaults.get_named_child('appearance')
if appearance:
- lws = appearance.get_named_children ('line-width')
+ lws = appearance.get_named_children('line-width')
for lw in lws:
# Possible types are: beam, bracket, dashes,
# enclosure, ending, extend, heavy barline, leger,
# light barline, octave shift, pedal, slur middle, slur tip,
# staff, stem, tie middle, tie tip, tuplet bracket, and wedge
tp = lw.type
- w = from_tenths (lw.get_text ())
+ w = from_tenths(lw.get_text())
# TODO: Do something with these values!
- nss = appearance.get_named_children ('note-size')
+ nss = appearance.get_named_children('note-size')
for ns in nss:
# Possible types are: cue, grace and large
tp = ns.type
- sz = from_tenths (ns.get_text ())
+ sz = from_tenths(ns.get_text())
# TODO: Do something with these values!
# <other-appearance> elements have no specified meaning
- rawmusicfont = defaults.get_named_child ('music-font')
+ rawmusicfont = defaults.get_named_child('music-font')
if rawmusicfont:
# TODO: Convert the font
pass
- rawwordfont = defaults.get_named_child ('word-font')
+ rawwordfont = defaults.get_named_child('word-font')
if rawwordfont:
# TODO: Convert the font
pass
- rawlyricsfonts = defaults.get_named_children ('lyric-font')
+ rawlyricsfonts = defaults.get_named_children('lyric-font')
for lyricsfont in rawlyricsfonts:
# TODO: Convert the font
pass
return paper
-
+credit_dict = {
+ None:None,
+ '':None,
+ 'page number':None, #TODO: what is it used for ?
+ 'title':'title',
+ 'subtitle':'subtitle',
+ 'composer':'composer',
+ 'arranger':'arranger',
+ 'lyricist':'poet',
+ 'rights':'copyright'
+}
# score information is contained in the <work>, <identification> or <movement-title> tags
# extract those into a hash, indexed by proper lilypond header attributes
-def extract_score_information (tree):
- header = musicexp.Header ()
- def set_if_exists (field, value):
+def extract_score_information(tree):
+ header = musicexp.Header()
+ def set_if_exists(field, value):
if value:
- header.set_field (field, musicxml.escape_ly_output_string (value))
+ header.set_field(field, utilities.escape_ly_output_string(value))
- work = tree.get_maybe_exist_named_child ('work')
- if work:
- set_if_exists ('worknumber', work.get_work_number ())
- set_if_exists ('opus', work.get_opus ())
-
- movement_title = tree.get_maybe_exist_named_child ('movement-title')
+ movement_title = tree.get_maybe_exist_named_child('movement-title')
+ movement_number = tree.get_maybe_exist_named_child('movement-number')
+ if movement_title:
+ set_if_exists('title', movement_title.get_text())
+ if movement_number:
+ set_if_exists('movementnumber', movement_number.get_text())
+ # set_if_exists('piece', movement_number.get_text()) # the movement number should be visible in the score.
- # use either work-title or movement-title as title.
- # if both exist use movement-title as subtitle.
- # if there is only a movement-title (or work-title is empty or missing) the movement-title should be typeset as a title
+ work = tree.get_maybe_exist_named_child('work')
if work:
- work_title = work.get_work_title ()
- set_if_exists ('title', work_title)
- if work_title == '' and movement_title :
- set_if_exists ('title', movement_title.get_text ())
- elif movement_title:
- set_if_exists ('subtitle', movement_title.get_text ())
- elif movement_title:
- set_if_exists ('title', movement_title.get_text ())
-
- identifications = tree.get_named_children ('identification')
+ work_number = work.get_work_number()
+ work_title = work.get_work_title()
+ # Overwrite the title from movement-title with work->title
+ set_if_exists('title', work.get_work_title())
+ set_if_exists('opus', work.get_work_number())
+ # Use movement-title as subtitle
+ if movement_title:
+ set_if_exists('subtitle', movement_title.get_text())
+
+# TODO: Translation of opus element. Not to be confused with opus in LilyPond. MusicXML opus is a document element for opus DTD
+ identifications = tree.get_named_children('identification')
for ids in identifications:
- set_if_exists ('copyright', ids.get_rights ())
- set_if_exists ('composer', ids.get_composer ())
- set_if_exists ('arranger', ids.get_arranger ())
- set_if_exists ('editor', ids.get_editor ())
- set_if_exists ('poet', ids.get_poet ())
-
- set_if_exists ('encodingsoftware', ids.get_encoding_software ())
- set_if_exists ('encodingdate', ids.get_encoding_date ())
- set_if_exists ('encoder', ids.get_encoding_person ())
- set_if_exists ('encodingdescription', ids.get_encoding_description ())
-
- set_if_exists ('source', ids.get_source ())
-
- # miscellaneous --> texidoc
- set_if_exists ('texidoc', ids.get_file_description ());
+ set_if_exists('copyright', ids.get_rights())
+ set_if_exists('composer', ids.get_composer())
+ set_if_exists('arranger', ids.get_arranger())
+ set_if_exists('editor', ids.get_editor())
+ set_if_exists('poet', ids.get_poet())
+
+ set_if_exists('encodingsoftware', ids.get_encoding_software())
+ set_if_exists('encodingdate', ids.get_encoding_date())
+ set_if_exists('encoder', ids.get_encoding_person())
+ set_if_exists('encodingdescription', ids.get_encoding_description())
+ set_if_exists('source', ids.get_source())
+
+ # <miscellaneous><miscellaneous-field name="description"> ... becomes
+ # \header { texidoc = ...
+ set_if_exists('texidoc', ids.get_file_description());
# Finally, apply the required compatibility modes
# Some applications created wrong MusicXML files, so we need to
# apply some compatibility mode, e.g. ignoring some features/tags
# in those files
- software = ids.get_encoding_software_list ()
+ software = ids.get_encoding_software_list()
# Case 1: "Sibelius 5.1" with the "Dolet 3.4 for Sibelius" plugin
# is missing all beam ends => ignore all beaming information
"Noteworthy Composer": "Noteworthy Composer's nwc2xm[",
}
for s in software:
- app_description = ignore_beaming_software.get (s, False);
+ app_description = ignore_beaming_software.get(s, False);
if app_description:
conversion_settings.ignore_beaming = True
- ly.warning (_ ("Encountered file created by %s, containing "
+ ly.warning(_("Encountered file created by %s, containing "
"wrong beaming information. All beaming "
"information in the MusicXML file will be "
"ignored") % app_description)
+ credits = tree.get_named_children('credit')
+ has_composer = False
+ for cred in credits:
+ type = credit_dict.get(cred.get_type())
+ if(type == None):
+ type = credit_dict.get(cred.find_type(credits))
+ if(type == 'composer'):
+ if(has_composer):
+ type = 'poet'
+ else:
+ has_composer = True
+ set_if_exists(type, cred.get_text())
+ elif(type == 'title'):
+ if(not(work) and not(movement_title)):
+ set_if_exists('title', cred.get_text())
+ #elif(not(movement_title)): #bullshit!
+ # set_if_exists('subtitle', cred.get_text()) #bullshit! otherwise both title and subtitle show the work-title.
+ elif(type == None):
+ pass
+ else:
+ set_if_exists(type, cred.get_text())
+
+
# TODO: Check for other unsupported features
return header
class PartGroupInfo:
- def __init__ (self):
+ def __init__(self):
self.start = {}
self.end = {}
- def is_empty (self):
- return len (self.start) + len (self.end) == 0
- def add_start (self, g):
- self.start[getattr (g, 'number', "1")] = g
- def add_end (self, g):
- self.end[getattr (g, 'number', "1")] = g
- def print_ly (self, printer):
- ly.warning (_ ("Unprocessed PartGroupInfo %s encountered") % self)
- def ly_expression (self):
- ly.warning (_ ("Unprocessed PartGroupInfo %s encountered") % self)
+ def is_empty(self):
+ return len(self.start) + len(self.end) == 0
+ def add_start(self, g):
+ self.start[getattr(g, 'number', "1")] = g
+ def add_end(self, g):
+ self.end[getattr(g, 'number', "1")] = g
+ def print_ly(self, printer):
+ ly.warning(_("Unprocessed PartGroupInfo %s encountered") % self)
+ def ly_expression(self):
+ ly.warning(_("Unprocessed PartGroupInfo %s encountered") % self)
return ''
-def musicxml_step_to_lily (step):
- if step:
- return (ord (step) - ord ('A') + 7 - 2) % 7
- else:
- return None
-
-
-def staff_attributes_to_string_tunings (mxl_attr):
- details = mxl_attr.get_maybe_exist_named_child ('staff-details')
+def staff_attributes_to_string_tunings(mxl_attr):
+ details = mxl_attr.get_maybe_exist_named_child('staff-details')
if not details:
return []
lines = 6
- staff_lines = details.get_maybe_exist_named_child ('staff-lines')
+ staff_lines = details.get_maybe_exist_named_child('staff-lines')
if staff_lines:
- lines = string.atoi (staff_lines.get_text ())
-
+ lines = string.atoi(staff_lines.get_text())
tunings = [musicexp.Pitch()] * lines
- staff_tunings = details.get_named_children ('staff-tuning')
+ staff_tunings = details.get_named_children('staff-tuning')
for i in staff_tunings:
p = musicexp.Pitch()
line = 0
try:
- line = string.atoi (i.line) - 1
+ line = string.atoi(i.line) - 1
except ValueError:
pass
tunings[line] = p
- step = i.get_named_child (u'tuning-step')
- step = step.get_text ().strip ()
- p.step = musicxml_step_to_lily (step)
+ step = i.get_named_child(u'tuning-step')
+ step = step.get_text().strip()
+ p.step = musicxml2ly_conversion.musicxml_step_to_lily(step)
- octave = i.get_named_child (u'tuning-octave')
- octave = octave.get_text ().strip ()
- p.octave = int (octave) - 4
+ octave = i.get_named_child(u'tuning-octave')
+ octave = octave.get_text().strip()
+ p.octave = int(octave) - 4
- alter = i.get_named_child (u'tuning-alter')
+ alter = i.get_named_child(u'tuning-alter')
if alter:
- p.alteration = int (alter.get_text ().strip ())
+ p.alteration = int(alter.get_text().strip())
# lilypond seems to use the opposite ordering than MusicXML...
- tunings.reverse ()
-
+ tunings.reverse()
return tunings
-
-def staff_attributes_to_lily_staff (mxl_attr):
+def staff_attributes_to_lily_staff(mxl_attr):
if not mxl_attr:
- return musicexp.Staff ()
+ return musicexp.Staff()
- (staff_id, attributes) = mxl_attr.items ()[0]
+ (staff_id, attributes) = mxl_attr.items()[0]
# distinguish by clef:
- # percussion (percussion and rhythmic), tab, and everything else
+ # percussion(percussion and rhythmic), tab, and everything else
clef_sign = None
- clef = attributes.get_maybe_exist_named_child ('clef')
+ clef = attributes.get_maybe_exist_named_child('clef')
if clef:
- sign = clef.get_maybe_exist_named_child ('sign')
+ sign = clef.get_maybe_exist_named_child('sign')
if sign:
- clef_sign = {"percussion": "percussion", "TAB": "tab"}.get (sign.get_text (), None)
+ clef_sign = {"percussion": "percussion", "TAB": "tab"}.get(sign.get_text(), None)
lines = 5
- details = attributes.get_named_children ('staff-details')
+ details = attributes.get_named_children('staff-details')
for d in details:
- staff_lines = d.get_maybe_exist_named_child ('staff-lines')
+ staff_lines = d.get_maybe_exist_named_child('staff-lines')
if staff_lines:
- lines = string.atoi (staff_lines.get_text ())
+ lines = string.atoi(staff_lines.get_text())
# TODO: Handle other staff attributes like staff-space, etc.
staff = None
if clef_sign == "percussion" and lines == 1:
- staff = musicexp.RhythmicStaff ()
+ staff = musicexp.RhythmicStaff()
elif clef_sign == "percussion":
- staff = musicexp.DrumStaff ()
+ staff = musicexp.DrumStaff()
# staff.drum_style_table = ???
elif clef_sign == "tab":
- staff = musicexp.TabStaff ()
- staff.string_tunings = staff_attributes_to_string_tunings (attributes)
+ staff = musicexp.TabStaff()
+ staff.string_tunings = staff_attributes_to_string_tunings(attributes)
# staff.tablature_format = ???
else:
- staff = musicexp.Staff ()
+ staff = musicexp.Staff()
# TODO: Handle case with lines <> 5!
- if (lines != 5):
- staff.add_context_modification ("\\override StaffSymbol.line-count = #%s" % lines)
-
+ if(lines != 5):
+ staff.add_context_modification("\\override StaffSymbol #'line-count = #%s" % lines)
return staff
+def extract_instrument_sound(score_part):
+ score_instrument = score_part.get_maybe_exist_named_child('score-instrument')
+ if not score_instrument:
+ return None
+ sound = score_instrument.get_maybe_exist_named_child('instrument-sound')
+ if sound:
+ return utilities.musicxml_sound_to_lilypond_midi_instrument(sound.get_text())
-def extract_score_structure (part_list, staffinfo):
- score = musicexp.Score ()
- structure = musicexp.StaffGroup (None)
- score.set_contents (structure)
+def extract_score_structure(part_list, staffinfo):
+ score = musicexp.Score()
+ structure = musicexp.StaffGroup(None)
+ score.set_contents(structure)
if not part_list:
return structure
- def read_score_part (el):
- if not isinstance (el, musicxml.Score_part):
+ def read_score_part(el):
+ if not isinstance(el, musicxml.Score_part):
return
# Depending on the attributes of the first measure, we create different
- # types of staves (Staff, RhythmicStaff, DrumStaff, TabStaff, etc.)
- staff = staff_attributes_to_lily_staff (staffinfo.get (el.id, None))
+ # types of staves(Staff, RhythmicStaff, DrumStaff, TabStaff, etc.)
+ staff = staff_attributes_to_lily_staff(staffinfo.get(el.id, None))
if not staff:
return None
staff.id = el.id
- partname = el.get_maybe_exist_named_child ('part-name')
+ partname = el.get_maybe_exist_named_child('part-name')
# Finale gives unnamed parts the name "MusicXML Part" automatically!
if partname and partname.get_text() != "MusicXML Part":
- staff.instrument_name = partname.get_text ()
+ staff.instrument_name = partname.get_text()
# part-name-display overrides part-name!
- partname = el.get_maybe_exist_named_child ("part-name-display")
+ partname = el.get_maybe_exist_named_child("part-name-display")
if partname:
- staff.instrument_name = extract_display_text (partname)
-
- partdisplay = el.get_maybe_exist_named_child ('part-abbreviation')
+ staff.instrument_name = extract_display_text(partname)
+ if hasattr(options, 'midi') and options.midi:
+ staff.sound = extract_instrument_sound(el)
+ if staff.instrument_name:
+ paper.indent = max(paper.indent, len(staff.instrument_name))
+ paper.instrument_names.append(staff.instrument_name)
+ partdisplay = el.get_maybe_exist_named_child('part-abbreviation')
if partdisplay:
- staff.short_instrument_name = partdisplay.get_text ()
+ staff.short_instrument_name = partdisplay.get_text()
# part-abbreviation-display overrides part-abbreviation!
- partdisplay = el.get_maybe_exist_named_child ("part-abbreviation-display")
+ partdisplay = el.get_maybe_exist_named_child("part-abbreviation-display")
if partdisplay:
- staff.short_instrument_name = extract_display_text (partdisplay)
+ staff.short_instrument_name = extract_display_text(partdisplay)
# TODO: Read in the MIDI device / instrument
+ if staff.short_instrument_name:
+ paper.short_indent = max(paper.short_indent, len(staff.short_instrument_name))
return staff
- def read_score_group (el):
- if not isinstance (el, musicxml.Part_group):
+ def read_score_group(el):
+ if not isinstance(el, musicxml.Part_group):
return
- group = musicexp.StaffGroup ()
- if hasattr (el, 'number'):
+ group = musicexp.StaffGroup()
+ if hasattr(el, 'number'):
id = el.number
group.id = id
#currentgroups_dict[id] = group
- #currentgroups.append (id)
- if el.get_maybe_exist_named_child ('group-name'):
- group.instrument_name = el.get_maybe_exist_named_child ('group-name').get_text ()
- if el.get_maybe_exist_named_child ('group-abbreviation'):
- group.short_instrument_name = el.get_maybe_exist_named_child ('group-abbreviation').get_text ()
- if el.get_maybe_exist_named_child ('group-symbol'):
- group.symbol = el.get_maybe_exist_named_child ('group-symbol').get_text ()
- if el.get_maybe_exist_named_child ('group-barline'):
- group.spanbar = el.get_maybe_exist_named_child ('group-barline').get_text ()
+ #currentgroups.append(id)
+ if el.get_maybe_exist_named_child('group-name'):
+ group.instrument_name = el.get_maybe_exist_named_child('group-name').get_text()
+ if el.get_maybe_exist_named_child('group-abbreviation'):
+ group.short_instrument_name = el.get_maybe_exist_named_child('group-abbreviation').get_text()
+ if el.get_maybe_exist_named_child('group-symbol'):
+ group.symbol = el.get_maybe_exist_named_child('group-symbol').get_text()
+ if el.get_maybe_exist_named_child('group-barline'):
+ group.spanbar = el.get_maybe_exist_named_child('group-barline').get_text()
return group
- parts_groups = part_list.get_all_children ()
+ parts_groups = part_list.get_all_children()
# the start/end group tags are not necessarily ordered correctly and groups
# might even overlap, so we can't go through the children sequentially!
# 1) Replace all Score_part objects by their corresponding Staff objects,
# also collect all group start/stop points into one PartGroupInfo object
staves = []
- group_info = PartGroupInfo ()
+ group_info = PartGroupInfo()
for el in parts_groups:
- if isinstance (el, musicxml.Score_part):
- if not group_info.is_empty ():
- staves.append (group_info)
- group_info = PartGroupInfo ()
- staff = read_score_part (el)
+ if isinstance(el, musicxml.Score_part):
+ if not group_info.is_empty():
+ staves.append(group_info)
+ group_info = PartGroupInfo()
+ staff = read_score_part(el)
if staff:
- staves.append (staff)
- elif isinstance (el, musicxml.Part_group):
+ staves.append(staff)
+ elif isinstance(el, musicxml.Part_group):
if el.type == "start":
- group_info.add_start (el)
+ group_info.add_start(el)
elif el.type == "stop":
- group_info.add_end (el)
- if not group_info.is_empty ():
- staves.append (group_info)
+ group_info.add_end(el)
+ if not group_info.is_empty():
+ staves.append(group_info)
# 2) Now, detect the groups:
group_starts = []
pos = 0
- while pos < len (staves):
+ while pos < len(staves):
el = staves[pos]
- if isinstance (el, PartGroupInfo):
+ if isinstance(el, PartGroupInfo):
prev_start = 0
- if len (group_starts) > 0:
+ if len(group_starts) > 0:
prev_start = group_starts[-1]
- elif len (el.end) > 0: # no group to end here
+ elif len(el.end) > 0: # no group to end here
el.end = {}
- if len (el.end) > 0: # closes an existing group
- ends = el.end.keys ()
- prev_started = staves[prev_start].start.keys ()
+ if len(el.end) > 0: # closes an existing group
+ ends = el.end.keys()
+ prev_started = staves[prev_start].start.keys()
grpid = None
intersection = filter(lambda x:x in ends, prev_started)
- if len (intersection) > 0:
+ if len(intersection) > 0:
grpid = intersection[0]
else:
# Close the last started group
- grpid = staves[prev_start].start.keys () [0]
+ grpid = staves[prev_start].start.keys() [0]
# Find the corresponding closing tag and remove it!
j = pos + 1
foundclosing = False
- while j < len (staves) and not foundclosing:
- if isinstance (staves[j], PartGroupInfo) and staves[j].end.has_key (grpid):
+ while j < len(staves) and not foundclosing:
+ if isinstance(staves[j], PartGroupInfo) and staves[j].end.has_key(grpid):
foundclosing = True
del staves[j].end[grpid]
- if staves[j].is_empty ():
+ if staves[j].is_empty():
del staves[j]
j += 1
grpobj = staves[prev_start].start[grpid]
- group = read_score_group (grpobj)
+ group = read_score_group(grpobj)
# remove the id from both the start and end
- if el.end.has_key (grpid):
+ if el.end.has_key(grpid):
del el.end[grpid]
del staves[prev_start].start[grpid]
- if el.is_empty ():
+ if el.is_empty():
del staves[pos]
# replace the staves with the whole group
for j in staves[(prev_start + 1):pos]:
- group.append_staff (j)
+ group.append_staff(j)
del staves[(prev_start + 1):pos]
- staves.insert (prev_start + 1, group)
+ staves.insert(prev_start + 1, group)
# reset pos so that we continue at the correct position
pos = prev_start
# remove an empty start group
- if staves[prev_start].is_empty ():
+ if staves[prev_start].is_empty():
del staves[prev_start]
- group_starts.remove (prev_start)
+ group_starts.remove(prev_start)
pos -= 1
- elif len (el.start) > 0: # starts new part groups
- group_starts.append (pos)
+ elif len(el.start) > 0: # starts new part groups
+ group_starts.append(pos)
pos += 1
for i in staves:
- structure.append_staff (i)
+ structure.append_staff(i)
return score
-def musicxml_duration_to_lily (mxl_note):
- # if the note has no Type child, then that method returns None. In that case,
- # use the <duration> tag instead. If that doesn't exist, either -> Error
- dur = mxl_note.get_duration_info ()
- if dur:
- d = musicexp.Duration ()
- d.duration_log = dur[0]
- d.dots = dur[1]
- # Grace notes by specification have duration 0, so no time modification
- # factor is possible. It even messes up the output with *0/1
- if not mxl_note.get_maybe_exist_typed_child (musicxml.Grace):
- d.factor = mxl_note._duration / d.get_length ()
- return d
-
- else:
- if mxl_note._duration > 0:
- return rational_to_lily_duration (mxl_note._duration)
- else:
- mxl_note.message (_ ("Encountered note at %s without type and duration (=%s)") % (mxl_note.start, mxl_note._duration) )
- return None
-
-
-def rational_to_lily_duration (rational_len):
- d = musicexp.Duration ()
- rational_len.normalize_self ()
- d_log = {1: 0, 2: 1, 4:2, 8:3, 16:4, 32:5, 64:6, 128:7, 256:8, 512:9}.get (rational_len.denominator (), -1)
-
- # Duration of the form 1/2^n or 3/2^n can be converted to a simple lilypond duration
- dots = {1: 0, 3: 1, 7: 2, 15: 3, 31: 4, 63: 5, 127: 6}.get (rational_len.numerator(), -1)
- if ( d_log >= dots >= 0 ):
- # account for the dots!
- d.duration_log = d_log - dots
- d.dots = dots
- elif (d_log >= 0):
- d.duration_log = d_log
- d.factor = Rational (rational_len.numerator ())
- else:
- ly.warning (_ ("Encountered rational duration with denominator %s, "
- "unable to convert to lilypond duration") %
- rational_len.denominator ())
- # TODO: Test the above error message
- return None
- return d
-
-def musicxml_partial_to_lily (partial_len):
+def musicxml_partial_to_lily(partial_len):
if partial_len > 0:
- p = musicexp.Partial ()
- p.partial = rational_to_lily_duration (partial_len)
+ p = musicexp.Partial()
+ p.partial = musicxml2ly_conversion.rational_to_lily_duration(partial_len)
return p
else:
return None
-# Detect repeats and alternative endings in the chord event list (music_list)
+# Detect repeats and alternative endings in the chord event list(music_list)
# and convert them to the corresponding musicexp objects, containing nested
# music
-def group_repeats (music_list):
+def group_repeats(music_list):
repeat_replaced = True
music_start = 0
i = 0
# Walk through the list of expressions, looking for repeat structure
- # (repeat start/end, corresponding endings). If we find one, try to find the
+ #(repeat start/end, corresponding endings). If we find one, try to find the
# last event of the repeat, replace the whole structure and start over again.
# For nested repeats, as soon as we encounter another starting repeat bar,
# treat that one first, and start over for the outer repeat.
ending_start = -1 # position of current ending start
endings = [] # list of already finished endings
pos = 0
- last = len (music_list) - 1
+ last = len(music_list) - 1
repeat_replaced = False
final_marker = 0
- while pos < len (music_list) and not repeat_replaced:
+ while pos < len(music_list) and not repeat_replaced:
e = music_list[pos]
repeat_finished = False
- if isinstance (e, RepeatMarker):
+ if isinstance(e, musicxml2ly_conversion.RepeatMarker):
if not repeat_times and e.times:
repeat_times = e.times
if e.direction == -1:
if repeat_end < 0:
repeat_end = pos
final_marker = pos
- elif isinstance (e, EndingMarker):
+ elif isinstance(e, musicxml2ly_conversion.EndingMarker):
if e.direction == -1:
if repeat_start < 0:
repeat_start = 0
elif e.direction == 1:
if ending_start < 0:
ending_start = 0
- endings.append ([ending_start, pos])
+ endings.append([ending_start, pos])
ending_start = -1
final_marker = pos
- elif not isinstance (e, musicexp.BarLine):
+ elif not isinstance(e, musicexp.BarLine):
# As soon as we encounter an element when repeat start and end
# is set and we are not inside an alternative ending,
# this whole repeat structure is finished => replace it
if repeat_start >= 0 and repeat_end > 0 and ending_start < 0:
repeat_finished = True
- # Finish off all repeats without explicit ending bar (e.g. when
+ # Finish off all repeats without explicit ending bar(e.g. when
# we convert only one page of a multi-page score with repeats)
if pos == last and repeat_start >= 0:
repeat_finished = True
if repeat_end < 0:
repeat_end = pos
if ending_start >= 0:
- endings.append ([ending_start, pos])
+ endings.append([ending_start, pos])
ending_start = -1
if repeat_finished:
# We found the whole structure replace it!
- r = musicexp.RepeatedMusic ()
+ r = musicexp.RepeatedMusic()
if repeat_times <= 0:
repeat_times = 2
r.repeat_count = repeat_times
- # don't erase the first element for "implicit" repeats (i.e. no
+ # don't erase the first element for "implicit" repeats(i.e. no
# starting repeat bars at the very beginning)
start = repeat_start + 1
if repeat_start == music_start:
start = music_start
- r.set_music (music_list[start:repeat_end])
- for (start, end) in endings:
- s = musicexp.SequentialMusic ()
+ r.set_music(music_list[start:repeat_end])
+ for(start, end) in endings:
+ s = musicexp.SequentialMusic()
s.elements = music_list[start + 1:end]
- r.add_ending (s)
+ r.add_ending(s)
del music_list[repeat_start:final_marker + 1]
- music_list.insert (repeat_start, r)
+ music_list.insert(repeat_start, r)
repeat_replaced = True
pos += 1
# TODO: Implement repeats until the end without explicit ending bar
# Extract the settings for tuplets from the <notations><tuplet> and the
# <time-modification> elements of the note:
-def musicxml_tuplet_to_lily (tuplet_elt, time_modification):
- tsm = musicexp.TimeScaledMusic ()
- fraction = (1, 1)
+def musicxml_tuplet_to_lily(tuplet_elt, time_modification):
+ tsm = musicexp.TimeScaledMusic()
+ fraction =(1, 1)
if time_modification:
- fraction = time_modification.get_fraction ()
+ fraction = time_modification.get_fraction()
tsm.numerator = fraction[0]
tsm.denominator = fraction[1]
- normal_type = tuplet_elt.get_normal_type ()
+ normal_type = tuplet_elt.get_normal_type()
if not normal_type and time_modification:
- normal_type = time_modification.get_normal_type ()
+ normal_type = time_modification.get_normal_type()
if not normal_type and time_modification:
- note = time_modification.get_parent ()
+ note = time_modification.get_parent()
if note:
- normal_type = note.get_duration_info ()
+ normal_type = note.get_duration_info()
if normal_type:
- normal_note = musicexp.Duration ()
+ normal_note = musicexp.Duration()
(normal_note.duration_log, normal_note.dots) = normal_type
tsm.normal_type = normal_note
- actual_type = tuplet_elt.get_actual_type ()
+ actual_type = tuplet_elt.get_actual_type()
if actual_type:
- actual_note = musicexp.Duration ()
+ actual_note = musicexp.Duration()
(actual_note.duration_log, actual_note.dots) = actual_type
tsm.actual_type = actual_note
# Obtain non-default nrs of notes from the tuplet object!
- tsm.display_numerator = tuplet_elt.get_normal_nr ()
- tsm.display_denominator = tuplet_elt.get_actual_nr ()
+ tsm.display_numerator = tuplet_elt.get_normal_nr()
+ tsm.display_denominator = tuplet_elt.get_actual_nr()
- if hasattr (tuplet_elt, 'bracket') and tuplet_elt.bracket == "no":
+ if hasattr(tuplet_elt, 'bracket') and tuplet_elt.bracket == "no":
tsm.display_bracket = None
- elif hasattr (tuplet_elt, 'line-shape') and getattr (tuplet_elt, 'line-shape') == "curved":
+ elif hasattr(tuplet_elt, 'line-shape') and getattr(tuplet_elt, 'line-shape') == "curved":
tsm.display_bracket = "curved"
else:
tsm.display_bracket = "bracket"
display_values = {"none": None, "actual": "actual", "both": "both"}
- if hasattr (tuplet_elt, "show-number"):
- tsm.display_number = display_values.get (getattr (tuplet_elt, "show-number"), "actual")
+ if hasattr(tuplet_elt, "show-number"):
+ tsm.display_number = display_values.get(getattr(tuplet_elt, "show-number"), "actual")
- if hasattr (tuplet_elt, "show-type"):
- tsm.display_type = display_values.get (getattr (tuplet_elt, "show-type"), None)
+ if hasattr(tuplet_elt, "show-type"):
+ tsm.display_type = display_values.get(getattr(tuplet_elt, "show-type"), None)
return tsm
-def group_tuplets (music_list, events):
+def group_tuplets(music_list, events):
"""Collect Musics from
MUSIC_LIST demarcated by EVENTS_LIST in TimeScaledMusic objects.
"""
-
indices = []
brackets = {}
j = 0
- for (ev_chord, tuplet_elt, time_modification) in events:
- while (j < len (music_list)):
+ for(ev_chord, tuplet_elt, time_modification) in events:
+ while(j < len(music_list)):
if music_list[j] == ev_chord:
break
j += 1
nr = 0
- if hasattr (tuplet_elt, 'number'):
- nr = getattr (tuplet_elt, 'number')
+ if hasattr(tuplet_elt, 'number'):
+ nr = getattr(tuplet_elt, 'number')
if tuplet_elt.type == 'start':
- tuplet_object = musicxml_tuplet_to_lily (tuplet_elt, time_modification)
+ tuplet_object = musicxml_tuplet_to_lily(tuplet_elt, time_modification)
tuplet_info = [j, None, tuplet_object]
- indices.append (tuplet_info)
+ indices.append(tuplet_info)
brackets[nr] = tuplet_info
elif tuplet_elt.type == 'stop':
- bracket_info = brackets.get (nr, None)
+ bracket_info = brackets.get(nr, None)
if bracket_info:
bracket_info[1] = j # Set the ending position to j
del brackets[nr]
new_list = []
last = 0
- for (i1, i2, tsm) in indices:
+ for(i1, i2, tsm) in indices:
if i1 > i2:
continue
- new_list.extend (music_list[last:i1])
- seq = musicexp.SequentialMusic ()
+ new_list.extend(music_list[last:i1])
+ seq = musicexp.SequentialMusic()
last = i2 + 1
+
+ # At this point music_list[i1:last] encompasses all the notes of the
+ # tuplet. There might be dynamics following this range, however, which
+ # apply to the last note of the tuplet. Advance last to include them
+ # in the range.
+ while last < len(music_list) and isinstance(music_list[last], musicexp.DynamicsEvent):
+ last += 1
+
seq.elements = music_list[i1:last]
tsm.element = seq
- new_list.append (tsm)
+ new_list.append(tsm)
#TODO: Handle nested tuplets!!!!
- new_list.extend (music_list[last:])
+ new_list.extend(music_list[last:])
return new_list
-def musicxml_clef_to_lily (attributes):
- change = musicexp.ClefChange ()
- (change.type, change.position, change.octave) = attributes.get_clef_information ()
+def musicxml_clef_to_lily(attributes):
+ change = musicexp.ClefChange()
+ (change.type, change.position, change.octave) = attributes.get_clef_information()
return change
-def musicxml_time_to_lily (attributes):
- sig = attributes.get_time_signature ()
+def musicxml_time_to_lily(attributes):
+ change = musicexp.TimeSignatureChange()
+ # time signature function
+ if hasattr(options, 'shift_meter') and options.shift_meter:
+ tmp_meter = options.shift_meter.split("/",1)
+ sig = [int(tmp_meter[0]), int(tmp_meter[1])]
+ change.originalFractions = attributes.get_time_signature()
+ else:
+ sig = attributes.get_time_signature()
if not sig:
return None
- change = musicexp.TimeSignatureChange()
change.fractions = sig
- time_elm = attributes.get_maybe_exist_named_child ('time')
- if time_elm and hasattr (time_elm, 'symbol'):
+ time_elm = attributes.get_maybe_exist_named_child('time')
+ if time_elm and hasattr(time_elm, 'symbol'):
change.style = { 'single-number': "'single-digit",
'cut': None,
'common': None,
- 'normal': "'()"}.get (time_elm.symbol, "'()")
+ 'normal': "'()"}.get(time_elm.symbol, "'()")
else:
change.style = "'()"
# TODO: Handle senza-misura measures
- # TODO: Handle hidden time signatures (print-object="no")
+ # TODO: Handle hidden time signatures(print-object="no")
# TODO: What shall we do if the symbol clashes with the sig? e.g. "cut"
- # with 3/8 or "single-number" with (2+3)/8 or 3/8+2/4?
-
+ # with 3/8 or "single-number" with(2+3)/8 or 3/8+2/4?
return change
-def musicxml_key_to_lily (attributes):
- key_sig = attributes.get_key_signature ()
- if not key_sig or not (isinstance (key_sig, list) or isinstance (key_sig, tuple)):
- ly.warning (_ ("Unable to extract key signature!"))
+def musicxml_key_to_lily(attributes):
+ key_sig = attributes.get_key_signature()
+ if not key_sig or not(isinstance(key_sig, list) or isinstance(key_sig, tuple)):
+ ly.warning(_("Unable to extract key signature!"))
return None
change = musicexp.KeySignatureChange()
- if len (key_sig) == 2 and not isinstance (key_sig[0], list):
- # standard key signature, (fifths, mode)
+ if len(key_sig) == 2 and not isinstance(key_sig[0], list):
+ # standard key signature,(fifths, mode)
(fifths, mode) = key_sig
change.mode = mode
- start_pitch = musicexp.Pitch ()
+ start_pitch = musicexp.Pitch()
start_pitch.octave = 0
try:
(n, a) = {
start_pitch.step = n
start_pitch.alteration = a
except KeyError:
- ly.warning (_ ("unknown mode %s, expecting 'major' or 'minor' "
+ ly.warning(_("unknown mode %s, expecting 'major' or 'minor' "
"or a church mode!") % mode)
fifth = musicexp.Pitch()
if fifths < 0:
fifths *= -1
fifth.step *= -1
- fifth.normalize ()
- for x in range (fifths):
- start_pitch = start_pitch.transposed (fifth)
+ fifth.normalize()
+ for x in range(fifths):
+ start_pitch = start_pitch.transposed(fifth)
change.tonic = start_pitch
else:
# MusicXML contains C,D,E,F,G,A,B as steps, lily uses 0-7, so convert
alterations = []
for k in key_sig:
- k[0] = musicxml_step_to_lily (k[0])
- alterations.append (k)
+ k[0] = musicxml2ly_conversion.musicxml_step_to_lily(k[0])
+ alterations.append(k)
change.non_standard_alterations = alterations
return change
-def musicxml_transpose_to_lily (attributes):
- transpose = attributes.get_transposition ()
+def musicxml_transpose_to_lily(attributes):
+ transpose = attributes.get_transposition()
if not transpose:
return None
- shift = musicexp.Pitch ()
- octave_change = transpose.get_maybe_exist_named_child ('octave-change')
+ shift = musicexp.Pitch()
+ octave_change = transpose.get_maybe_exist_named_child('octave-change')
if octave_change:
- shift.octave = string.atoi (octave_change.get_text ())
- chromatic_shift = string.atoi (transpose.get_named_child ('chromatic').get_text ())
+ shift.octave = string.atoi(octave_change.get_text())
+ chromatic_shift = string.atoi(transpose.get_named_child('chromatic').get_text())
chromatic_shift_normalized = chromatic_shift % 12;
(shift.step, shift.alteration) = [
(0, 0), (0, 1), (1, 0), (2, -1), (2, 0),
shift.octave += (chromatic_shift - chromatic_shift_normalized) / 12
- diatonic = transpose.get_maybe_exist_named_child ('diatonic')
+ diatonic = transpose.get_maybe_exist_named_child('diatonic')
if diatonic:
- diatonic_step = string.atoi (diatonic.get_text ()) % 7
+ diatonic_step = string.atoi(diatonic.get_text()) % 7
if diatonic_step != shift.step:
# We got the alter incorrect!
- old_semitones = shift.semitones ()
+ old_semitones = shift.semitones()
shift.step = diatonic_step
- new_semitones = shift.semitones ()
+ new_semitones = shift.semitones()
shift.alteration += old_semitones - new_semitones
- transposition = musicexp.Transposition ()
- transposition.pitch = musicexp.Pitch ().transposed (shift)
+ transposition = musicexp.Transposition()
+ transposition.pitch = musicexp.Pitch().transposed(shift)
return transposition
-def musicxml_staff_details_to_lily (attributes):
- details = attributes.get_maybe_exist_named_child ('staff-details')
+def musicxml_staff_details_to_lily(attributes):
+ details = attributes.get_maybe_exist_named_child('staff-details')
if not details:
return None
## TODO: Handle staff-type, staff-lines, staff-tuning, capo, staff-size
ret = []
- stafflines = details.get_maybe_exist_named_child ('staff-lines')
+ stafflines = details.get_maybe_exist_named_child('staff-lines')
if stafflines:
- lines = string.atoi (stafflines.get_text ());
- lines_event = musicexp.StaffLinesEvent (lines);
- ret.append (lines_event);
+ lines = string.atoi(stafflines.get_text());
+ lines_event = musicexp.StaffLinesEvent(lines);
+ ret.append(lines_event);
return ret;
-def musicxml_attributes_to_lily (attrs):
+def musicxml_attributes_to_lily(attrs):
elts = []
attr_dispatch = {
'clef': musicxml_clef_to_lily,
'transpose': musicxml_transpose_to_lily,
'staff-details': musicxml_staff_details_to_lily,
}
- for (k, func) in attr_dispatch.items ():
- children = attrs.get_named_children (k)
+ for (k, func) in attr_dispatch.items():
+ children = attrs.get_named_children(k)
if children:
- ev = func (attrs)
- if isinstance (ev, list):
+ ev = func(attrs)
+ if isinstance(ev, list):
for e in ev:
- elts.append (e)
+ elts.append(e)
elif ev:
- elts.append (ev)
+ elts.append(ev)
return elts
-def extract_display_text (el):
- child = el.get_maybe_exist_named_child ("display-text")
+def extract_display_text(el):
+ child = el.get_maybe_exist_named_child("display-text")
if child:
- return child.get_text ()
+ return child.get_text()
else:
return False
-def musicxml_print_to_lily (el):
+def musicxml_print_to_lily(el):
# TODO: Implement other print attributes
# <!ELEMENT print (page-layout?, system-layout?, staff-layout*,
# measure-layout?, measure-numbering?, part-name-display?,
# page-number CDATA #IMPLIED
# >
elts = []
- if (hasattr (el, "new-system") and conversion_settings.convert_page_layout):
- val = getattr (el, "new-system")
+ if (hasattr(el, "new-system") and conversion_settings.convert_system_breaks):
+ val = getattr(el, "new-system")
if (val == "yes"):
- elts.append (musicexp.Break ("break"))
- if (hasattr (el, "new-page") and conversion_settings.convert_page_layout):
- val = getattr (el, "new-page")
+ elts.append(musicexp.Break("break"))
+ if (hasattr(el, "new-page") and conversion_settings.convert_page_breaks):
+ val = getattr(el, "new-page")
if (val == "yes"):
- elts.append (musicexp.Break ("pageBreak"))
- child = el.get_maybe_exist_named_child ("part-name-display")
+ elts.append(musicexp.Break("pageBreak"))
+ child = el.get_maybe_exist_named_child("part-name-display")
if child:
- elts.append (musicexp.SetEvent ("Staff.instrumentName",
- "\"%s\"" % extract_display_text (child)))
- child = el.get_maybe_exist_named_child ("part-abbreviation-display")
+ elts.append(musicexp.SetEvent("Staff.instrumentName",
+ "\"%s\"" % extract_display_text(child)))
+ child = el.get_maybe_exist_named_child("part-abbreviation-display")
if child:
- elts.append (musicexp.SetEvent ("Staff.shortInstrumentName",
- "\"%s\"" % extract_display_text (child)))
+ elts.append(musicexp.SetEvent("Staff.shortInstrumentName",
+ "\"%s\"" % extract_display_text(child)))
return elts
-class Marker (musicexp.Music):
- def __init__ (self):
- self.direction = 0
- self.event = None
- def print_ly (self, printer):
- ly.warning (_ ("Encountered unprocessed marker %s\n") % self)
- pass
- def ly_expression (self):
- return ""
-class RepeatMarker (Marker):
- def __init__ (self):
- Marker.__init__ (self)
- self.times = 0
-class EndingMarker (Marker):
- pass
-
-# Convert the <barline> element to musicxml.BarLine (for non-standard barlines)
-# and to RepeatMarker and EndingMarker objects for repeat and
-# alternatives start/stops
-def musicxml_barline_to_lily (barline):
- # retval contains all possible markers in the order:
- # 0..bw_ending, 1..bw_repeat, 2..barline, 3..fw_repeat, 4..fw_ending
- retval = {}
- bartype_element = barline.get_maybe_exist_named_child ("bar-style")
- repeat_element = barline.get_maybe_exist_named_child ("repeat")
- ending_element = barline.get_maybe_exist_named_child ("ending")
-
- bartype = None
- if bartype_element:
- bartype = bartype_element.get_text ()
-
- if repeat_element and hasattr (repeat_element, 'direction'):
- repeat = RepeatMarker ()
- repeat.direction = {"forward": -1, "backward": 1}.get (repeat_element.direction, 0)
-
- if ( (repeat_element.direction == "forward" and bartype == "heavy-light") or
- (repeat_element.direction == "backward" and bartype == "light-heavy") ):
- bartype = None
- if hasattr (repeat_element, 'times'):
- try:
- repeat.times = int (repeat_element.times)
- except ValueError:
- repeat.times = 2
- repeat.event = barline
- if repeat.direction == -1:
- retval[3] = repeat
- else:
- retval[1] = repeat
-
- if ending_element and hasattr (ending_element, 'type'):
- ending = EndingMarker ()
- ending.direction = {"start": -1, "stop": 1, "discontinue": 1}.get (ending_element.type, 0)
- ending.event = barline
- if ending.direction == -1:
- retval[4] = ending
- else:
- retval[0] = ending
-
- if bartype:
- b = musicexp.BarLine ()
- b.type = bartype
- retval[2] = b
- return retval.values ()
spanner_event_dict = {
'beam' : musicexp.BeamEvent,
'pedal' : musicexp.PedalEvent,
'slide' : musicexp.GlissandoEvent,
'slur' : musicexp.SlurEvent,
- 'wavy-line' : musicexp.TrillSpanEvent,
+ 'wavy-line' : musicexp.TextSpannerEvent,
'wedge' : musicexp.HairpinEvent
}
spanner_type_dict = {
- 'start': -1,
- 'begin': -1,
- 'crescendo': -1,
- 'decreschendo': -1,
- 'diminuendo': -1,
+ 'start':-1,
+ 'begin':-1,
+ 'crescendo':-1,
+ 'decreschendo':-1,
+ 'diminuendo':-1,
'continue': 0,
'change': 0,
- 'up': -1,
- 'down': -1,
+ 'up':-1,
+ 'down':-1,
'stop': 1,
'end' : 1
}
-def musicxml_spanner_to_lily_event (mxl_event):
+def musicxml_spanner_to_lily_event(mxl_event):
ev = None
name = mxl_event.get_name()
- func = spanner_event_dict.get (name)
+ func = spanner_event_dict.get(name)
if func:
ev = func()
else:
- ly.warning (_ ('unknown span event %s') % mxl_event)
+ ly.warning(_('unknown span event %s') % mxl_event)
+ if name == "wavy-line":
+ ev.style=OrnamenthasWhat(mxl_event)
- type = mxl_event.get_type ()
- span_direction = spanner_type_dict.get (type)
+ type = mxl_event.get_type()
+ span_direction = spanner_type_dict.get(type)
# really check for None, because some types will be translated to 0, which
# would otherwise also lead to the unknown span warning
if span_direction != None:
ev.span_direction = span_direction
else:
- ly.warning (_ ('unknown span type %s for %s') % (type, name))
+ ly.warning(_('unknown span type %s for %s') %(type, name))
- ev.set_span_type (type)
- ev.line_type = getattr (mxl_event, 'line-type', 'solid')
+ ev.set_span_type(type)
+ ev.line_type = getattr(mxl_event, 'line-type', 'solid')
# assign the size, which is used for octave-shift, etc.
- ev.size = mxl_event.get_size ()
+ ev.size = mxl_event.get_size()
return ev
-def musicxml_direction_to_indicator (direction):
- return { "above": 1, "upright": 1, "up": 1, "below": -1, "downright": -1, "down": -1, "inverted": -1 }.get (direction, 0)
+def musicxml_direction_to_indicator(direction):
+ return { "above": 1, "upright": 1, "up": 1, "below":-1, "downright":-1, "down":-1, "inverted":-1 }.get(direction, 0)
+
+def musicxml_fermata_to_lily_event(mxl_event):
+
+ ev = musicexp.ArticulationEvent()
+ txt = mxl_event.get_text()
-def musicxml_fermata_to_lily_event (mxl_event):
- ev = musicexp.ArticulationEvent ()
- txt = mxl_event.get_text ()
# The contents of the element defined the shape, possible are normal, angled and square
- ev.type = { "angled": "shortfermata", "square": "longfermata" }.get (txt, "fermata")
- if hasattr (mxl_event, 'type'):
- dir = musicxml_direction_to_indicator (mxl_event.type)
- if dir and options.convert_directions:
- ev.force_direction = dir
+ ev.type = { "angled": "shortfermata", "square": "longfermata" }.get(txt, "fermata")
+ fermata_types= { "angled": "shortfermata",
+ "square": "longfermata" }
+
+ # MusicXML fermata types can be specified in two different ways:
+ # 1. <fermata>angled</fermata> and
+ # 2. <fermata type="angled"/> -- both need to be handled.
+ if hasattr(mxl_event, 'type'):
+ fermata_type = fermata_types.get(mxl_event.type, 'fermata')
+ else:
+ fermata_type = fermata_types.get(mxl_event.get_text(), 'fermata')
+
+ ev.type = fermata_type
+
+ if hasattr(mxl_event, 'type'):
+ dir = musicxml_direction_to_indicator(mxl_event.type)
+ if dir and options.convert_directions:
+ ev.force_direction = dir
return ev
-def musicxml_arpeggiate_to_lily_event (mxl_event):
- ev = musicexp.ArpeggioEvent ()
- ev.direction = musicxml_direction_to_indicator (getattr (mxl_event, 'direction', None))
+def musicxml_arpeggiate_to_lily_event(mxl_event):
+ ev = musicexp.ArpeggioEvent()
+ ev.direction = musicxml_direction_to_indicator(getattr(mxl_event, 'direction', None))
return ev
-def musicxml_nonarpeggiate_to_lily_event (mxl_event):
- ev = musicexp.ArpeggioEvent ()
+def musicxml_nonarpeggiate_to_lily_event(mxl_event):
+ ev = musicexp.ArpeggioEvent()
ev.non_arpeggiate = True
- ev.direction = musicxml_direction_to_indicator (getattr (mxl_event, 'direction', None))
+ ev.direction = musicxml_direction_to_indicator(getattr(mxl_event, 'direction', None))
return ev
-def musicxml_tremolo_to_lily_event (mxl_event):
- ev = musicexp.TremoloEvent ()
- txt = mxl_event.get_text ()
+def musicxml_tremolo_to_lily_event(mxl_event):
+ ev = musicexp.TremoloEvent()
+ txt = mxl_event.get_text()
if txt:
- ev.bars = txt
+ ev.strokes = txt
else:
- ev.bars = "3"
+ # This is supposed to be a default for empty tremolo elements
+ # TODO: Add empty tremolo element to test cases in tremolo.xml
+ # TODO: Test empty tremolo element
+ # TODO: Consideration: Is 3 really a reasonable default?
+ ev.strokes = "3"
return ev
-def musicxml_falloff_to_lily_event (mxl_event):
- ev = musicexp.BendEvent ()
+def musicxml_falloff_to_lily_event(mxl_event):
+ ev = musicexp.BendEvent()
ev.alter = -4
return ev
-def musicxml_doit_to_lily_event (mxl_event):
- ev = musicexp.BendEvent ()
+def musicxml_doit_to_lily_event(mxl_event):
+ ev = musicexp.BendEvent()
ev.alter = 4
return ev
-def musicxml_bend_to_lily_event (mxl_event):
- ev = musicexp.BendEvent ()
- ev.alter = mxl_event.bend_alter ()
+def musicxml_bend_to_lily_event(mxl_event):
+ ev = musicexp.BendEvent()
+ ev.alter = mxl_event.bend_alter()
return ev
-def musicxml_caesura_to_lily_event (mxl_event):
- ev = musicexp.MarkupEvent ()
+def musicxml_caesura_to_lily_event(mxl_event):
+ ev = musicexp.MarkupEvent()
# FIXME: default to straight or curved caesura?
ev.contents = "\\musicglyph #\"scripts.caesura.straight\""
ev.force_direction = 1
return ev
-def musicxml_fingering_event (mxl_event):
- ev = musicexp.ShortArticulationEvent ()
- ev.type = mxl_event.get_text ()
+def musicxml_fingering_event(mxl_event):
+ ev = musicexp.ShortArticulationEvent()
+ ev.type = mxl_event.get_text()
return ev
-def musicxml_string_event (mxl_event):
- ev = musicexp.NoDirectionArticulationEvent ()
- ev.type = mxl_event.get_text ()
+def musicxml_string_event(mxl_event):
+ ev = musicexp.NoDirectionArticulationEvent()
+ ev.type = mxl_event.get_text()
return ev
-def musicxml_accidental_mark (mxl_event):
- ev = musicexp.MarkupEvent ()
+def musicxml_accidental_mark(mxl_event):
+ ev = musicexp.MarkupEvent()
contents = { "sharp": "\\sharp",
"natural": "\\natural",
"flat": "\\flat",
"quarter-sharp": "\\semisharp",
"three-quarters-flat": "\\sesquiflat",
"three-quarters-sharp": "\\sesquisharp",
- }.get (mxl_event.get_text ())
+ }.get(mxl_event.get_text())
if contents:
ev.contents = contents
return ev
}
articulation_spanners = [ "wavy-line" ]
-def musicxml_articulation_to_lily_event (mxl_event):
+def OrnamenthasWhat(mxl_event):
+ wavy = trilly = ignore = start = stop = False
+ for i in mxl_event._parent._children:
+ if i._name == "wavy-line": wavy = True
+ elif i._name == "trill-mark": trilly = True
+ try:
+ if i.type == "continue": ignore = True
+ elif i.type == "start": start = True
+ elif i.type == "stop": stop = True
+ except:
+ pass
+ if start == True:
+ if wavy == True and trilly == False: musicexp.whatOrnament = "wave"
+ else: musicexp.whatOrnament = "trill"
+ if ignore == True: return "ignore"
+ elif stop == True: return "stop"
+ elif wavy == True and trilly == True: return "trill and wave"
+ elif wavy == True: return "wave"
+ elif trilly == True: return "trill"
+
+def OrnamenthasWavyline(mxl_event):
+ for i in mxl_event._parent._children:
+ if i._name == "wavy-line": return True
+ return False
+
+
+def musicxml_articulation_to_lily_event(mxl_event):
# wavy-line elements are treated as trill spanners, not as articulation ornaments
- if mxl_event.get_name () in articulation_spanners:
- return musicxml_spanner_to_lily_event (mxl_event)
+ if mxl_event.get_name() in articulation_spanners:
+ return musicxml_spanner_to_lily_event(mxl_event)
- tmp_tp = articulations_dict.get (mxl_event.get_name ())
+ tmp_tp = articulations_dict.get(mxl_event.get_name())
+ if OrnamenthasWavyline(mxl_event):
+ return
if not tmp_tp:
return
- if isinstance (tmp_tp, str):
- ev = musicexp.ArticulationEvent ()
+ if isinstance(tmp_tp, str):
+ ev = musicexp.ArticulationEvent()
ev.type = tmp_tp
- elif isinstance (tmp_tp, tuple):
- ev = tmp_tp[0] ()
+ elif isinstance(tmp_tp, tuple):
+ ev = tmp_tp[0]()
ev.type = tmp_tp[1]
else:
- ev = tmp_tp (mxl_event)
+ ev = tmp_tp(mxl_event)
# Some articulations use the type attribute, other the placement...
dir = None
- if hasattr (mxl_event, 'type') and options.convert_directions:
- dir = musicxml_direction_to_indicator (mxl_event.type)
- if hasattr (mxl_event, 'placement') and options.convert_directions:
- dir = musicxml_direction_to_indicator (mxl_event.placement)
+ if hasattr(mxl_event, 'type') and hasattr(options, 'convert_directions') and options.convert_directions:
+ dir = musicxml_direction_to_indicator(mxl_event.type)
+ if hasattr(mxl_event, 'placement') and hasattr(options, 'convert_directions') and options.convert_directions:
+ dir = musicxml_direction_to_indicator(mxl_event.placement)
if dir:
ev.force_direction = dir
return ev
-def musicxml_dynamics_to_lily_event (dynentry):
+def musicxml_dynamics_to_lily_event(dynentry):
dynamics_available = (
"ppppp", "pppp", "ppp", "pp", "p", "mp", "mf",
- "f", "ff", "fff", "ffff", "fp", "sf", "sff", "sp", "spp", "sfz", "rfz" )
- dynamicsname = dynentry.get_name ()
+ "f", "ff", "fff", "ffff", "fp", "sf", "sff", "sp", "spp", "sfz", "rfz")
+ dynamicsname = dynentry.get_name()
if dynamicsname == "other-dynamics":
- dynamicsname = dynentry.get_text ()
+ dynamicsname = dynentry.get_text()
if not dynamicsname or dynamicsname == "#text":
- return
+ return None
if not dynamicsname in dynamics_available:
# Get rid of - in tag names (illegal in ly tags!)
dynamicstext = dynamicsname
- dynamicsname = string.replace (dynamicsname, "-", "")
+ dynamicsname = string.replace(dynamicsname, "-", "")
additional_definitions[dynamicsname] = dynamicsname + \
" = #(make-dynamic-script \"" + dynamicstext + "\")"
- needed_additional_definitions.append (dynamicsname)
- event = musicexp.DynamicsEvent ()
+ needed_additional_definitions.append(dynamicsname)
+ event = musicexp.DynamicsEvent()
event.type = dynamicsname
return event
# Convert single-color two-byte strings to numbers 0.0 - 1.0
-def hexcolorval_to_nr (hex_val):
+def hexcolorval_to_nr(hex_val):
try:
- v = int (hex_val, 16)
+ v = int(hex_val, 16)
if v == 255:
v = 256
return v / 256.
except ValueError:
return 0.
-def hex_to_color (hex_val):
- res = re.match (r'#([0-9a-f][0-9a-f]|)([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$', hex_val, re.IGNORECASE)
+def hex_to_color(hex_val):
+ res = re.match(r'#([0-9a-f][0-9a-f]|)([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$', hex_val, re.IGNORECASE)
if res:
- return map (lambda x: hexcolorval_to_nr (x), res.group (2, 3, 4))
+ return map(lambda x: hexcolorval_to_nr(x), res.group(2, 3, 4))
else:
return None
-def musicxml_words_to_lily_event (words):
- event = musicexp.TextEvent ()
- text = words.get_text ()
- text = re.sub ('^ *\n? *', '', text)
- text = re.sub (' *\n? *$', '', text)
+def font_size_number_to_lily_command(size):
+ d = {
+ (0, 8): r'\teeny',
+ (8, 10): r'\tiny',
+ (10, 12): r'\small',
+ (12, 16): r'',
+ (16, 24): r'\large',
+ (24, float('inf')): r'\huge',
+ }
+ result = None
+ for r in d.keys():
+ if r[0] <= size < r[1]:
+ result = d[r]
+ break
+ return result
+
+def font_size_word_to_lily_command(size):
+ font_size_dict = {
+ "xx-small": '\\teeny',
+ "x-small": '\\tiny',
+ "small": '\\small',
+ "medium": '',
+ "large": '\\large',
+ "x-large": '\\huge',
+ "xx-large": '\\larger\\huge'
+ }
+ return font_size_dict.get(size, '')
+
+def get_font_size(size):
+ try:
+ size = float(size)
+ return font_size_number_to_lily_command(size)
+ except ValueError:
+ return font_size_word_to_lily_command(size)
+
+def musicxml_words_to_lily_event(words):
+ event = musicexp.TextEvent()
+ text = words.get_text()
+ text = re.sub('^ *\n? *', '', text) #remove white spaces and line breaks before text
+ text = re.sub(' *\n? *$', '', text) #remove white spaces and line breaks before text
event.text = text
- if hasattr (words, 'default-y') and options.convert_directions:
- offset = getattr (words, 'default-y')
+ if hasattr(words, 'default-y') and hasattr(options, 'convert_directions') and options.convert_directions:
+ offset = getattr(words, 'default-y')
try:
- off = string.atoi (offset)
+ off = string.atoi(offset)
if off > 0:
event.force_direction = 1
else:
except ValueError:
event.force_direction = 0
- if hasattr (words, 'font-weight'):
- font_weight = { "normal": '', "bold": '\\bold' }.get (getattr (words, 'font-weight'), '')
+ if hasattr(words, 'font-weight'):
+ font_weight = { "normal": '', "bold": '\\bold' }.get(getattr(words, 'font-weight'), '')
if font_weight:
event.markup += font_weight
- if hasattr (words, 'font-size'):
- size = getattr (words, 'font-size')
- font_size = {
- "xx-small": '\\teeny',
- "x-small": '\\tiny',
- "small": '\\small',
- "medium": '',
- "large": '\\large',
- "x-large": '\\huge',
- "xx-large": '\\larger\\huge'
- }.get (size, '')
+ if hasattr(words, 'font-size'):
+ size = getattr(words, 'font-size')
+ # font_size = font_size_dict.get(size, '')
+ font_size = get_font_size(size)
if font_size:
event.markup += font_size
- if hasattr (words, 'color'):
- color = getattr (words, 'color')
- rgb = hex_to_color (color)
+ if hasattr(words, 'color'):
+ color = getattr(words, 'color')
+ rgb = hex_to_color(color)
if rgb:
event.markup += "\\with-color #(rgb-color %s %s %s)" % (rgb[0], rgb[1], rgb[2])
- if hasattr (words, 'font-style'):
- font_style = { "italic": '\\italic' }.get (getattr (words, 'font-style'), '')
+ if hasattr(words, 'font-style'):
+ font_style = { "italic": '\\italic' }.get(getattr(words, 'font-style'), '')
if font_style:
event.markup += font_style
# convert accordion-registration to lilypond.
# Since lilypond does not have any built-in commands, we need to create
# the markup commands manually and define our own variables.
-# Idea was taken from: http://lsr.di.unimi.it/LSR/Item?id=194
-def musicxml_accordion_to_markup (mxl_event):
+# Idea was taken from: http://lsr.dsi.unimi.it/LSR/Item?id=194
+def musicxml_accordion_to_markup(mxl_event):
commandname = "accReg"
command = ""
- high = mxl_event.get_maybe_exist_named_child ('accordion-high')
+ high = mxl_event.get_maybe_exist_named_child('accordion-high')
if high:
commandname += "H"
command += """\\combine
\\raise #2.5 \\musicglyph #\"accordion.dot\"
"""
- middle = mxl_event.get_maybe_exist_named_child ('accordion-middle')
+ middle = mxl_event.get_maybe_exist_named_child('accordion-middle')
if middle:
# By default, use one dot (when no or invalid content is given). The
# MusicXML spec is quiet about this case...
txt = 1
try:
- txt = string.atoi (middle.get_text ())
+ txt = string.atoi(middle.get_text())
except ValueError:
pass
if txt == 3:
command += """\\combine
\\raise #1.5 \\musicglyph #\"accordion.dot\"
"""
- low = mxl_event.get_maybe_exist_named_child ('accordion-low')
+ low = mxl_event.get_maybe_exist_named_child('accordion-low')
if low:
commandname += "L"
command += """\\combine
command = "\\markup { \\normalsize %s }" % command
# Define the newly built command \accReg[H][MMM][L]
additional_definitions[commandname] = "%s = %s" % (commandname, command)
- needed_additional_definitions.append (commandname)
+ needed_additional_definitions.append(commandname)
return "\\%s" % commandname
-def musicxml_accordion_to_ly (mxl_event):
- txt = musicxml_accordion_to_markup (mxl_event)
+def musicxml_accordion_to_ly(mxl_event):
+ txt = musicxml_accordion_to_markup(mxl_event)
if txt:
- ev = musicexp.MarkEvent (txt)
+ ev = musicexp.MarkEvent(txt)
return ev
return
-def musicxml_rehearsal_to_ly_mark (mxl_event):
- text = mxl_event.get_text ()
+def musicxml_rehearsal_to_ly_mark(mxl_event):
+ text = mxl_event.get_text()
if not text:
return
# default is boxed rehearsal marks!
encl = "box"
- if hasattr (mxl_event, 'enclosure'):
- encl = {"none": None, "square": "box", "circle": "circle" }.get (mxl_event.enclosure, None)
+ if hasattr(mxl_event, 'enclosure'):
+ encl = {"none": None, "square": "box", "circle": "circle" }.get(mxl_event.enclosure, None)
if encl:
text = "\\%s { %s }" % (encl, text)
- ev = musicexp.MarkEvent ("\\markup { %s }" % text)
+ ev = musicexp.MarkEvent("\\markup { %s }" % text)
return ev
-def musicxml_harp_pedals_to_ly (mxl_event):
+def musicxml_harp_pedals_to_ly(mxl_event):
count = 0
result = "\\harp-pedal #\""
- for t in mxl_event.get_named_children ('pedal-tuning'):
- alter = t.get_named_child ('pedal-alter')
+ for t in mxl_event.get_named_children('pedal-tuning'):
+ alter = t.get_named_child('pedal-alter')
if alter:
- val = int (alter.get_text ().strip ())
- result += {1: "v", 0: "-", -1: "^"}.get (val, "")
+ val = int(alter.get_text().strip())
+ result += {1: "v", 0: "-", -1: "^"}.get(val, "")
count += 1
if count == 3:
result += "|"
- ev = musicexp.MarkupEvent ()
+ ev = musicexp.MarkupEvent()
ev.contents = result + "\""
return ev
-def musicxml_eyeglasses_to_ly (mxl_event):
- needed_additional_definitions.append ("eyeglasses")
- return musicexp.MarkEvent ("\\markup { \\eyeglasses }")
+def musicxml_eyeglasses_to_ly(mxl_event):
+ needed_additional_definitions.append("eyeglasses")
+ return musicexp.MarkEvent("\\markup { \\eyeglasses }")
-def next_non_hash_index (lst, pos):
+def next_non_hash_index(lst, pos):
pos += 1
- while pos < len (lst) and isinstance (lst[pos], musicxml.Hash_text):
+ while pos < len(lst) and isinstance(lst[pos], musicxml.Hash_text):
pos += 1
return pos
-def musicxml_metronome_to_ly (mxl_event):
- children = mxl_event.get_all_children ()
+def musicxml_metronome_to_ly(mxl_event):
+ children = mxl_event.get_all_children()
if not children:
return
index = -1
- index = next_non_hash_index (children, index)
- if isinstance (children[index], musicxml.BeatUnit):
+ index = next_non_hash_index(children, index)
+ if isinstance(children[index], musicxml.BeatUnit):
# first form of metronome-mark, using unit and beats/min or other unit
- ev = musicexp.TempoMark ()
- if hasattr (mxl_event, 'parentheses'):
- ev.set_parentheses (mxl_event.parentheses == "yes")
-
- d = musicexp.Duration ()
- d.duration_log = musicxml.musicxml_duration_to_log (children[index].get_text ())
- index = next_non_hash_index (children, index)
- if isinstance (children[index], musicxml.BeatUnitDot):
+ ev = musicexp.TempoMark()
+ if hasattr(mxl_event, 'parentheses'):
+ ev.set_parentheses(mxl_event.parentheses == "yes")
+
+ d = musicexp.Duration()
+ d.duration_log = utilities.musicxml_duration_to_log(
+ children[index].get_text())
+ index = next_non_hash_index(children, index)
+ if isinstance(children[index], musicxml.BeatUnitDot):
d.dots = 1
- index = next_non_hash_index (children, index)
- ev.set_base_duration (d)
- if isinstance (children[index], musicxml.BeatUnit):
+ index = next_non_hash_index(children, index)
+ ev.set_base_duration(d)
+ if isinstance(children[index], musicxml.BeatUnit):
# Form "note = newnote"
- newd = musicexp.Duration ()
- newd.duration_log = musicxml.musicxml_duration_to_log (children[index].get_text ())
- index = next_non_hash_index (children, index)
- if isinstance (children[index], musicxml.BeatUnitDot):
+ newd = musicexp.Duration()
+ newd.duration_log = utilities.musicxml_duration_to_log(
+ children[index].get_text())
+ index = next_non_hash_index(children, index)
+ if isinstance(children[index], musicxml.BeatUnitDot):
newd.dots = 1
- index = next_non_hash_index (children, index)
- ev.set_new_duration (newd)
- elif isinstance (children[index], musicxml.PerMinute):
+ index = next_non_hash_index(children, index)
+ ev.set_new_duration(newd)
+ elif isinstance(children[index], musicxml.PerMinute):
# Form "note = bpm"
try:
- beats = int (children[index].get_text ())
- ev.set_beats_per_minute (beats)
+ beats = int(children[index].get_text())
+ ev.set_beats_per_minute(beats)
except ValueError:
pass
else:
- ly.warning (_ ("Unknown metronome mark, ignoring"))
+ ly.warning(_("Unknown metronome mark, ignoring"))
return
return ev
else:
#TODO: Implement the other (more complex) way for tempo marks!
- ly.warning (_ ("Metronome marks with complex relations (<metronome-note> in MusicXML) are not yet implemented."))
+ ly.warning(_("Metronome marks with complex relations (<metronome-note> in MusicXML) are not yet implemented."))
return
# translate directions into Events, possible values:
}
directions_spanners = [ 'octave-shift', 'pedal', 'wedge', 'dashes', 'bracket' ]
-def musicxml_direction_to_lily (n):
+def musicxml_direction_to_lily(n):
# TODO: Handle the <staff> element!
res = []
# placement applies to all children!
dir = None
- if hasattr (n, 'placement') and options.convert_directions:
- dir = musicxml_direction_to_indicator (n.placement)
+ if hasattr(n, 'placement') and hasattr(options, 'convert_directions') and options.convert_directions:
+ dir = musicxml_direction_to_indicator(n.placement)
dirtype_children = []
# TODO: The direction-type is used for grouping (e.g. dynamics with text),
# so we can't simply flatten them out!
- for dt in n.get_typed_children (musicxml.DirType):
- dirtype_children += dt.get_all_children ()
+ for dt in n.get_typed_children(musicxml.DirType):
+ dirtype_children += dt.get_all_children()
for entry in dirtype_children:
- # backets, dashes, octave shifts. pedal marks, hairpins etc. are spanners:
+ # brackets, dashes, octave shifts. pedal marks, hairpins etc. are spanners:
if entry.get_name() in directions_spanners:
- event = musicxml_spanner_to_lily_event (entry)
+ event = musicxml_spanner_to_lily_event(entry)
if event:
- res.append (event)
+ event.force_direction=dir
+ res.append(event)
continue
# now treat all the "simple" ones, that can be translated using the dict
ev = None
- tmp_tp = directions_dict.get (entry.get_name (), None)
- if isinstance (tmp_tp, str): # string means MarkEvent
- ev = musicexp.MarkEvent (tmp_tp)
- elif isinstance (tmp_tp, tuple): # tuple means (EventClass, "text")
- ev = tmp_tp[0] (tmp_tp[1])
+ tmp_tp = directions_dict.get(entry.get_name(), None)
+ if isinstance(tmp_tp, str): # string means MarkEvent
+ ev = musicexp.MarkEvent(tmp_tp)
+ elif isinstance(tmp_tp, tuple): # tuple means (EventClass, "text")
+ ev = tmp_tp[0](tmp_tp[1])
elif tmp_tp:
- ev = tmp_tp (entry)
+ ev = tmp_tp(entry)
if ev:
# TODO: set the correct direction! Unfortunately, \mark in ly does
# not seem to support directions!
ev.force_direction = dir
- res.append (ev)
+ res.append(ev)
continue
- if entry.get_name () == "dynamics":
- for dynentry in entry.get_all_children ():
- ev = musicxml_dynamics_to_lily_event (dynentry)
+ if entry.get_name() == "dynamics":
+ for dynentry in entry.get_all_children():
+ ev = musicxml_dynamics_to_lily_event(dynentry)
if ev:
- res.append (ev)
-
- return res
-
-def musicxml_frame_to_lily_event (frame):
- ev = musicexp.FretEvent ()
- ev.strings = frame.get_strings ()
- ev.frets = frame.get_frets ()
- #offset = frame.get_first_fret () - 1
- barre = []
- for fn in frame.get_named_children ('frame-note'):
- fret = fn.get_fret ()
- if fret <= 0:
- fret = "o"
- el = [ fn.get_string (), fret ]
- fingering = fn.get_fingering ()
- if fingering >= 0:
- el.append (fingering)
- ev.elements.append (el)
- b = fn.get_barre ()
- if b == 'start':
- barre[0] = el[0] # start string
- barre[2] = el[1] # fret
- elif b == 'stop':
- barre[1] = el[0] # end string
- if barre:
- ev.barre = barre
- return ev
+ ev.force_direction = dir
+ res.append(ev)
-def musicxml_harmony_to_lily (n):
- res = []
- for f in n.get_named_children ('frame'):
- ev = musicxml_frame_to_lily_event (f)
- if ev:
- res.append (ev)
return res
-
notehead_styles_dict = {
'slash': '\'slash',
'triangle': '\'triangle',
'ti': '\'ti',
}
-def musicxml_notehead_to_lily (nh):
- styles = []
-
- # Notehead style
- style = notehead_styles_dict.get (nh.get_text ().strip (), None)
- style_elm = musicexp.NotestyleEvent ()
- if style:
- style_elm.style = style
- if hasattr (nh, 'filled'):
- style_elm.filled = (getattr (nh, 'filled') == "yes")
- if style_elm.style or (style_elm.filled != None):
- styles.append (style_elm)
-
- # parentheses
- if hasattr (nh, 'parentheses') and (nh.parentheses == "yes"):
- styles.append (musicexp.ParenthesizeEvent ())
-
- return styles
-
-def musicxml_chordpitch_to_lily (mxl_cpitch):
- r = musicexp.ChordPitch ()
- r.alteration = mxl_cpitch.get_alteration ()
- r.step = musicxml_step_to_lily (mxl_cpitch.get_step ())
+def musicxml_chordpitch_to_lily(mxl_cpitch):
+ r = musicexp.ChordPitch()
+ r.alteration = mxl_cpitch.get_alteration()
+ r.step = musicxml2ly_conversion.musicxml_step_to_lily(mxl_cpitch.get_step())
return r
chordkind_dict = {
- 'major': '5',
- 'minor': 'm5',
- 'augmented': 'aug5',
- 'diminished': 'dim5',
+ 'major': r'{}:5',
+ 'minor': r'{}:m5',
+ 'augmented': r'{}:aug5',
+ 'diminished': r'{}:dim5',
# Sevenths:
- 'dominant': '7',
- 'dominant-seventh': '7',
- 'major-seventh': 'maj7',
- 'minor-seventh': 'm7',
- 'diminished-seventh': 'dim7',
- 'augmented-seventh': 'aug7',
- 'half-diminished': 'dim5m7',
- 'major-minor': 'maj7m5',
+ 'dominant': r'{}:7',
+ 'dominant-seventh': r'{}:7',
+ 'major-seventh': r'{}:maj7',
+ 'minor-seventh': r'{}:m7',
+ 'diminished-seventh': r'{}:dim7',
+ 'augmented-seventh': r'{}:aug7',
+ 'half-diminished': r'{}:dim5m7',
+ 'major-minor': r'{}:maj7m5',
# Sixths:
- 'major-sixth': '6',
- 'minor-sixth': 'm6',
+ 'major-sixth': r'{}:6',
+ 'minor-sixth': r'{}:m6',
# Ninths:
- 'dominant-ninth': '9',
- 'major-ninth': 'maj9',
- 'minor-ninth': 'm9',
+ 'dominant-ninth': r'{}:9',
+ 'major-ninth': r'{}:maj9',
+ 'minor-ninth': r'{}:m9',
# 11ths (usually as the basis for alteration):
- 'dominant-11th': '11',
- 'major-11th': 'maj11',
- 'minor-11th': 'm11',
+ 'dominant-11th': r'{}:11',
+ 'major-11th': r'{}:maj11',
+ 'minor-11th': r'{}:m11',
# 13ths (usually as the basis for alteration):
- 'dominant-13th': '13.11',
- 'major-13th': 'maj13.11',
- 'minor-13th': 'm13',
+ 'dominant-13th': r'{}:13.11',
+ 'major-13th': r'{}:maj13.11',
+ 'minor-13th': r'{}:m13',
# Suspended:
- 'suspended-second': 'sus2',
- 'suspended-fourth': 'sus4',
+ 'suspended-second': r'{}:sus2',
+ 'suspended-fourth': r'{}:sus4',
# Functional sixths:
# TODO
#'Neapolitan': '???',
#'German': '???',
# Other:
#'pedal': '???',(pedal-point bass)
- 'power': '5^3',
+ 'power': r'\powerChords {}:1.5',
#'Tristan': '???',
- 'other': '1',
+ 'other': r'{}:1',
'none': None,
}
-def musicxml_chordkind_to_lily (kind):
- res = chordkind_dict.get (kind, None)
+def musicxml_chordkind_to_lily(kind):
+ res = chordkind_dict.get(kind, None)
# Check for None, since a major chord is converted to ''
if res == None:
- ly.warning (_ ("Unable to convert chord type %s to lilypond.") % kind)
+ ly.warning(_("Unable to convert chord type %s to lilypond.") % kind)
+ return res
+
+
+# Global variable for guitar string tunings
+string_tunings = None
+
+def musicxml_get_string_tunings(lines):
+ global string_tunings
+ if (string_tunings == None):
+ if not lines:
+ lines = 6
+ string_tunings = [musicexp.Pitch()] * lines
+ for i in range(0, lines):
+ p = musicexp.Pitch()
+ p.step = musicxml2ly_conversion.musicxml_step_to_lily(((("E","A","D","G","B")*(lines/5+1))[0:lines])[i])
+ p.octave = (([-2+int(x%5>1)+2*(x/5) for x in range(0,lines)][0:lines])[i])
+ p.alteration = 0
+ p._force_absolute_pitch = True
+ string_tunings[i] = p
+ string_tunings = string_tunings[::-1]
+ return string_tunings[0:lines]
+
+def musicxml_frame_to_lily_event(frame):
+ ev = musicexp.FretEvent()
+ ev.strings = frame.get_strings()
+ ev.frets = frame.get_frets()
+ #offset = frame.get_first_fret() - 1
+ #offset = frame.get_first_fret()
+ barre = []
+ open_strings = range(1,ev.strings+1)
+ for fn in frame.get_named_children('frame-note'):
+ fret = fn.get_fret()
+ if fret <= 0:
+ fret = "o"
+ el = [ fn.get_string(), fret ]
+ fingering = fn.get_fingering()
+ if fingering >= 0:
+ el.append(fingering)
+ ev.elements.append(el)
+ open_strings.remove(fn.get_string())
+ b = fn.get_barre()
+ if b == 'start':
+ barre.append(el[0]) # start string
+ barre.append(el[1]) # fret
+ elif b == 'stop':
+ barre.insert(1, el[0]) # end string
+ for string in open_strings:
+ ev.elements.append([string, 'x'])
+ ev.elements.sort()
+ ev.elements.reverse()
+ if barre:
+ ev.barre = barre
+ return ev
+
+def musicxml_harmony_to_lily(n):
+ res = []
+ for f in n.get_named_children('frame'):
+ ev = musicxml_frame_to_lily_event(f)
+ if ev:
+ res.append(ev)
+ return res
+
+def musicxml_harmony_to_lily_fretboards(n):
+ res = []
+ frame = n.get_maybe_exist_named_child('frame')
+ if frame:
+ strings = frame.get_strings()
+ if not strings:
+ strings = 6
+ tunings = musicxml_get_string_tunings(strings)
+ ev = musicexp.FretBoardEvent()
+ #barre = []
+ for fn in frame.get_named_children('frame-note'):
+ fbn = musicexp.FretBoardNote()
+ string = fn.get_string()
+ fbn.string = string
+ fingering = fn.get_fingering()
+ if fingering >= 0:
+ fbn.fingering = fingering
+ p = tunings[string-1].copy()
+ p.add_semitones(fn.get_fret())
+ fbn.pitch = p
+ ev.append(fbn)
+ res.append(ev)
return res
-def musicxml_harmony_to_lily_chordname (n):
+def musicxml_harmony_to_lily_chordname(n):
res = []
- root = n.get_maybe_exist_named_child ('root')
+ root = n.get_maybe_exist_named_child('root')
if root:
- ev = musicexp.ChordNameEvent ()
- ev.root = musicxml_chordpitch_to_lily (root)
- kind = n.get_maybe_exist_named_child ('kind')
+ ev = musicexp.ChordNameEvent()
+ ev.root = musicxml_chordpitch_to_lily(root)
+ kind = n.get_maybe_exist_named_child('kind')
if kind:
- ev.kind = musicxml_chordkind_to_lily (kind.get_text ())
+ ev.kind = musicxml_chordkind_to_lily(kind.get_text())
if not ev.kind:
return res
- bass = n.get_maybe_exist_named_child ('bass')
+ bass = n.get_maybe_exist_named_child('bass')
if bass:
- ev.bass = musicxml_chordpitch_to_lily (bass)
- inversion = n.get_maybe_exist_named_child ('inversion')
+ ev.bass = musicxml_chordpitch_to_lily(bass)
+ inversion = n.get_maybe_exist_named_child('inversion')
if inversion:
# TODO: LilyPond does not support inversions, does it?
# require you to know the chord and calculate either the fifth
# pitch (for the first inversion) or the third pitch (for the
# second inversion) so they may not be helpful for musicxml2ly.
- inversion_count = string.atoi (inversion.get_text ())
+ inversion_count = string.atoi(inversion.get_text())
if inversion_count == 1:
# TODO: Calculate the bass note for the inversion...
pass
pass
- for deg in n.get_named_children ('degree'):
- d = musicexp.ChordModification ()
- d.type = deg.get_type ()
- d.step = deg.get_value ()
- d.alteration = deg.get_alter ()
- ev.add_modification (d)
+ for deg in n.get_named_children('degree'):
+ d = musicexp.ChordModification()
+ d.type = deg.get_type()
+ d.step = deg.get_value()
+ d.alteration = deg.get_alter()
+ ev.add_modification(d)
#TODO: convert the user-symbols attribute:
#major: a triangle, like Unicode 25B3
#minor: -, like Unicode 002D
#diminished: (degree), like Unicode 00B0
#half-diminished: (o with slash), like Unicode 00F8
if ev and ev.root:
- res.append (ev)
-
+ res.append(ev)
return res
-def musicxml_figured_bass_note_to_lily (n):
- res = musicexp.FiguredBassNote ()
+def musicxml_figured_bass_note_to_lily(n):
+ res = musicexp.FiguredBassNote()
suffix_dict = { 'sharp' : "+",
'flat' : "-",
'natural' : "!",
'flat-flat' : "--",
'sharp-sharp' : "++",
'slash' : "/" }
- prefix = n.get_maybe_exist_named_child ('prefix')
+ prefix = n.get_maybe_exist_named_child('prefix')
if prefix:
- res.set_prefix (suffix_dict.get (prefix.get_text (), ""))
- fnumber = n.get_maybe_exist_named_child ('figure-number')
+ res.set_prefix(suffix_dict.get(prefix.get_text(), ""))
+ fnumber = n.get_maybe_exist_named_child('figure-number')
if fnumber:
- res.set_number (fnumber.get_text ())
- suffix = n.get_maybe_exist_named_child ('suffix')
+ res.set_number(fnumber.get_text())
+ suffix = n.get_maybe_exist_named_child('suffix')
if suffix:
- res.set_suffix (suffix_dict.get (suffix.get_text (), ""))
- if n.get_maybe_exist_named_child ('extend'):
+ res.set_suffix(suffix_dict.get(suffix.get_text(), ""))
+ if n.get_maybe_exist_named_child('extend'):
# TODO: Implement extender lines (unfortunately, in lilypond you have
# to use \set useBassFigureExtenders = ##t, which turns them on
# globally, while MusicXML has a property for each note...
-def musicxml_figured_bass_to_lily (n):
- if not isinstance (n, musicxml.FiguredBass):
+def musicxml_figured_bass_to_lily(n):
+ if not isinstance(n, musicxml.FiguredBass):
return
- res = musicexp.FiguredBassEvent ()
- for i in n.get_named_children ('figure'):
- note = musicxml_figured_bass_note_to_lily (i)
+ res = musicexp.FiguredBassEvent()
+ for i in n.get_named_children('figure'):
+ note = musicxml_figured_bass_note_to_lily(i)
if note:
- res.append (note)
- dur = n.get_maybe_exist_named_child ('duration')
+ res.append(note)
+ dur = n.get_maybe_exist_named_child('duration')
if dur:
# apply the duration to res
length = Rational(int(dur.get_text()), n._divisions) * Rational(1, 4)
- res.set_real_duration (length)
- duration = rational_to_lily_duration (length)
+ res.set_real_duration(length)
+ duration = musicxml2ly_conversion.rational_to_lily_duration(length)
if duration:
- res.set_duration (duration)
- if hasattr (n, 'parentheses') and n.parentheses == "yes":
- res.set_parentheses (True)
+ res.set_duration(duration)
+ if hasattr(n, 'parentheses') and n.parentheses == "yes":
+ res.set_parentheses(True)
return res
instrument_drumtype_dict = {
'Bass Drum': 'bassdrum',
}
-def musicxml_note_to_lily_main_event (n):
- pitch = None
- duration = None
- event = None
-
- mxl_pitch = n.get_maybe_exist_typed_child (musicxml.Pitch)
- if mxl_pitch:
- pitch = musicxml_pitch_to_lily (mxl_pitch)
- event = musicexp.NoteEvent ()
- event.pitch = pitch
-
- acc = n.get_maybe_exist_named_child ('accidental')
- if acc:
- # AccidentalCautionary in lily has parentheses
- # so treat accidental explicitly in parentheses as cautionary
- if hasattr(acc, 'parentheses') and acc.parentheses == "yes":
- event.cautionary = True
- else:
- event.cautionary = acc.cautionary
- # TODO: Handle editorial accidentals
- # TODO: Handle the level-display setting for displaying brackets/parentheses
-
- elif n.get_maybe_exist_typed_child (musicxml.Unpitched):
- # Unpitched elements have display-step and can also have
- # display-octave.
- unpitched = n.get_maybe_exist_typed_child (musicxml.Unpitched)
- event = musicexp.NoteEvent ()
- event.pitch = musicxml_unpitched_to_lily (unpitched)
-
- elif n.get_maybe_exist_typed_child (musicxml.Rest):
- # rests can have display-octave and display-step, which are
- # treated like an ordinary note pitch
- rest = n.get_maybe_exist_typed_child (musicxml.Rest)
- event = musicexp.RestEvent ()
- if options.convert_rest_positions:
- pitch = musicxml_restdisplay_to_lily (rest)
- event.pitch = pitch
-
- elif n.instrument_name:
- event = musicexp.NoteEvent ()
- drum_type = instrument_drumtype_dict.get (n.instrument_name)
- if drum_type:
- event.drum_type = drum_type
- else:
- n.message (_ ("drum %s type unknown, please add to instrument_drumtype_dict") % n.instrument_name)
- event.drum_type = 'acousticsnare'
-
- else:
- n.message (_ ("cannot find suitable event"))
- if event:
- event.duration = musicxml_duration_to_lily (n)
- noteheads = n.get_named_children ('notehead')
- for nh in noteheads:
- styles = musicxml_notehead_to_lily (nh)
- for s in styles:
- event.add_associated_event (s)
-
- return event
-
-def musicxml_lyrics_to_text (lyrics):
+def musicxml_lyrics_to_text(lyrics, ignoremelismata):
# TODO: Implement text styles for lyrics syllables
continued = False
extended = False
text = ''
- for e in lyrics.get_all_children ():
- if isinstance (e, musicxml.Syllabic):
- continued = e.continued ()
- elif isinstance (e, musicxml.Text):
+ for e in lyrics.get_all_children():
+ if isinstance(e, musicxml.Syllabic):
+ continued = e.continued()
+ elif isinstance(e, musicxml.Text):
# We need to convert soft hyphens to -, otherwise the ascii codec as well
# as lilypond will barf on that character
- text += string.replace( e.get_text(), u'\xad', '-' )
- elif isinstance (e, musicxml.Elision):
+ text += string.replace(e.get_text(), u'\xad', '-')
+ elif isinstance(e, musicxml.Elision):
if text:
text += " "
continued = False
extended = False
- elif isinstance (e, musicxml.Extend):
+ elif isinstance(e, musicxml.Extend):
if text:
text += " "
extended = True
elif text == "_" and extended:
return "__"
elif continued and text:
- return musicxml.escape_ly_output_string (text) + " --"
+ if hasattr(options, 'convert_beaming') and options.convert_beaming:
+ if (ignoremelismata == "on"):
+ return " \set ignoreMelismata = ##t " + utilities.escape_ly_output_string (text)
+ elif (ignoremelismata == "off"):
+ return " " + utilities.escape_ly_output_string(text) + " -- \unset ignoreMelismata"
+ else:
+ return " " + utilities.escape_ly_output_string(text) + " --"
+ else:
+ return " " + utilities.escape_ly_output_string(text) + " -- "
elif continued:
return "--"
elif extended and text:
- return musicxml.escape_ly_output_string (text) + " __"
+ return " " + utilities.escape_ly_output_string(text) + " __"
elif extended:
return "__"
elif text:
- return musicxml.escape_ly_output_string (text)
+ return " " + utilities.escape_ly_output_string(text)
else:
return ""
## TODO
class NegativeSkip:
- def __init__ (self, here, dest):
+ def __init__(self, here, dest):
self.here = here
self.dest = dest
class LilyPondVoiceBuilder:
- def __init__ (self):
+ def __init__(self):
self.elements = []
self.pending_dynamics = []
- self.end_moment = Rational (0)
- self.begin_moment = Rational (0)
- self.pending_multibar = Rational (0)
+ self.end_moment = Rational(0)
+ self.begin_moment = Rational(0)
+ self.pending_multibar = Rational(0)
self.ignore_skips = False
self.has_relevant_elements = False
- self.measure_length = Rational (4, 4)
+ self.measure_length = Rational(4, 4)
+ self.stay_here = False
- def _insert_multibar (self):
- layout_information.set_context_item ('Score', 'skipBars = ##t')
- r = musicexp.MultiMeasureRest ()
+ def _insert_multibar(self):
+ layout_information.set_context_item('Score', 'skipBars = ##t')
+ r = musicexp.MultiMeasureRest()
lenfrac = self.measure_length
- r.duration = rational_to_lily_duration (lenfrac)
+ r.duration = musicxml2ly_conversion.rational_to_lily_duration(lenfrac)
r.duration.factor *= self.pending_multibar / lenfrac
- self.elements.append (r)
+ self.elements.append(r)
self.begin_moment = self.end_moment
self.end_moment = self.begin_moment + self.pending_multibar
- self.pending_multibar = Rational (0)
+ self.pending_multibar = Rational(0)
- def set_measure_length (self, mlen):
+ def set_measure_length(self, mlen):
if (mlen != self.measure_length) and self.pending_multibar:
- self._insert_multibar ()
+ self._insert_multibar()
self.measure_length = mlen
- def add_multibar_rest (self, duration):
+ def add_multibar_rest(self, duration):
self.pending_multibar += duration
- def set_duration (self, duration):
+ def set_duration(self, duration):
self.end_moment = self.begin_moment + duration
- def current_duration (self):
+ def current_duration(self):
return self.end_moment - self.begin_moment
- def add_music (self, music, duration, relevant=True):
- assert isinstance (music, musicexp.Music)
- if self.pending_multibar > Rational (0):
- self._insert_multibar ()
+ def add_pending_dynamics(self):
+ for d in self.pending_dynamics:
+ self.elements.append(d)
+ self.pending_dynamics = []
+
+ def add_music(self, music, duration, relevant=True):
+ assert isinstance(music, musicexp.Music)
+ if self.pending_multibar > Rational(0):
+ self._insert_multibar()
self.has_relevant_elements = self.has_relevant_elements or relevant
- self.elements.append (music)
+
+ if isinstance(music, musicexp.BarLine):
+ if self.pending_dynamics:
+ for d in self.pending_dynamics:
+ if not isinstance(d, (musicexp.SpanEvent, musicexp.DynamicsEvent)):
+ index = self.pending_dynamics.index(d)
+ dyn = self.pending_dynamics.pop(index)
+ self.elements.append(dyn)
+
+ self.elements.append(music)
self.begin_moment = self.end_moment
- self.set_duration (duration)
+ self.set_duration(duration)
# Insert all pending dynamics right after the note/rest:
- if isinstance (music, musicexp.ChordEvent) and self.pending_dynamics:
- for d in self.pending_dynamics:
- music.append (d)
- self.pending_dynamics = []
+ if isinstance(music, musicexp.ChordEvent) and self.pending_dynamics:
+ self.add_pending_dynamics()
# Insert some music command that does not affect the position in the measure
- def add_command (self, command, relevant=True):
- assert isinstance (command, musicexp.Music)
- if self.pending_multibar > Rational (0):
- self._insert_multibar ()
+ def add_command(self, command, relevant=True):
+ assert isinstance(command, musicexp.Music)
+ if self.pending_multibar > Rational(0):
+ self._insert_multibar()
self.has_relevant_elements = self.has_relevant_elements or relevant
- self.elements.append (command)
- def add_barline (self, barline, relevant=False):
+ self.elements.append(command)
+ def add_barline(self, barline, relevant=False):
# Insert only if we don't have a barline already
# TODO: Implement proper merging of default barline and custom bar line
has_relevant = self.has_relevant_elements
if (not (self.elements) or
not (isinstance (self.elements[-1], musicexp.BarLine)) or
- (self.pending_multibar > Rational (0))):
- self.add_music (barline, Rational (0))
+ (self.pending_multibar > Rational(0))):
+
+ self.add_music(barline, Rational(0))
+
self.has_relevant_elements = has_relevant or relevant
- def add_partial (self, command):
+
+ def add_partial(self, command):
self.ignore_skips = True
# insert the partial, but restore relevant_elements (partial is not relevant)
relevant = self.has_relevant_elements
- self.add_command (command)
+ self.add_command(command)
self.has_relevant_elements = relevant
- def add_dynamics (self, dynamic):
+ def add_dynamics(self, dynamic):
# store the dynamic item(s) until we encounter the next note/rest:
- self.pending_dynamics.append (dynamic)
+ self.pending_dynamics.append(dynamic)
- def add_bar_check (self, number):
+ def add_bar_check(self, number):
# re/store has_relevant_elements, so that a barline alone does not
# trigger output for figured bass, chord names
- b = musicexp.BarLine ()
+ b = musicexp.BarLine()
b.bar_number = number
- self.add_barline (b)
-
- def jumpto (self, moment):
- current_end = self.end_moment + self.pending_multibar
- diff = moment - current_end
-
- if diff < Rational (0):
- ly.warning (_ ('Negative skip %s (from position %s to %s)')
- % (diff, current_end, moment))
- diff = Rational (0)
-
- if diff > Rational (0) and not (self.ignore_skips and moment == 0):
- skip = musicexp.SkipEvent()
- duration_factor = 1
- duration_log = {1: 0, 2: 1, 4:2, 8:3, 16:4, 32:5, 64:6, 128:7, 256:8, 512:9}.get (diff.denominator (), -1)
- duration_dots = 0
- # TODO: Use the time signature for skips, too. Problem: The skip
- # might not start at a measure boundary!
- if duration_log > 0: # denominator is a power of 2...
- if diff.numerator () == 3:
- duration_log -= 1
- duration_dots = 1
+ self.add_barline(b)
+
+ def jumpto(self, moment):
+ if (not self.stay_here):
+ current_end = self.end_moment + self.pending_multibar
+ diff = moment - current_end
+
+ if diff < Rational(0):
+ ly.warning(_('Negative skip %s (from position %s to %s)') %
+ (diff, current_end, moment))
+ diff = Rational(0)
+
+ if diff > Rational(0) and not(self.ignore_skips and moment == 0):
+ skip = musicexp.SkipEvent()
+ duration_factor = 1
+ duration_log = {1: 0, 2: 1, 4:2, 8:3, 16:4, 32:5, 64:6, 128:7, 256:8, 512:9}.get(diff.denominator(), -1)
+ duration_dots = 0
+ # TODO: Use the time signature for skips, too. Problem: The skip
+ # might not start at a measure boundary!
+ if duration_log > 0: # denominator is a power of 2...
+ if diff.numerator() == 3:
+ duration_log -= 1
+ duration_dots = 1
+ else:
+ duration_factor = Rational(diff.numerator())
else:
- duration_factor = Rational (diff.numerator ())
- else:
- # for skips of a whole or more, simply use s1*factor
- duration_log = 0
- duration_factor = diff
- skip.duration.duration_log = duration_log
- skip.duration.factor = duration_factor
- skip.duration.dots = duration_dots
-
- evc = musicexp.ChordEvent ()
- evc.elements.append (skip)
- self.add_music (evc, diff, False)
+ # for skips of a whole or more, simply use s1*factor
+ duration_log = 0
+ duration_factor = diff
+ skip.duration.duration_log = duration_log
+ skip.duration.factor = duration_factor
+ skip.duration.dots = duration_dots
- if diff > Rational (0) and moment == 0:
- self.ignore_skips = False
+ evc = musicexp.ChordEvent()
+ evc.elements.append(skip)
+ self.add_music(evc, diff, False)
- def last_event_chord (self, starting_at):
+ if diff > Rational(0) and moment == 0:
+ self.ignore_skips = False
+ def last_event_chord(self, starting_at):
value = None
# if the position matches, find the last ChordEvent, do not cross a bar line!
at = len(self.elements) - 1
while (at >= 0 and
- not isinstance (self.elements[at], musicexp.ChordEvent) and
- not isinstance (self.elements[at], musicexp.BarLine)):
+ not isinstance(self.elements[at], musicexp.ChordEvent) and
+ not isinstance(self.elements[at], musicexp.BarLine)):
at -= 1
if (self.elements
and at >= 0
- and isinstance (self.elements[at], musicexp.ChordEvent)
+ and isinstance(self.elements[at], musicexp.ChordEvent)
and self.begin_moment == starting_at):
value = self.elements[at]
else:
- self.jumpto (starting_at)
+ self.jumpto(starting_at)
value = None
return value
- def correct_negative_skip (self, goto):
+ def correct_negative_skip(self, goto):
self.end_moment = goto
self.begin_moment = goto
- evc = musicexp.ChordEvent ()
- self.elements.append (evc)
-
+ evc = musicexp.ChordEvent()
+ self.elements.append(evc)
class VoiceData:
- def __init__ (self):
+ def __init__(self):
self.voicename = None
self.voicedata = None
self.ly_voice = None
self.figured_bass = None
self.chordnames = None
+ self.fretboards = None
self.lyrics_dict = {}
self.lyrics_order = []
-def measure_length_from_attributes (attr, current_measure_length):
- len = attr.get_measure_length ()
+def measure_length_from_attributes(attr, current_measure_length):
+ len = attr.get_measure_length()
if not len:
len = current_measure_length
return len
-def musicxml_voice_to_lily_voice (voice):
+def music_xml_voice_name_to_lily_name(part_id, name):
+ str = "Part%sVoice%s" % (part_id, name)
+ return musicxml_id_to_lily(str)
+
+def music_xml_lyrics_name_to_lily_name(part_id, name, lyricsnr):
+ str = music_xml_voice_name_to_lily_name(part_id, name)+("Lyrics%s" % lyricsnr)
+ return musicxml_id_to_lily(str)
+
+def music_xml_figuredbass_name_to_lily_name(part_id, voicename):
+ str = music_xml_voice_name_to_lily_name(part_id, voicename)+"FiguredBass"
+ return musicxml_id_to_lily(str)
+
+def music_xml_chordnames_name_to_lily_name(part_id, voicename):
+ str = music_xml_voice_name_to_lily_name(part_id, voicename)+"Chords"
+ return musicxml_id_to_lily(str)
+
+def music_xml_fretboards_name_to_lily_name(part_id, voicename):
+ str = music_xml_voice_name_to_lily_name(part_id, voicename)+"FretBoards"
+ return musicxml_id_to_lily(str)
+
+def get_all_lyric_parts_in_voice(voice):
+ '''
+ Collect the indexes of all lyric parts in this voice.
+ In case not all of the current lyric parts are active (a typical case would be
+ a refrain/chorus), the current implementation inserts \skip-commands in the
+ inactive parts to keep them in sync.
+ '''
+ all_lyric_parts = []
+ for elem in voice._elements:
+ lyrics = elem.get_typed_children(musicxml.Lyric)
+ if lyrics:
+ for lyric in lyrics:
+ index = lyric.number
+ if not index in all_lyric_parts:
+ all_lyric_parts.append(index)
+ return all_lyric_parts
+
+
+def extract_lyrics(voice, lyric_key, lyrics_dict):
+ curr_number = None
+ result = []
+
+ def is_note(elem):
+ return isinstance(elem, musicxml.Note)
+
+ def is_rest(elem):
+ return elem.get_typed_children(musicxml.Rest)
+
+ def is_note_and_not_rest(elem):
+ return is_note(elem) and not is_rest(elem)
+
+ def get_lyric_elements(note):
+ return note.get_typed_children(musicxml.Lyric)
+
+ def has_lyric_belonging_to_lyric_part(note, lyric_part_id):
+ lyric_elements = get_lyric_elements(note)
+ lyric_numbers = [lyric.number for lyric in lyric_elements]
+ return any([lyric_number == lyric_part_id for lyric_number in lyric_numbers])
+
+ for idx, elem in enumerate(voice._elements):
+ lyrics = get_lyric_elements(elem)
+ lyric_keys = [lyric.number for lyric in lyrics]
+ note_has_lyric_belonging_to_lyric_part = lyric_key in lyric_keys
+ # Current note has lyric with 'number' matching 'lyric_key'.
+ if note_has_lyric_belonging_to_lyric_part:
+ for lyric in lyrics:
+ if lyric.number == lyric_key:
+ text = musicxml_lyrics_to_text(lyric, None)
+ result.append(text)
+ # Note has any lyric.
+ elif get_lyric_elements(elem) and \
+ not note_has_lyric_belonging_to_lyric_part:
+ result.append('\skip1 ')
+ # Note does not have any lyric attached to it.
+ elif is_note_and_not_rest(elem):
+ result.append('\skip1 ')
+
+ lyrics_dict[lyric_key].extend(result)
+
+def musicxml_voice_to_lily_voice(voice):
tuplet_events = []
modes_found = {}
lyrics = {}
- return_value = VoiceData ()
+ return_value = VoiceData()
return_value.voicedata = voice
# First pitch needed for relative mode (if selected in command-line options)
pending_figured_bass = []
pending_chordnames = []
+ pending_fretboards = []
# Make sure that the keys in the dict don't get reordered, since
# we need the correct ordering of the lyrics stanzas! By default,
# a dict will reorder its keys
- return_value.lyrics_order = voice.get_lyrics_numbers ()
+ return_value.lyrics_order = voice.get_lyrics_numbers()
for k in return_value.lyrics_order:
lyrics[k] = []
- voice_builder = LilyPondVoiceBuilder ()
- figured_bass_builder = LilyPondVoiceBuilder ()
- chordnames_builder = LilyPondVoiceBuilder ()
- current_measure_length = Rational (4, 4)
- voice_builder.set_measure_length (current_measure_length)
+ voice_builder = LilyPondVoiceBuilder()
+ figured_bass_builder = LilyPondVoiceBuilder()
+ chordnames_builder = LilyPondVoiceBuilder()
+ fretboards_builder = LilyPondVoiceBuilder()
+ current_measure_length = Rational(4, 4)
+ voice_builder.set_measure_length(current_measure_length)
+ in_slur = False
- for n in voice._elements:
+ all_lyric_parts = set(get_all_lyric_parts_in_voice(voice))
+ if lyrics.keys():
+ for number in lyrics.keys():
+ extracted_lyrics = extract_lyrics(voice, number, lyrics)
+
+ for idx, n in enumerate(voice._elements):
tie_started = False
- if n.get_name () == 'forward':
+ if n.get_name() == 'forward':
continue
- staff = n.get_maybe_exist_named_child ('staff')
+ staff = n.get_maybe_exist_named_child('staff')
if staff:
- staff = staff.get_text ()
- if current_staff and staff <> current_staff and not n.get_maybe_exist_named_child ('chord'):
- voice_builder.add_command (musicexp.StaffChange (staff))
+ staff = staff.get_text()
+ if current_staff and staff <> current_staff and not n.get_maybe_exist_named_child('chord'):
+ voice_builder.add_command(musicexp.StaffChange(staff))
current_staff = staff
- if isinstance (n, musicxml.Partial) and n.partial > 0:
- a = musicxml_partial_to_lily (n.partial)
+ if isinstance(n, musicxml.Partial) and n.partial > 0:
+ a = musicxml_partial_to_lily(n.partial)
if a:
- voice_builder.add_partial (a)
- figured_bass_builder.add_partial (a)
- chordnames_builder.add_partial (a)
+ voice_builder.add_partial(a)
+ figured_bass_builder.add_partial(a)
+ chordnames_builder.add_partial(a)
+ fretboards_builder.add_partial(a)
continue
- is_chord = n.get_maybe_exist_named_child ('chord')
- is_after_grace = (isinstance (n, musicxml.Note) and n.is_after_grace ());
+ is_chord = n.get_maybe_exist_named_child('chord')
+ is_after_grace =(isinstance(n, musicxml.Note) and n.is_after_grace());
if not is_chord and not is_after_grace:
try:
- voice_builder.jumpto (n._when)
- figured_bass_builder.jumpto (n._when)
- chordnames_builder.jumpto (n._when)
+ voice_builder.jumpto(n._when)
+ figured_bass_builder.jumpto(n._when)
+ chordnames_builder.jumpto(n._when)
+ fretboards_builder.jumpto(n._when)
except NegativeSkip, neg:
- voice_builder.correct_negative_skip (n._when)
- figured_bass_builder.correct_negative_skip (n._when)
- chordnames_builder.correct_negative_skip (n._when)
- n.message (_ ("Negative skip found: from %s to %s, difference is %s") % (neg.here, neg.dest, neg.dest - neg.here))
-
- if isinstance (n, musicxml.Barline):
- barlines = musicxml_barline_to_lily (n)
+ voice_builder.correct_negative_skip(n._when)
+ figured_bass_builder.correct_negative_skip(n._when)
+ chordnames_builder.correct_negative_skip(n._when)
+ fretboards_builder.correct_negative_skip(n._when)
+ n.message(_("Negative skip found: from %s to %s, difference is %s") % (neg.here, neg.dest, neg.dest - neg.here))
+
+ if isinstance(n, musicxml.Barline):
+ barlines = n.to_lily_object()
for a in barlines:
- if isinstance (a, musicexp.BarLine):
- voice_builder.add_barline (a)
- figured_bass_builder.add_barline (a, False)
- chordnames_builder.add_barline (a, False)
- elif isinstance (a, RepeatMarker) or isinstance (a, EndingMarker):
- voice_builder.add_command (a)
- figured_bass_builder.add_barline (a, False)
- chordnames_builder.add_barline (a, False)
+ if isinstance(a, musicexp.BarLine):
+ voice_builder.add_barline(a)
+ figured_bass_builder.add_barline(a, False)
+ chordnames_builder.add_barline(a, False)
+ fretboards_builder.add_barline(a, False)
+ elif isinstance(a, musicxml2ly_conversion.RepeatMarker) or isinstance(a, musicxml2ly_conversion.EndingMarker):
+ voice_builder.add_command(a)
+ figured_bass_builder.add_barline(a, False)
+ chordnames_builder.add_barline(a, False)
+ fretboards_builder.add_barline(a, False)
continue
-
- if isinstance (n, musicxml.Print):
- for a in musicxml_print_to_lily (n):
- voice_builder.add_command (a, False)
+ if isinstance(n, musicxml.Print):
+ for a in musicxml_print_to_lily(n):
+ voice_builder.add_command(a, False)
continue
# Continue any multimeasure-rests before trying to add bar checks!
# Don't handle new MM rests yet, because for them we want bar checks!
- rest = n.get_maybe_exist_typed_child (musicxml.Rest)
- if (rest and rest.is_whole_measure ()
- and voice_builder.pending_multibar > Rational (0)):
- voice_builder.add_multibar_rest (n._duration)
+ rest = n.get_maybe_exist_typed_child(musicxml.Rest)
+ if (rest and rest.is_whole_measure()
+ and voice_builder.pending_multibar > Rational(0)):
+ voice_builder.add_multibar_rest(n._duration)
continue
-
# print a bar check at the beginning of each measure!
- if n.is_first () and n._measure_position == Rational (0) and n != voice._elements[0]:
+ if n.is_first() and n._measure_position == Rational(0) and n != voice._elements[0]:
try:
- num = int (n.get_parent ().number)
+ num = int(n.get_parent().number)
except ValueError:
num = 0
if num > 0:
- voice_builder.add_bar_check (num)
- figured_bass_builder.add_bar_check (num)
- chordnames_builder.add_bar_check (num)
+ voice_builder.add_bar_check(num)
+ figured_bass_builder.add_bar_check(num)
+ chordnames_builder.add_bar_check(num)
+ fretboards_builder.add_bar_check(num)
+
+ if isinstance(n, musicxml.Direction):
+ # check if Direction already has been converted in another voice.
+ if n.converted:
+ continue
+ else:
+ n.converted = True
+ for direction in musicxml_direction_to_lily(n):
+ if direction.wait_for_note():
+ voice_builder.add_dynamics(direction)
+ else:
+ voice_builder.add_command(direction)
+ continue
# Start any new multimeasure rests
- if (rest and rest.is_whole_measure ()):
- voice_builder.add_multibar_rest (n._duration)
- continue
-
-
- if isinstance (n, musicxml.Direction):
- for a in musicxml_direction_to_lily (n):
- if a.wait_for_note ():
- voice_builder.add_dynamics (a)
- else:
- voice_builder.add_command (a)
+ if (rest and rest.is_whole_measure()):
+ if pending_chordnames:
+ chordnames_builder.jumpto(n._when)
+ chordnames_builder.stay_here = True
+ if pending_figured_bass:
+ figured_bass_builder.jumpto(n._when)
+ figured_bass_builder.stay_here = True
+ if pending_fretboards:
+ fretboards_builder.jumpto(n._when)
+ fretboards_builder.stay_here = True
+ voice_builder.add_multibar_rest(n._duration)
continue
- if isinstance (n, musicxml.Harmony):
- for a in musicxml_harmony_to_lily (n):
- if a.wait_for_note ():
- voice_builder.add_dynamics (a)
- else:
- voice_builder.add_command (a)
- for a in musicxml_harmony_to_lily_chordname (n):
- pending_chordnames.append (a)
+ if isinstance(n, musicxml.Harmony):
+ if (options.fretboards):
+ # Makes fretboard diagrams in a separate FretBoards voice
+ for a in musicxml_harmony_to_lily_fretboards(n):
+ pending_fretboards.append(a)
+ else:
+ # Makes markup fretboard-diagrams inside the voice
+ for a in musicxml_harmony_to_lily(n):
+ if a.wait_for_note():
+ voice_builder.add_dynamics(a)
+ else:
+ voice_builder.add_command(a)
+ for a in musicxml_harmony_to_lily_chordname(n):
+ pending_chordnames.append(a)
continue
- if isinstance (n, musicxml.FiguredBass):
- a = musicxml_figured_bass_to_lily (n)
+ if isinstance(n, musicxml.FiguredBass):
+ a = musicxml_figured_bass_to_lily(n)
if a:
- pending_figured_bass.append (a)
+ pending_figured_bass.append(a)
continue
- if isinstance (n, musicxml.Attributes):
- for a in musicxml_attributes_to_lily (n):
- voice_builder.add_command (a)
- measure_length = measure_length_from_attributes (n, current_measure_length)
+ if isinstance(n, musicxml.Attributes):
+ for a in musicxml_attributes_to_lily(n):
+ voice_builder.add_command(a)
+ measure_length = measure_length_from_attributes(n, current_measure_length)
if current_measure_length != measure_length:
current_measure_length = measure_length
- voice_builder.set_measure_length (current_measure_length)
+ voice_builder.set_measure_length(current_measure_length)
continue
if not n.__class__.__name__ == 'Note':
- n.message (_ ('unexpected %s; expected %s or %s or %s') % (n, 'Note', 'Attributes', 'Barline'))
+ n.message(_('unexpected %s; expected %s or %s or %s') % (n, 'Note', 'Attributes', 'Barline'))
continue
- main_event = musicxml_note_to_lily_main_event (n)
+# if not hasattr(conversion_settings, 'convert_rest_positions'):
+# conversion_settings.convert_rest_positions = True
+
+ main_event = n.to_lily_object(
+ convert_stem_directions=conversion_settings.convert_stem_directions,
+ convert_rest_positions=conversion_settings.convert_rest_positions)
+
if main_event and not first_pitch:
first_pitch = main_event.pitch
# ignore lyrics for notes inside a slur, tie, chord or beam
- ignore_lyrics = inside_slur or is_tied or is_chord or is_beamed
+ ignore_lyrics = is_tied or is_chord #or is_beamed or inside_slur
- if main_event and hasattr (main_event, 'drum_type') and main_event.drum_type:
+ if main_event and hasattr(main_event, 'drum_type') and main_event.drum_type:
modes_found['drummode'] = True
- ev_chord = voice_builder.last_event_chord (n._when)
+ ev_chord = voice_builder.last_event_chord(n._when)
if not ev_chord:
ev_chord = musicexp.ChordEvent()
- voice_builder.add_music (ev_chord, n._duration)
+ voice_builder.add_music(ev_chord, n._duration)
# For grace notes:
- grace = n.get_maybe_exist_typed_child (musicxml.Grace)
- if n.is_grace ():
- is_after_grace = ev_chord.has_elements () or n.is_after_grace ();
- is_chord = n.get_maybe_exist_typed_child (musicxml.Chord)
+ grace = n.get_maybe_exist_typed_child(musicxml.Grace)
+ if n.is_grace():
+ is_after_grace = ev_chord.has_elements() or n.is_after_grace();
+ is_chord = n.get_maybe_exist_typed_child(musicxml.Chord)
grace_chord = None
# whether we have a chord or not, obtain either a new ChordEvent or
# the previous one to create a chord
if is_after_grace:
- if ev_chord.after_grace_elements and n.get_maybe_exist_typed_child (musicxml.Chord):
- grace_chord = ev_chord.after_grace_elements.get_last_event_chord ()
+ if ev_chord.after_grace_elements and n.get_maybe_exist_typed_child(musicxml.Chord):
+ grace_chord = ev_chord.after_grace_elements.get_last_event_chord()
if not grace_chord:
- grace_chord = musicexp.ChordEvent ()
- ev_chord.append_after_grace (grace_chord)
- elif n.is_grace ():
- if ev_chord.grace_elements and n.get_maybe_exist_typed_child (musicxml.Chord):
- grace_chord = ev_chord.grace_elements.get_last_event_chord ()
+ grace_chord = musicexp.ChordEvent()
+ ev_chord.append_after_grace(grace_chord)
+ elif n.is_grace():
+ if ev_chord.grace_elements and n.get_maybe_exist_typed_child(musicxml.Chord):
+ grace_chord = ev_chord.grace_elements.get_last_event_chord()
if not grace_chord:
- grace_chord = musicexp.ChordEvent ()
- ev_chord.append_grace (grace_chord)
+ grace_chord = musicexp.ChordEvent()
+ ev_chord.append_grace(grace_chord)
- if hasattr (grace, 'slash') and not is_after_grace:
+ if hasattr(grace, 'slash') and not is_after_grace:
# TODO: use grace_type = "appoggiatura" for slurred grace notes
if grace.slash == "yes":
ev_chord.grace_type = "acciaccatura"
# now that we have inserted the chord into the grace music, insert
# everything into that chord instead of the ev_chord
ev_chord = grace_chord
- ev_chord.append (main_event)
+ ev_chord.append(main_event)
ignore_lyrics = True
else:
- ev_chord.append (main_event)
+ ev_chord.append(main_event)
# When a note/chord has grace notes (duration==0), the duration of the
# event chord is not yet known, but the event chord was already added
# with duration 0. The following correct this when we hit the real note!
- if voice_builder.current_duration () == 0 and n._duration > 0:
- voice_builder.set_duration (n._duration)
+ if voice_builder.current_duration() == 0 and n._duration > 0:
+ voice_builder.set_duration(n._duration)
# if we have a figured bass, set its voice builder to the correct position
# and insert the pending figures
if pending_figured_bass:
try:
- figured_bass_builder.jumpto (n._when)
+ figured_bass_builder.jumpto(n._when)
+ if (figured_bass_builder.stay_here):
+ figured_bass_builder.stay_here = False
except NegativeSkip, neg:
pass
for fb in pending_figured_bass:
# if a duration is given, use that, otherwise the one of the note
dur = fb.real_duration
if not dur:
- dur = ev_chord.get_length ()
+ dur = ev_chord.get_length()
if not fb.duration:
- fb.duration = ev_chord.get_duration ()
- figured_bass_builder.add_music (fb, dur)
+ fb.duration = ev_chord.get_duration()
+ figured_bass_builder.add_music(fb, dur)
pending_figured_bass = []
if pending_chordnames:
try:
- chordnames_builder.jumpto (n._when)
+ chordnames_builder.jumpto(n._when)
+ if (chordnames_builder.stay_here):
+ chordnames_builder.stay_here = False
except NegativeSkip, neg:
pass
for cn in pending_chordnames:
# Assign the duration of the EventChord
- cn.duration = ev_chord.get_duration ()
- chordnames_builder.add_music (cn, ev_chord.get_length ())
+ cn.duration = ev_chord.get_duration()
+ chordnames_builder.add_music(cn, ev_chord.get_length())
pending_chordnames = []
- notations_children = n.get_typed_children (musicxml.Notations)
+ if pending_fretboards:
+ try:
+ fretboards_builder.jumpto(n._when)
+ if (fretboards_builder.stay_here):
+ fretboards_builder.stay_here = False
+ except NegativeSkip, neg:
+ pass
+ for fb in pending_fretboards:
+ # Assign the duration of the EventChord
+ fb.duration = ev_chord.get_duration()
+ fretboards_builder.add_music(fb, ev_chord.get_length())
+ pending_fretboards = []
+
+ notations_children = n.get_typed_children(musicxml.Notations)
tuplet_event = None
span_events = []
# accidental-mark | other-notation
for notations in notations_children:
for tuplet_event in notations.get_tuplets():
- time_mod = n.get_maybe_exist_typed_child (musicxml.Time_modification)
- tuplet_events.append ((ev_chord, tuplet_event, time_mod))
+ time_mod = n.get_maybe_exist_typed_child(musicxml.Time_modification)
+ tuplet_events.append((ev_chord, tuplet_event, time_mod))
# First, close all open slurs, only then start any new slur
# TODO: Record the number of the open slur to dtermine the correct
# closing slur!
- endslurs = [s for s in notations.get_named_children ('slur')
- if s.get_type () in ('stop')]
+ endslurs = [s for s in notations.get_named_children('slur')
+ if s.get_type() in ('stop')]
if endslurs and not inside_slur:
- endslurs[0].message (_ ('Encountered closing slur, but no slur is open'))
+ endslurs[0].message(_('Encountered closing slur, but no slur is open'))
elif endslurs:
- if len (endslurs) > 1:
- endslurs[0].message (_ ('Cannot have two simultaneous (closing) slurs'))
+ if len(endslurs) > 1:
+ endslurs[0].message(_('Cannot have two simultaneous (closing) slurs'))
# record the slur status for the next note in the loop
inside_slur = False
- lily_ev = musicxml_spanner_to_lily_event (endslurs[0])
- ev_chord.append (lily_ev)
+ lily_ev = musicxml_spanner_to_lily_event(endslurs[0])
+ ev_chord.append(lily_ev)
- startslurs = [s for s in notations.get_named_children ('slur')
- if s.get_type () in ('start')]
+ startslurs = [s for s in notations.get_named_children('slur')
+ if s.get_type() in('start')]
if startslurs and inside_slur:
- startslurs[0].message (_ ('Cannot have a slur inside another slur'))
+ startslurs[0].message(_('Cannot have a slur inside another slur'))
elif startslurs:
- if len (startslurs) > 1:
- startslurs[0].message (_ ('Cannot have two simultaneous slurs'))
+ if len(startslurs) > 1:
+ startslurs[0].message(_('Cannot have two simultaneous slurs'))
# record the slur status for the next note in the loop
inside_slur = True
- lily_ev = musicxml_spanner_to_lily_event (startslurs[0])
- ev_chord.append (lily_ev)
+ lily_ev = musicxml_spanner_to_lily_event(startslurs[0])
+ ev_chord.append(lily_ev)
if not grace:
- mxl_tie = notations.get_tie ()
+ mxl_tie = notations.get_tie()
if mxl_tie and mxl_tie.type == 'start':
- ev_chord.append (musicexp.TieEvent ())
+ ev_chord.append(musicexp.TieEvent())
is_tied = True
tie_started = True
else:
is_tied = False
- fermatas = notations.get_named_children ('fermata')
+ fermatas = notations.get_named_children('fermata')
for a in fermatas:
- ev = musicxml_fermata_to_lily_event (a)
+ ev = musicxml_fermata_to_lily_event(a)
if ev:
- ev_chord.append (ev)
+ ev_chord.append(ev)
- arpeggiate = notations.get_named_children ('arpeggiate')
+ arpeggiate = notations.get_named_children('arpeggiate')
for a in arpeggiate:
- ev = musicxml_arpeggiate_to_lily_event (a)
+ ev = musicxml_arpeggiate_to_lily_event(a)
if ev:
- ev_chord.append (ev)
+ ev_chord.append(ev)
- arpeggiate = notations.get_named_children ('non-arpeggiate')
+ arpeggiate = notations.get_named_children('non-arpeggiate')
for a in arpeggiate:
- ev = musicxml_nonarpeggiate_to_lily_event (a)
+ ev = musicxml_nonarpeggiate_to_lily_event(a)
if ev:
- ev_chord.append (ev)
+ ev_chord.append(ev)
- glissandos = notations.get_named_children ('glissando')
- glissandos += notations.get_named_children ('slide')
+ glissandos = notations.get_named_children('glissando')
+ glissandos += notations.get_named_children('slide')
for a in glissandos:
- ev = musicxml_spanner_to_lily_event (a)
+ ev = musicxml_spanner_to_lily_event(a)
if ev:
- ev_chord.append (ev)
+ ev_chord.append(ev)
# accidental-marks are direct children of <notation>!
- for a in notations.get_named_children ('accidental-mark'):
- ev = musicxml_articulation_to_lily_event (a)
+ for a in notations.get_named_children('accidental-mark'):
+ ev = musicxml_articulation_to_lily_event(a)
if ev:
- ev_chord.append (ev)
+ ev_chord.append(ev)
# Articulations can contain the following child elements:
# accent | strong-accent | staccato | tenuto |
# trill-mark | turn | delayed-turn | inverted-turn |
# shake | wavy-line | mordent | inverted-mordent |
# schleifer | tremolo | other-ornament, accidental-mark
- ornaments = notations.get_named_children ('ornaments')
- ornaments += notations.get_named_children ('articulations')
- ornaments += notations.get_named_children ('technical')
+ ornaments = notations.get_named_children('ornaments')
+ ornaments += notations.get_named_children('articulations')
+ ornaments += notations.get_named_children('technical')
for a in ornaments:
- for ch in a.get_all_children ():
- ev = musicxml_articulation_to_lily_event (ch)
+ for ch in a.get_all_children():
+ ev = musicxml_articulation_to_lily_event(ch)
if ev:
- ev_chord.append (ev)
+ ev_chord.append(ev)
- dynamics = notations.get_named_children ('dynamics')
+ dynamics = notations.get_named_children('dynamics')
for a in dynamics:
- for ch in a.get_all_children ():
- ev = musicxml_dynamics_to_lily_event (ch)
+ for ch in a.get_all_children():
+ ev = musicxml_dynamics_to_lily_event(ch)
if ev:
- ev_chord.append (ev)
+ ev_chord.append(ev)
- mxl_beams = [b for b in n.get_named_children ('beam')
- if (b.get_type () in ('begin', 'end')
- and b.is_primary ())]
+ mxl_beams = [b for b in n.get_named_children('beam')
+ if (b.get_type() in('begin', 'end')
+ and b.is_primary())]
if mxl_beams and not conversion_settings.ignore_beaming:
- beam_ev = musicxml_spanner_to_lily_event (mxl_beams[0])
+ beam_ev = musicxml_spanner_to_lily_event(mxl_beams[0])
if beam_ev:
- ev_chord.append (beam_ev)
+ ev_chord.append(beam_ev)
if beam_ev.span_direction == -1: # beam and thus melisma starts here
is_beamed = True
elif beam_ev.span_direction == 1: # beam and thus melisma ends here
is_beamed = False
- # Extract the lyrics
- if not rest and not ignore_lyrics:
- note_lyrics_processed = []
- note_lyrics_elements = n.get_typed_children (musicxml.Lyric)
- for l in note_lyrics_elements:
- if l.get_number () < 0:
- for k in lyrics.keys ():
- lyrics[k].append (musicxml_lyrics_to_text (l))
- note_lyrics_processed.append (k)
- else:
- lyrics[l.number].append(musicxml_lyrics_to_text (l))
- note_lyrics_processed.append (l.number)
- for lnr in lyrics.keys ():
- if not lnr in note_lyrics_processed:
- lyrics[lnr].append ("\skip4")
-
# Assume that a <tie> element only lasts for one note.
# This might not be correct MusicXML interpretation, but works for
# most cases and fixes broken files, which have the end tag missing
if is_tied and not tie_started:
is_tied = False
- ## force trailing mm rests to be written out.
- voice_builder.add_music (musicexp.ChordEvent (), Rational (0))
+ # force trailing mm rests to be written out.
+ # voice_builder.add_music (musicexp.ChordEvent(), Rational(0))
+ if hasattr(options, 'shift_meter') and options.shift_meter:
+ for event in voice_builder.elements:
+ if isinstance(event, musicexp.TimeSignatureChange):
+ sd = []
+ for i in range(0,5):
+ sd.append(musicexp.ShiftDurations())
+ sd[i].set_shift_durations_parameters(event)
+ break;
- ly_voice = group_tuplets (voice_builder.elements, tuplet_events)
- ly_voice = group_repeats (ly_voice)
+ ly_voice = group_tuplets(voice_builder.elements, tuplet_events)
+ ly_voice = group_repeats(ly_voice)
- seq_music = musicexp.SequentialMusic ()
+ seq_music = musicexp.SequentialMusic()
- if 'drummode' in modes_found.keys ():
+ if 'drummode' in modes_found.keys():
## \key <pitch> barfs in drummode.
ly_voice = [e for e in ly_voice
if not isinstance(e, musicexp.KeySignatureChange)]
seq_music.elements = ly_voice
- for k in lyrics.keys ():
- return_value.lyrics_dict[k] = musicexp.Lyrics ()
+ for k in lyrics.keys():
+ return_value.lyrics_dict[k] = musicexp.Lyrics()
return_value.lyrics_dict[k].lyrics_syllables = lyrics[k]
- if len (modes_found) > 1:
- ly.warning (_ ('cannot simultaneously have more than one mode: %s') % modes_found.keys ())
+ if len(modes_found) > 1:
+ ly.warning(_('cannot simultaneously have more than one mode: %s') % modes_found.keys())
+
+ if hasattr(options, 'shift_meter') and options.shift_meter:
+ sd[-1].element = seq_music
+ seq_music = sd[-1]
+ sd.pop()
- if options.relative:
- v = musicexp.RelativeMusic ()
+ if hasattr(options, 'relative') and options.relative:
+ v = musicexp.RelativeMusic()
v.element = seq_music
v.basepitch = first_pitch
seq_music = v
return_value.ly_voice = seq_music
- for mode in modes_found.keys ():
+ for mode in modes_found.keys():
v = musicexp.ModeChangingMusicWrapper()
v.element = seq_music
v.mode = mode
# create \figuremode { figured bass elements }
if figured_bass_builder.has_relevant_elements:
- fbass_music = musicexp.SequentialMusic ()
- fbass_music.elements = group_repeats (figured_bass_builder.elements)
+ fbass_music = musicexp.SequentialMusic()
+ fbass_music.elements = group_repeats(figured_bass_builder.elements)
v = musicexp.ModeChangingMusicWrapper()
v.mode = 'figuremode'
v.element = fbass_music
+ if hasattr(options, 'shift_meter') and options.shift_meter:
+ sd[-1].element = v
+ v = sd[-1]
+ sd.pop()
return_value.figured_bass = v
# create \chordmode { chords }
if chordnames_builder.has_relevant_elements:
- cname_music = musicexp.SequentialMusic ()
- cname_music.elements = group_repeats (chordnames_builder.elements)
+ cname_music = musicexp.SequentialMusic()
+ cname_music.elements = group_repeats(chordnames_builder.elements)
v = musicexp.ModeChangingMusicWrapper()
v.mode = 'chordmode'
v.element = cname_music
+ if hasattr(options, 'shift_meter') and options.shift_meter:
+ sd[-1].element = v
+ v = sd[-1]
+ sd.pop()
return_value.chordnames = v
+ # create diagrams for FretBoards engraver
+ if fretboards_builder.has_relevant_elements:
+ fboard_music = musicexp.SequentialMusic()
+ fboard_music.elements = group_repeats(fretboards_builder.elements)
+ v = musicexp.MusicWrapper()
+ v.element = fboard_music
+ if hasattr(options, 'shift_meter') and options.shift_meter:
+ sd[-1].element = v
+ v = sd[-1]
+ sd.pop()
+ return_value.fretboards = v
+
+ # coll = []
+ # pending = []
+
+ # for elt in return_value.ly_voice.element.elements:
+ # if isinstance(elt, musicexp.TimeScaledMusic):
+ # print elt.element.elements
+ # pending.append(elt)
+ # else:
+ # coll.append(elt)
+
+ # if pending:
+ # coll.extend(pending)
+
+ # return_value.ly_voice.element.elements = coll
+
return return_value
-def musicxml_id_to_lily (id):
+def musicxml_id_to_lily(id):
digits = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five',
'Six', 'Seven', 'Eight', 'Nine', 'Ten']
for digit in digits:
- d = digits.index (digit)
- id = re.sub ('%d' % d, digit, id)
+ d = digits.index(digit)
+ id = re.sub('%d' % d, digit, id)
- id = re.sub ('[^a-zA-Z]', 'X', id)
+ id = re.sub('[^a-zA-Z]', 'X', id)
return id
-def musicxml_pitch_to_lily (mxl_pitch):
- p = musicexp.Pitch ()
- p.alteration = mxl_pitch.get_alteration ()
- p.step = musicxml_step_to_lily (mxl_pitch.get_step ())
- p.octave = mxl_pitch.get_octave () - 4
- return p
-
-def musicxml_unpitched_to_lily (mxl_unpitched):
- p = None
- step = mxl_unpitched.get_step ()
- if step:
- p = musicexp.Pitch ()
- p.step = musicxml_step_to_lily (step)
- octave = mxl_unpitched.get_octave ()
- if octave and p:
- p.octave = octave - 4
- return p
-
-def musicxml_restdisplay_to_lily (mxl_rest):
- p = None
- step = mxl_rest.get_step ()
- if step:
- p = musicexp.Pitch ()
- p.step = musicxml_step_to_lily (step)
- octave = mxl_rest.get_octave ()
- if octave and p:
- p.octave = octave - 4
- return p
-
-def voices_in_part (part):
+def voices_in_part(part):
"""Return a Name -> Voice dictionary for PART"""
- part.interpret ()
- part.extract_voices ()
- voices = part.get_voices ()
- part_info = part.get_staff_attributes ()
+ part.interpret()
+ part.extract_voices()
+ voices = part.get_voices()
+ part_info = part.get_staff_attributes()
return (voices, part_info)
-def voices_in_part_in_parts (parts):
+def voices_in_part_in_parts(parts):
"""return a Part -> Name -> Voice dictionary"""
- # don't crash if p doesn't have an id (that's invalid MusicXML,
- # but such files are out in the wild!
+ # don't crash if Part doesn't have an id (that's invalid MusicXML,
+ # but such files are out in the wild!)
dictionary = {}
for p in parts:
- voices = voices_in_part (p)
- if (hasattr (p, "id")):
+ voices = voices_in_part(p)
+ if (hasattr(p, "id")):
dictionary[p.id] = voices
else:
# TODO: extract correct part id from other sources
return dictionary;
-def get_all_voices (parts):
- all_voices = voices_in_part_in_parts (parts)
+def get_all_voices(parts):
+ all_voices = voices_in_part_in_parts(parts)
all_ly_voices = {}
all_ly_staffinfo = {}
- for p, (name_voice, staff_info) in all_voices.items ():
+ for p, (name_voice, staff_info) in all_voices.items():
part_ly_voices = {}
- for n, v in name_voice.items ():
- ly.progress (_ ("Converting to LilyPond expressions..."), True)
+ for n, v in name_voice.items():
+ ly.progress(_("Converting to LilyPond expressions..."), True)
# musicxml_voice_to_lily_voice returns (lily_voice, {nr->lyrics, nr->lyrics})
- part_ly_voices[n] = musicxml_voice_to_lily_voice (v)
+ voice = musicxml_voice_to_lily_voice(v)
+ part_ly_voices[n] = voice
all_ly_voices[p] = part_ly_voices
all_ly_staffinfo[p] = staff_info
return (all_ly_voices, all_ly_staffinfo)
-def option_parser ():
- p = ly.get_option_parser (usage = _ ("musicxml2ly [OPTION]... FILE.xml"),
- description =
-_ ("""Convert MusicXML from FILE.xml to LilyPond input.
+def option_parser():
+ p = ly.get_option_parser(usage=_("musicxml2ly [OPTION]... FILE.xml"),
+ description=
+_("""Convert MusicXML from FILE.xml to LilyPond input.
If the given filename is -, musicxml2ly reads from the command line.
"""), add_help_option=False)
p.add_option("-h", "--help",
action="help",
- help=_ ("show this help and exit"))
+ help=_("show this help and exit"))
- p.version = ('''%prog (LilyPond) @TOPLEVEL_VERSION@\n\n'''
+ p.version = ('%prog (LilyPond) ' + lilypond_version + '\n\n'
+
-_ ("""Copyright (c) 2005--2015 by
+_ ("""Copyright (c) 2005--2016 by
Han-Wen Nienhuys <hanwen@xs4all.nl>,
Jan Nieuwenhuizen <janneke@gnu.org> and
Reinhold Kainhofer <reinhold@kainhofer.com>
+ Patrick L. Schmidt <pls@philomelos.net>
"""
+
"""
action="version",
help=_ ("show version number and exit"))
- p.add_option ('-v', '--verbose',
+ p.add_option('-v', '--verbose',
action="callback",
callback=ly.handle_loglevel_option,
callback_args=("DEBUG",),
- help = _ ("be verbose"))
-
- p.add_option ('', '--lxml',
- action = "store_true",
- default = False,
- dest = "use_lxml",
- help = _ ("use lxml.etree; uses less memory and cpu time"))
-
- p.add_option ('-z', '--compressed',
- action = "store_true",
- dest = 'compressed',
- default = False,
- help = _ ("input file is a zip-compressed MusicXML file"))
-
- p.add_option ('-r', '--relative',
- action = "store_true",
- default = True,
- dest = "relative",
- help = _ ("convert pitches in relative mode (default)"))
-
- p.add_option ('-a', '--absolute',
- action = "store_false",
- dest = "relative",
- help = _ ("convert pitches in absolute mode"))
-
- p.add_option ('-l', '--language',
- metavar = _ ("LANG"),
- action = "store",
- help = _ ("use LANG for pitch names, e.g. 'deutsch' for note names in German"))
-
- p.add_option ("--loglevel",
+ help=_ ("be verbose"))
+
+ p.add_option('', '--lxml',
+ action="store_true",
+ default=False,
+ dest="use_lxml",
+ help=_ ("use lxml.etree; uses less memory and cpu time"))
+
+ p.add_option('-z', '--compressed',
+ action="store_true",
+ dest='compressed',
+ default=False,
+ help=_ ("input file is a zip-compressed MusicXML file"))
+
+ p.add_option('-r', '--relative',
+ action="store_true",
+ default=True,
+ dest="relative",
+ help=_ ("convert pitches in relative mode (default)"))
+
+ p.add_option('-a', '--absolute',
+ action="store_false",
+ dest="relative",
+ help=_ ("convert pitches in absolute mode"))
+
+ p.add_option('-l', '--language',
+ metavar=_ ("LANG"),
+ action="store",
+ help=_ ("use LANG for pitch names, e.g. 'deutsch' for note names in German"))
+
+ p.add_option("--loglevel",
help=_ ("Print log messages according to LOGLEVEL "
"(NONE, ERROR, WARNING, PROGRESS (default), DEBUG)"),
metavar=_ ("LOGLEVEL"),
callback=ly.handle_loglevel_option,
type='string')
- p.add_option ('--nd', '--no-articulation-directions',
- action = "store_false",
- default = True,
- dest = "convert_directions",
- help = _ ("do not convert directions (^, _ or -) for articulations, dynamics, etc."))
-
- p.add_option ('--nrp', '--no-rest-positions',
- action = "store_false",
- default = True,
- dest = "convert_rest_positions",
- help = _ ("do not convert exact vertical positions of rests"))
-
- p.add_option ('--npl', '--no-page-layout',
- action = "store_false",
- default = True,
- dest = "convert_page_layout",
- help = _ ("do not convert the exact page layout and breaks"))
-
- p.add_option ('--no-beaming',
- action = "store_false",
- default = True,
- dest = "convert_beaming",
- help = _ ("do not convert beaming information, use lilypond's automatic beaming instead"))
-
- p.add_option ('-o', '--output',
- metavar = _ ("FILE"),
- action = "store",
- default = None,
- type = 'string',
- dest = 'output_name',
- help = _ ("set output filename to FILE, stdout if -"))
-
- p.add_option ('-m', '--midi',
- action = "store_true",
- default = False,
- dest = "midi",
- help = _("activate midi-block"))
-
- p.add_option_group ('',
- description = (
+ p.add_option('--nd', '--no-articulation-directions',
+ action="store_false",
+ default=True,
+ dest="convert_directions",
+ help=_ ("do not convert directions (^, _ or -) for articulations, dynamics, etc."))
+
+ p.add_option('--nrp', '--no-rest-positions',
+ action="store_false",
+ default=True,
+ dest="convert_rest_positions",
+ help=_ ("do not convert exact vertical positions of rests"))
+
+ p.add_option('--nsb', '--no-system-breaks',
+ action="store_false",
+ default=True,
+ dest="convert_system_breaks",
+ help=_ ("ignore system breaks"))
+
+ p.add_option('--npb', '--no-page-breaks',
+ action="store_false",
+ default=True,
+ dest="convert_page_breaks",
+ help=_ ("ignore page breaks"))
+
+ p.add_option('--npm', '--no-page-margins',
+ action="store_false",
+ default=True,
+ dest="convert_page_margins",
+ help=_ ("ignore page margins"))
+
+ p.add_option('--npl', '--no-page-layout',
+ action="store_false",
+ default=True,
+ dest="convert_page_layout",
+ help=_ ("do not convert the exact page layout and breaks (shortcut for \"--nsb --npb --npm\" options)"))
+
+ p.add_option('--nsd', '--no-stem-directions',
+ action="store_false",
+ default=True,
+ dest="convert_stem_directions",
+ help=_ ("ignore stem directions from MusicXML, use lilypond's automatic stemming instead"))
+
+ p.add_option('--nb', '--no-beaming',
+ action="store_false",
+ default=True,
+ dest="convert_beaming",
+ help=_ ("do not convert beaming information, use lilypond's automatic beaming instead"))
+
+ p.add_option('-o', '--output',
+ metavar=_ ("FILE"),
+ action="store",
+ default=None,
+ type='string',
+ dest='output_name',
+ help=_ ("set output filename to FILE, stdout if -"))
+
+ p.add_option('-m', '--midi',
+ action="store_true",
+ default=False,
+ dest="midi",
+ help=_("activate midi-block in .ly file"))
+
+ # transpose function
+ p.add_option('--transpose',
+ metavar=_ ("TOPITCH"),
+ action="store",
+ dest="transpose",
+ help=_ ("set pitch to transpose by the interval between pitch 'c' and TOPITCH"))
+
+ # time signature changing function
+ p.add_option('--sm', '--shift-meter',
+ metavar=_ ("BEATS/BEATTYPE"),
+ action="store",
+ dest="shift_meter",
+ help=_ ("change the length|duration of notes as a function of a given time signature to make the score look faster or slower, (eg. '4/4' or '2/2')"))
+
+ # switch tabstaff clef
+ p.add_option('--tc', '--tab-clef',
+ metavar=_ ("TABCLEFNAME"),
+ action="store",
+ dest="tab_clef",
+ help=_ ("switch between two versions of tab clefs (\"tab\" and \"moderntab\")"))
+
+ # StringNumber stencil on/off
+ p.add_option('--sn', '--string-numbers',
+ metavar=_ ("t[rue]/f[alse]"),
+ action="store",
+ dest="string_numbers",
+ help=_ ("deactivate string number stencil with --string-numbers f[alse]. Default is t[rue]"))
+
+ # StringNumber stencil on/off
+ p.add_option('--fb', '--fretboards',
+ action="store_true",
+ default=False,
+ dest="fretboards",
+ help=_("converts '<frame>' events to a separate FretBoards voice instead of markups"))
+
+ p.add_option_group('',
+ description=(
_ ("Report bugs via %s")
% 'http://post.gmane.org/post.php'
'?group=gmane.comp.gnu.lilypond.bugs') + '\n')
return p
-def music_xml_voice_name_to_lily_name (part_id, name):
- str = "Part%sVoice%s" % (part_id, name)
- return musicxml_id_to_lily (str)
-
-def music_xml_lyrics_name_to_lily_name (part_id, name, lyricsnr):
- str = "Part%sVoice%sLyrics%s" % (part_id, name, lyricsnr)
- return musicxml_id_to_lily (str)
-
-def music_xml_figuredbass_name_to_lily_name (part_id, voicename):
- str = "Part%sVoice%sFiguredBass" % (part_id, voicename)
- return musicxml_id_to_lily (str)
-
-def music_xml_chordnames_name_to_lily_name (part_id, voicename):
- str = "Part%sVoice%sChords" % (part_id, voicename)
- return musicxml_id_to_lily (str)
-
def print_voice_definitions (printer, part_list, voices):
for part in part_list:
part_id = part.id
printer.newline()
if voice.chordnames:
cnname = music_xml_chordnames_name_to_lily_name (part_id, name)
- printer.dump ('%s = ' % cnname )
+ printer.dump ('%s = ' % cnname)
voice.chordnames.print_ly (printer)
printer.newline()
for l in voice.lyrics_order:
lname = music_xml_lyrics_name_to_lily_name (part_id, name, l)
- printer.dump ('%s = ' % lname )
+ printer.dump ('%s = ' % lname)
voice.lyrics_dict[l].print_ly (printer)
printer.newline()
if voice.figured_bass:
fbname = music_xml_figuredbass_name_to_lily_name (part_id, name)
- printer.dump ('%s = ' % fbname )
+ printer.dump ('%s = ' % fbname)
voice.figured_bass.print_ly (printer)
printer.newline()
+ if voice.fretboards:
+ fbdname = music_xml_fretboards_name_to_lily_name (part_id, name)
+ printer.dump ('%s = ' % fbdname)
+ voice.fretboards.print_ly (printer)
+ printer.newline()
-
-def uniq_list (l):
- return dict ([(elt, 1) for elt in l]).keys ()
+def uniq_list(l):
+ return dict([(elt, 1) for elt in l]).keys()
# format the information about the staff in the form
# [staffid,
# ]
# ]
# raw_voices is of the form [(voicename, lyricsids, havefiguredbass)*]
-def format_staff_info (part_id, staff_id, raw_voices):
+def format_staff_info(part_id, staff_id, raw_voices):
voices = []
- for (v, lyricsids, figured_bass, chordnames) in raw_voices:
- voice_name = music_xml_voice_name_to_lily_name (part_id, v)
- voice_lyrics = [music_xml_lyrics_name_to_lily_name (part_id, v, l)
+ for (v, lyricsids, figured_bass, chordnames, fretboards) in raw_voices:
+ voice_name = music_xml_voice_name_to_lily_name(part_id, v)
+ voice_lyrics = [music_xml_lyrics_name_to_lily_name(part_id, v, l)
for l in lyricsids]
figured_bass_name = ''
if figured_bass:
- figured_bass_name = music_xml_figuredbass_name_to_lily_name (part_id, v)
+ figured_bass_name = music_xml_figuredbass_name_to_lily_name(part_id, v)
chordnames_name = ''
if chordnames:
- chordnames_name = music_xml_chordnames_name_to_lily_name (part_id, v)
- voices.append ([voice_name, voice_lyrics, figured_bass_name, chordnames_name])
+ chordnames_name = music_xml_chordnames_name_to_lily_name(part_id, v)
+ fretboards_name = ''
+ if fretboards:
+ fretboards_name = music_xml_fretboards_name_to_lily_name(part_id, v)
+ voices.append([voice_name, voice_lyrics, figured_bass_name, chordnames_name, fretboards_name])
return [staff_id, voices]
-def update_score_setup (score_structure, part_list, voices):
-
+def update_score_setup(score_structure, part_list, voices, parts):
for part_definition in part_list:
part_id = part_definition.id
- nv_dict = voices.get (part_id)
+ nv_dict = voices.get(part_id)
if not nv_dict:
- ly.warning (_ ('unknown part in part-list: %s') % part_id)
+ ly.warning(_('unknown part in part-list: %s') % part_id)
continue
- staves = reduce (lambda x,y: x+ y,
- [voice.voicedata._staves.keys ()
- for voice in nv_dict.values ()],
+ staves = reduce(lambda x, y: x + y,
+ [voice.voicedata._staves.keys()
+ for voice in nv_dict.values()],
[])
staves_info = []
- if len (staves) > 1:
+ if len(staves) > 1:
staves_info = []
- staves = uniq_list (staves)
- staves.sort ()
+ staves = uniq_list(staves)
+ staves.sort()
for s in staves:
- thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames)
- for (voice_name, voice) in nv_dict.items ()
+ thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames, voice.fretboards)
+ for (voice_name, voice) in nv_dict.items()
if voice.voicedata._start_staff == s]
- staves_info.append (format_staff_info (part_id, s, thisstaff_raw_voices))
+ staves_info.append(format_staff_info(part_id, s, thisstaff_raw_voices))
else:
- thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames)
- for (voice_name, voice) in nv_dict.items ()]
- staves_info.append (format_staff_info (part_id, None, thisstaff_raw_voices))
- score_structure.set_part_information (part_id, staves_info)
+ thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames, voice.fretboards)
+ for (voice_name, voice) in nv_dict.items()]
+ staves_info.append(format_staff_info(part_id, None, thisstaff_raw_voices))
+ score_structure.set_part_information(part_id, staves_info)
+
+ sounds = []
+ for part in parts:
+ for measure in part.get_typed_children(musicxml.Measure):
+ for sound in measure.get_typed_children(musicxml.Sound):
+ sounds.append(sound)
+ for direction in measure.get_typed_children(musicxml.Direction):
+ for sound in direction.get_typed_children(musicxml.Sound):
+ sounds.append(sound)
+
+ score_structure.set_tempo('100')
+ if len(sounds) != 0:
+ for sound in sounds:
+ if (sound.get_tempo() != None and sound.get_tempo() != ""):
+ score_structure.set_tempo(sound.get_tempo())
+ break
+
# Set global values in the \layout block, like auto-beaming etc.
-def update_layout_information ():
+def update_layout_information():
if not conversion_settings.ignore_beaming and layout_information:
- layout_information.set_context_item ('Score', 'autoBeaming = ##f')
-
-def print_ly_preamble (printer, filename):
- printer.dump_version ()
- printer.print_verbatim ('%% automatically converted by musicxml2ly from %s\n' % filename)
+ layout_information.set_context_item('Score', 'autoBeaming = ##f')
+ if musicexp.get_string_numbers() == "f":
+ layout_information.set_context_item('Score', '\\override StringNumber #\'stencil = ##f')
+
+# \n\t\t\t\t\\override StringNumber #\'stencil = ##f
+
+def print_ly_preamble(printer, filename):
+ printer.dump_version(lilypond_version)
+ printer.print_verbatim('% automatically converted by musicxml2ly from ' + filename)
+ printer.newline()
+ printer.dump(r'\pointAndClickOff')
+ printer.newline()
+ if options.midi:
+ printer.newline()
+ printer.dump(r'\include "articulate.ly"')
+ printer.newline()
-def print_ly_additional_definitions (printer, filename):
+def print_ly_additional_definitions(printer, filename=None):
if needed_additional_definitions:
- printer.newline ()
- printer.print_verbatim ('%% additional definitions required by the score:')
- printer.newline ()
+ printer.newline()
+ printer.print_verbatim('%% additional definitions required by the score:')
+ printer.newline()
for a in set(needed_additional_definitions):
- printer.print_verbatim (additional_definitions.get (a, ''))
- printer.newline ()
- printer.newline ()
+ printer.print_verbatim(additional_definitions.get(a, ''))
+ printer.newline()
+ printer.newline()
# Read in the tree from the given I/O object (either file or string) and
# demarshall it using the classes from the musicxml.py file
-def read_xml (io_object, use_lxml):
+def read_xml(io_object, use_lxml):
if use_lxml:
import lxml.etree
- tree = lxml.etree.parse (io_object)
- mxl_tree = musicxml.lxml_demarshal_node (tree.getroot ())
+ tree = lxml.etree.parse(io_object)
+ mxl_tree = musicxml.lxml_demarshal_node(tree.getroot())
return mxl_tree
else:
from xml.dom import minidom, Node
doc = minidom.parse(io_object)
node = doc.documentElement
- return musicxml.minidom_demarshal_node (node)
+ return musicxml.minidom_demarshal_node(node)
return None
-def read_musicxml (filename, compressed, use_lxml):
+def read_musicxml(filename, compressed, use_lxml):
raw_string = None
if compressed:
if filename == "-":
- ly.progress (_ ("Input is compressed, extracting raw MusicXML data from stdin"), True)
+ ly.progress(_("Input is compressed, extracting raw MusicXML data from stdin"), True)
# unfortunately, zipfile.ZipFile can't read directly from
# stdin, so copy everything from stdin to a temp file and read
# that. TemporaryFile() will remove the file when it is closed.
tmp = tempfile.TemporaryFile()
sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) # Make sys.stdin binary
- bytes_read = sys.stdin.read (8192)
+ bytes_read = sys.stdin.read(8192)
while bytes_read:
for b in bytes_read:
tmp.write(b)
- bytes_read = sys.stdin.read (8192)
- z = zipfile.ZipFile (tmp, "r")
+ bytes_read = sys.stdin.read(8192)
+ z = zipfile.ZipFile(tmp, "r")
else:
- ly.progress (_ ("Input file %s is compressed, extracting raw MusicXML data") % filename, True)
- z = zipfile.ZipFile (filename, "r")
- container_xml = z.read ("META-INF/container.xml")
+ ly.progress(_("Input file %s is compressed, extracting raw MusicXML data") % filename, True)
+ z = zipfile.ZipFile(filename, "r")
+ container_xml = z.read("META-INF/container.xml")
if not container_xml:
return None
- container = read_xml (StringIO.StringIO (container_xml), use_lxml)
+ container = read_xml(StringIO.StringIO(container_xml), use_lxml)
if not container:
return None
- rootfiles = container.get_maybe_exist_named_child ('rootfiles')
+ rootfiles = container.get_maybe_exist_named_child('rootfiles')
if not rootfiles:
return None
- rootfile_list = rootfiles.get_named_children ('rootfile')
+ rootfile_list = rootfiles.get_named_children('rootfile')
mxml_file = None
- if len (rootfile_list) > 0:
- mxml_file = getattr (rootfile_list[0], 'full-path', None)
+ if len(rootfile_list) > 0:
+ mxml_file = getattr(rootfile_list[0], 'full-path', None)
if mxml_file:
- raw_string = z.read (mxml_file)
+ raw_string = z.read(mxml_file)
if raw_string:
- io_object = StringIO.StringIO (raw_string)
+ io_object = StringIO.StringIO(raw_string)
elif filename == "-":
io_object = sys.stdin
else:
io_object = filename
- return read_xml (io_object, use_lxml)
+ return read_xml(io_object, use_lxml)
-def convert (filename, options):
+def convert(filename, options):
if filename == "-":
- ly.progress (_ ("Reading MusicXML from Standard input ..."), True)
+ ly.progress(_("Reading MusicXML from Standard input ..."), True)
else:
- ly.progress (_ ("Reading MusicXML from %s ...") % filename, True)
+ ly.progress(_("Reading MusicXML from %s ...") % filename, True)
- tree = read_musicxml (filename, options.compressed, options.use_lxml)
- score_information = extract_score_information (tree)
- paper_information = extract_paper_information (tree)
+ tree = read_musicxml(filename, options.compressed, options.use_lxml)
+ score_information = extract_score_information(tree)
+ paper_information = extract_paper_information(tree)
- parts = tree.get_typed_children (musicxml.Part)
- (voices, staff_info) = get_all_voices (parts)
+ parts = tree.get_typed_children(musicxml.Part)
+ (voices, staff_info) = get_all_voices(parts)
score = None
- mxl_pl = tree.get_maybe_exist_typed_child (musicxml.Part_list)
+ mxl_pl = tree.get_maybe_exist_typed_child(musicxml.Part_list)
if mxl_pl:
- score = extract_score_structure (mxl_pl, staff_info)
- part_list = mxl_pl.get_named_children ("score-part")
+ score = extract_score_structure(mxl_pl, staff_info)
+ part_list = mxl_pl.get_named_children("score-part")
# score information is contained in the <work>, <identification> or <movement-title> tags
- update_score_setup (score, part_list, voices)
+ update_score_setup(score, part_list, voices, parts)
# After the conversion, update the list of settings for the \layout block
- update_layout_information ()
+ update_layout_information()
if not options.output_name:
- options.output_name = os.path.basename (filename)
- options.output_name = os.path.splitext (options.output_name)[0]
- elif re.match (".*\.ly", options.output_name):
- options.output_name = os.path.splitext (options.output_name)[0]
+ options.output_name = os.path.basename(filename)
+ options.output_name = os.path.splitext(options.output_name)[0]
+ elif re.match(".*\.ly", options.output_name):
+ options.output_name = os.path.splitext(options.output_name)[0]
#defs_ly_name = options.output_name + '-defs.ly'
output_ly_name = 'Standard output'
else:
output_ly_name = options.output_name + '.ly'
-
- ly.progress (_ ("Output to `%s'") % output_ly_name, True)
+ ly.progress(_("Output to `%s'") % output_ly_name, True)
printer = musicexp.Output_printer()
- #ly.progress (_ ("Output to `%s'") % defs_ly_name, True)
+ #ly.progress(_("Output to `%s'") % defs_ly_name, True)
if (options.output_name == "-"):
- printer.set_file (codecs.getwriter ("utf-8")(sys.stdout))
+ printer.set_file(codecs.getwriter("utf-8")(sys.stdout))
else:
- printer.set_file (codecs.open (output_ly_name, 'wb', encoding='utf-8'))
- print_ly_preamble (printer, filename)
- print_ly_additional_definitions (printer, filename)
+ printer.set_file(codecs.open(output_ly_name, 'wb', encoding='utf-8'))
+ print_ly_preamble(printer, filename)
+ print_ly_additional_definitions(printer, filename)
if score_information:
- score_information.print_ly (printer)
+ score_information.print_ly(printer)
if paper_information and conversion_settings.convert_page_layout:
- paper_information.print_ly (printer)
+ paper_information.print_ly(printer)
if layout_information:
- layout_information.print_ly (printer)
- print_voice_definitions (printer, part_list, voices)
+ layout_information.print_ly(printer)
+ print_voice_definitions(printer, part_list, voices)
+
+ printer.newline()
+ printer.dump("% The score definition")
+ printer.newline()
+ score.print_ly(printer)
+ printer.newline()
- printer.newline ()
- printer.dump ("% The score definition")
- printer.newline ()
- score.print_ly (printer)
- printer.newline ()
+ # Syntax update to current version
+ if (options.output_name != "-"):
+ version = os.popen("lilypond --version | head -1 | cut -d' ' -f3").read().strip()
+ ly.progress(_("Converting to current version (%s) notations ..." % version), True)
+ os.system("convert-ly -e %s 2> /dev/null" % utilities.escape_ly_output_string(output_ly_name))
return voices
-def get_existing_filename_with_extension (filename, ext):
- if os.path.exists (filename):
+def get_existing_filename_with_extension(filename, ext):
+ if os.path.exists(filename):
return filename
newfilename = filename + "." + ext
- if os.path.exists (newfilename):
+ if os.path.exists(newfilename):
return newfilename;
newfilename = filename + ext
- if os.path.exists (newfilename):
+ if os.path.exists(newfilename):
return newfilename;
return ''
-def main ():
+
+def main():
opt_parser = option_parser()
global options
- (options, args) = opt_parser.parse_args ()
+ (options, args) = opt_parser.parse_args()
if not args:
opt_parser.print_usage()
- sys.exit (2)
+ sys.exit(2)
+ # midi-block option
if options.midi:
- musicexp.set_create_midi (options.midi)
+ musicexp.set_create_midi(options.midi)
+
+ # transpose function
+ if options.transpose:
+ musicexp.set_transpose(options.transpose)
+
+ # tab clef option
+ if options.tab_clef:
+ musicexp.set_tab_clef(options.tab_clef)
+
+ # string numbers option
+ if options.string_numbers:
+ musicexp.set_string_numbers(options.string_numbers)
if options.language:
- musicexp.set_pitch_language (options.language)
- needed_additional_definitions.append (options.language)
+ musicexp.set_pitch_language(options.language)
+ needed_additional_definitions.append(options.language)
additional_definitions[options.language] = "\\language \"%s\"\n" % options.language
+
conversion_settings.ignore_beaming = not options.convert_beaming
conversion_settings.convert_page_layout = options.convert_page_layout
+ if conversion_settings.convert_page_layout:
+ conversion_settings.convert_system_breaks = options.convert_system_breaks
+ conversion_settings.convert_page_breaks = options.convert_page_breaks
+ conversion_settings.convert_page_margins = options.convert_page_margins
+ else:
+ conversion_settings.convert_system_breaks = False
+ conversion_settings.convert_page_breaks = False
+ conversion_settings.convert_page_margins = False
+ conversion_settings.convert_stem_directions = options.convert_stem_directions
# Allow the user to leave out the .xml or xml on the filename
basefilename = args[0].decode('utf-8')
if basefilename == "-": # Read from stdin
filename = "-"
else:
- filename = get_existing_filename_with_extension (basefilename, "xml")
+ filename = get_existing_filename_with_extension(basefilename, "xml")
if not filename:
- filename = get_existing_filename_with_extension (basefilename, "mxl")
+ filename = get_existing_filename_with_extension(basefilename, "mxl")
options.compressed = True
- if filename and filename.endswith ("mxl"):
+ if filename and filename.endswith("mxl"):
options.compressed = True
- if filename and (filename == "-" or os.path.exists (filename)):
- voices = convert (filename, options)
+ if filename and (filename == "-" or os.path.exists(filename)):
+ voices = convert(filename, options)
else:
- ly.error (_ ("Unable to find input file %s") % basefilename)
+ ly.error(_("Unable to find input file %s") % basefilename)
+ sys.exit(1)
if __name__ == '__main__':
main()
$(EXECUTABLE): $(O_FILES) $(outdir)/version.hh $(MODULE_LIBS:%=%/$(outdir)/library.a)
$(foreach a, $(MODULE_LIBS), $(MAKE) -C $(a) && ) true
- $(LD) -o $@ $(O_FILES) $(LOADLIBES) $(ALL_LDFLAGS)
+ $(CXX) -o $@ $(O_FILES) $(LOADLIBES) $(ALL_LDFLAGS)
$(TEST_EXECUTABLE): $(TEST_O_FILES) $(TEST_MODULE_LIBS:%=%/$(outdir)/library.a)
$(foreach a, $(TEST_MODULE_LIBS), $(MAKE) -C $(a) && ) true
- $(LD) -o $@ $(TEST_O_FILES) $(TEST_LOADLIBES) $(ALL_LDFLAGS)
+ $(CXX) -o $@ $(TEST_O_FILES) $(TEST_LOADLIBES) $(ALL_LDFLAGS)
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2016-03-29.15}
+\def\texinfoversion{2016-05-26.20}
%
% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
\everyjob{\message{[Texinfo version \texinfoversion]}%
\catcode`+=\active \catcode`\_=\active}
+% LaTeX's \typeout. This ensures that the messages it is used for
+% are identical in format to the corresponding ones from latex/pdflatex.
+\def\typeout{\immediate\write17}%
+
\chardef\other=12
% We never want plain's \outer definition of \+ in Texinfo.
%
% PDF outline support
%
- \pdfmakepagedesttrue \relax
% Emulate the primitive of pdfTeX
\def\pdfdest name#1 xyz{%
\special{pdf:dest (name#1) [@thispage /XYZ @xpos @ypos]}%
% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
% Unless we're in typewriter, use \ecfont because the CM text fonts do
% not have braces, and we don't want to switch into math.
-\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
-\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
+\def\mylbrace{{\ifmonospace\char123\else\ensuremath\lbrace\fi}}
+\def\myrbrace{{\ifmonospace\char125\else\ensuremath\rbrace\fi}}
\let\{=\mylbrace \let\lbracechar=\{
\let\}=\myrbrace \let\rbracechar=\}
\begingroup
\fi
}
+% Like \expandablevalue, but completely expandable (the \message in the
+% definition above operates at the execution level of TeX). Used when
+% writing to auxiliary files, due to the expansion that \write does.
+%
+% NB flag names containing - or _ may not work here.
+\def\dummyvalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ [No value for ``#1'']%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
% with @set.
%
\def\docodeindex#1{\edef\indexname{#1}\parsearg\docodeindexxxx}
\def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}}
-% Used when writing an index entry out to an index file, to prevent
+% Used when writing an index entry out to an index file to prevent
% expansion of Texinfo commands that can appear in an index entry.
%
\def\indexdummies{%
%
% We want to disable all macros so that they are not expanded by \write.
\macrolist
+ \let\value\dummyvalue
%
\normalturnoffactive
- %
- % Handle some cases of @value -- where it does not contain any
- % (non-fully-expandable) commands.
- \makevalueexpandable
}
% \commondummiesnofonts: common to \commondummies and \indexnofonts.
\ifx\suffix\indexisfl\def\suffix{f1}\fi
% Open the file
\immediate\openout\csname#1indfile\endcsname \jobname.\suffix
- % Using \immediate here prevents an object entering into the current box,
- % which could confound checks such as those in \safewhatsit for preceding
- % skips.
+ % Using \immediate above here prevents an object entering into the current
+ % box, which could confound checks such as those in \safewhatsit for
+ % preceding skips.
+ \typeout{Writing index file \jobname.\suffix}%
\fi}
\def\indexisfl{fl}
% index. The easiest way to prevent this problem is to make sure
% there is some text.
\putwordIndexNonexistent
+ \typeout{No file \jobname.\indexname s.}%
\else
\catcode`\\ = 0
- \escapechar = `\\
%
% If the index file exists but is empty, then \openin leaves \ifeof
% false. We have to make TeX try to read something from the file, so
% 1 and 2 (the page numbers aren't printed), and so are the first
% two pages of the document. Thus, we'd have two destinations named
% `1', and two named `2'.
- \ifpdf \global\pdfmakepagedesttrue \fi
+ \ifpdf
+ \global\pdfmakepagedesttrue
+ \else
+ \ifx\XeTeXrevision\thisisundefined
+ \else
+ \global\pdfmakepagedesttrue
+ \fi
+ \fi
}
\catcode `\>=\other
\catcode `\`=\other
\catcode `\'=\other
- \escapechar=`\\
%
% ' is active in math mode (mathcode"8000). So reset it, and all our
% other math active characters (just in case), to plain's definitions.
% alias because \c means cedilla in @tex or @math
\let\texinfoc=\c
+\newcount\savedcatcodeone
+\newcount\savedcatcodetwo
+
% Used at the time of macro expansion.
% Argument is macro body with arguments substituted
\def\scanmacro#1{%
\newlinechar`\^^M
\def\xeatspaces{\eatspaces}%
%
+ % Temporarily undo catcode changes of \printindex. Set catcode of @ to
+ % 0 so that @-commands in macro expansions aren't printed literally when
+ % formatting an index file, where \ is used as the escape character.
+ \savedcatcodeone=\catcode`\@
+ \savedcatcodetwo=\catcode`\\
+ \catcode`\@=0
+ \catcode`\\=\active
+ %
% Process the macro body under the current catcode regime.
- \scantokens{#1\texinfoc}\aftermacro%
+ \scantokens{#1@texinfoc}\aftermacro%
+ %
+ \catcode`\@=\savedcatcodeone
+ \catcode`\\=\savedcatcodetwo
%
% The \texinfoc is to remove the \newlinechar added by \scantokens, and
% can be noticed by \parsearg.
{%
\requireauxfile
\atdummies % preserve commands, but don't expand them
+ % match definition in \xrdef, \refx, \xrefX.
+ \def\value##1{##1}%
\edef\writexrdef##1##2{%
\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
##1}{##2}}% these are parameters of \writexrdef
% include an _ in the xref name, etc.
\indexnofonts
\turnoffactive
+ \def\value##1{##1}%
\expandafter\global\expandafter\let\expandafter\Xthisreftitle
\csname XR#1-title\endcsname
}%
\fi\fi\fi
}
-% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
-% If its value is nonempty, SUFFIX is output afterward.
-%
+% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX
+% is output afterwards if non-empty.
\def\refx#1#2{%
\requireauxfile
{%
\indexnofonts
\otherbackslash
+ \def\value##1{##1}%
\expandafter\global\expandafter\let\expandafter\thisrefX
\csname XR#1\endcsname
}%
#2% Output the suffix in any case.
}
-% This is the macro invoked by entries in the aux file. Usually it's
-% just a \def (we prepend XR to the control sequence name to avoid
-% collisions). But if this is a float type, we have more work to do.
+% This is the macro invoked by entries in the aux file. Define a control
+% sequence for a cross-reference target (we prepend XR to the control sequence
+% name to avoid collisions). The value is the page number. If this is a float
+% type, we have more work to do.
%
\def\xrdef#1#2{%
- {% The node name might contain 8-bit characters, which in our current
- % implementation are changed to commands like @'e. Don't let these
- % mess up the control sequence name.
+ {% Expand the node or anchor name to remove control sequences.
+ % \turnoffactive stops 8-bit characters being changed to commands
+ % like @'e. \refx does the same to retrieve the value in the definition.
\indexnofonts
\turnoffactive
+ \def\value##1{##1}%
\xdef\safexrefname{#1}%
}%
%
" some handy key mappings
"
" <F4> save & make and play midi with timidity
-map <buffer> <F4> :w<Return>:se makeprg=lilypond\ \"%<\"<Return>:make<Return>:!timidity "%<.midi"<Return>
+map <buffer> <F4> :w<Return>:setl makeprg=lilypond\ \"%<\"<Return>:make<Return>:!timidity "%<.midi"<Return>
"
" <F5> save & make
-map <buffer> <F5> :w<Return>:se makeprg=lilypond\ \"%<\"<Return>:make<Return>
+map <buffer> <F5> :w<Return>:setl makeprg=lilypond\ \"%<\"<Return>:make<Return>
"
" <F6> view pdf with ghostview
map <buffer> <F6> :!gv --watch "%<.pdf" &<Return>
map <buffer> <F8> :cn<Return>
"
" <F9> make
-map <buffer> <F9> :w<Return>:se makeprg=make\ -k<Return>:make<Return>
+map <buffer> <F9> :w<Return>:setl makeprg=make\ -k<Return>:make<Return>
"
" <F10> menu
source $VIMRUNTIME/menu.vim