]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge commit '4d0d5f7'
authorJoe Neeman <joeneeman@gmail.com>
Mon, 20 Aug 2007 22:38:57 +0000 (08:38 +1000)
committerJoe Neeman <joeneeman@gmail.com>
Mon, 20 Aug 2007 22:38:57 +0000 (08:38 +1000)
Documentation/user/GNUmakefile
python/musicexp.py
python/musicxml.py
scm/define-grob-interfaces.scm
scm/define-grob-properties.scm
scm/document-backend.scm
scripts/musicxml2ly.py

index a0d3abacbe35a427d79f91f60dcc3fd885073c0d..278061df3958f124cececaac1dd5893ff64d11c3 100644 (file)
@@ -74,6 +74,7 @@ ifneq ($(patsubst %/local,%,$(DESTDIR)$(prefix)),/usr)
 else
        -$(INSTALL) -d $(DESTDIR)$(package_infodir)
        -install-info --remove --info-dir=$(infodir) $(outdir)/lilypond.info
+       -install-info --remove --info-dir=$(infodir) $(outdir)/lilypond-program.info
        install-info --info-dir=$(infodir) $(outdir)/lilypond.info
        (cd $(package_infodir) && ln -sf $(webdir)/Documentation/user/*png .)
 endif
index e7b3870425cabd4344322035742174c9b533c6d5..b543dbc2e6056d5267406d485c13137d4dc25d15 100644 (file)
@@ -498,7 +498,78 @@ class TieEvent(Event):
     def ly_expression (self):
         return '~'
 
+
+class HairpinEvent (Event):
+    def __init__ (self, type):
+        self.type = type
+    def hairpin_to_ly (self):
+        val = ''
+        tp = { 0: '\!', 1: '\<', -1: '\>' }.get (self.type)
+        if tp:
+            val += tp
+        return val
+    
+    def ly_expression (self):
+        return self.hairpin_to_ly ()
     
+    def print_ly (self, printer):
+        val = self.hairpin_to_ly ()
+        if val:
+            printer.dump (val)
+
+
+
+class DynamicsEvent (Event):
+    def __init__ (self):
+        self.type = None
+        self.available_commands = [ "ppppp", "pppp", "ppp", "pp", "p", 
+                                    "mp", "mf", 
+                                    "f", "ff", "fff", "ffff", 
+                                    "fp", "sf", "sff", "sp", "spp", "sfz", "rfz" ];
+    def ly_expression (self):
+        if self.type == None:
+            return;
+        elif self.type in self.available_commands:
+            return '\%s' % self.type
+        else:
+            return '\markup{ \dynamic %s }' % self.type
+        
+    def print_ly (self, printer):
+        if self.type == None:
+            return
+        elif self.type in self.available_commands:
+            printer.dump ("\\%s" % self.type)
+        else:
+            printer.dump ("\\markup{ \\dynamic %s }" % self.type)
+
+
+class ArticulationEvent (Event):
+    def __init__ (self):
+        self.type = None
+        self.force_direction = None
+
+    def direction_mod (self):
+        dirstr = { 1: '^', -1: '_', 0: '-' }.get (self.force_direction)
+        if dirstr:
+            return dirstr
+        else:
+            return ''
+
+    def ly_expression (self):
+        return '%s\\%s' % (self.direction_mod (), self.type)
+
+
+class TremoloEvent (Event):
+    def __init__ (self):
+        self.bars = 0;
+
+    def ly_expression (self):
+        str=''
+        if self.bars > 0:
+            str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
+        return str
+
+
 class RhythmicEvent(Event):
     def __init__ (self):
         Event.__init__ (self)
index 3466473c4352a879c2d1259e46f4f3b6d90f6f4a..132ce5a752021d2798d60f0c86425873cb37b628 100644 (file)
@@ -39,10 +39,13 @@ class Xml_node:
             p = p.get_parent ()
         
     def get_typed_children (self, klass):
-       return [c for c in self._children if isinstance(c, 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 (class_dict[nm])
+       return self.get_typed_children (class_dict.get (nm))
 
     def get_named_child (self, nm):
        return self.get_maybe_exist_named_child (nm)
@@ -354,14 +357,16 @@ class Part (Music_xml_node):
        for n in elements:
            voice_id = n.get_maybe_exist_typed_child (class_dict['voice'])
 
-           if not (voice_id or isinstance (n, Attributes)):
+            # TODO: If the first element of a voice is a dynamics entry,
+            #       then voice_id is not yet set! Thus it will currently be ignored
+           if not (voice_id or isinstance (n, Attributes) or isinstance (n, Direction) ):
                continue
 
            if isinstance (n, Attributes) and not start_attr:
                start_attr = n
                continue
 
-           if isinstance (n, Attributes):
+           if isinstance (n, Attributes) or isinstance (n, Direction):
                for v in voices.values ():
                    v.add_element (n)
                continue
@@ -450,6 +455,34 @@ class Staff (Music_xml_node):
 class Instrument (Music_xml_node):
     pass
 
+class Fermata (Music_xml_node):
+    pass
+class Dynamics (Music_xml_node):
+    pass
+class Articulations (Music_xml_node):
+    pass
+class Accent (Music_xml_node):
+    pass
+class Staccato (Music_xml_node):
+    pass
+class Tenuto (Music_xml_node):
+    pass
+class Tremolo (Music_xml_node):
+    pass
+class Technical (Music_xml_node):
+    pass
+class Ornaments (Music_xml_node):
+    pass
+
+
+class Direction (Music_xml_node):
+    pass
+class DirType (Music_xml_node):
+    pass
+class Wedge (Music_xml_node):
+    pass
+
+
 ## need this, not all classes are instantiated
 ## for every input file.
 class_dict = {
@@ -477,6 +510,18 @@ class_dict = {
        'type': Type,
        'part-list': Part_list,
        'staff': Staff,
+        'fermata': Fermata,
+        'articulations': Articulations,
+        'accent': Accent,
+        'staccato': Staccato,
+        'tenuto': Tenuto,
+        'tremolo': Tremolo,
+        'technical': Technical,
+        'ornaments': Ornaments,
+        'direction': Direction,
+        'direction-type': DirType,
+        'dynamics': Dynamics,
+        'wedge': Wedge
 }
 
 def name2class_name (name):
index 707344e605658a72659ac211ef476ec6b6e89d52..a6dfb3a63d6725a8df66b1a18ba582e039481cfa 100644 (file)
 
 (ly:add-interface
  'accidental-suggestion-interface
-   "An accidental, printed as a suggestion (typically: vertically over a note)"
-   '())
+ "An accidental, printed as a suggestion (typically: vertically over a
+note)."
+ '())
 
 (ly:add-interface
  'bass-figure-interface
- "A bass figure text"
+ "A bass figure text."
  '(implicit))
 
+(ly:add-interface
+ 'bass-figure-alignment-interface
+ "Align a bass figure."
+ '())
+
 (ly:add-interface
  'bend-after-interface
  "A doit or drop."
  '(thickness delta-position))
 
-(ly:add-interface
- 'bass-figure-alignment-interface
- ""
- '())
-
 (ly:add-interface
  'dynamic-interface
  "Any kind of loudness sign"
  '())
"Any kind of loudness sign."
+ '())
 
 (ly:add-interface
  'dynamic-line-spanner-interface
  "Dynamic line spanner"
  '(avoid-slur))
"Dynamic line spanner."
+ '(avoid-slur))
 
 (ly:add-interface
  'dynamic-text-spanner-interface
  "Dynamic text spanner"
  '(text))
"Dynamic text spanner."
+ '(text))
 
 (ly:add-interface
  'finger-interface
- "A fingering instruction"
+ "A fingering instruction."
  '())
 
 (ly:add-interface
  'fret-diagram-interface
- "A fret diagram"
-
+ "A fret diagram."
  '(align-dir barre-type dot-color dot-radius finger-code fret-count
 label-dir number-type size string-count xo-font-magnification
 mute-string open-string orientation string-fret-finger-combinations
@@ -65,28 +65,17 @@ thickness))
 
 (ly:add-interface
  'key-cancellation-interface
- "A key cancellation"
- '())
-
-(ly:add-interface
- 'ligature-interface
- "A ligature"
- '())
-
-(ly:add-interface
- 'key-cancellation-interface
- "A key cancellation"
+ "A key cancellation."
  '())
 
 (ly:add-interface
  'ligature-bracket-interface
- "A bracket indicating a ligature in the original edition"
+ "A bracket indicating a ligature in the original edition."
  '(width thickness height))
 
-
 (ly:add-interface
- 'lyric-syllable-interface
- "A single piece of lyrics"
+ 'ligature-interface
+ "A ligature."
  '())
 
 (ly:add-interface
@@ -94,14 +83,19 @@ thickness))
  "Any object that is related to lyrics."
  '())
 
+(ly:add-interface
+ 'lyric-syllable-interface
+ "A single piece of lyrics."
+ '())
+
 (ly:add-interface
  'mark-interface
- "A rehearsal mark"
+ "A rehearsal mark."
  '())
 
 (ly:add-interface
  'metronome-mark-interface
- "A metronome mark"
+ "A metronome mark."
  '())
 
 (ly:add-interface
@@ -110,8 +104,8 @@ thickness))
  '(bound-padding))
 
 (ly:add-interface
-'note-name-interface
- "Note name"
+ 'note-name-interface
+ "Note names."
  '(style))
 
 (ly:add-interface
@@ -121,60 +115,48 @@ thickness))
 
 (ly:add-interface
  'parentheses-interface
- "Parentheses for other objects"
+ "Parentheses for other objects."
  '(padding stencils))
 
 (ly:add-interface
  'piano-pedal-interface
- "A piano pedal sign"
+ "A piano pedal sign."
  '())
 
 (ly:add-interface
  'piano-pedal-script-interface
- "A piano pedal sign, fixed size"
+ "A piano pedal sign, fixed size."
  '())
 
 (ly:add-interface
  'pitched-trill-interface
-   "A note head to indicate trill pitches"
-   '(accidental-grob))
-
-(ly:add-interface
- 'trill-pitch-accidental-interface
- "An accidental for trill pitch"
- '()
- )
-
-(ly:add-interface
- 'trill-spanner-interface
- "An accidental for trill pitch"
- '())
+ "A note head to indicate trill pitches."
+ '(accidental-grob))
 
 (ly:add-interface
  'rhythmic-grob-interface
- "Any object with a duration. Used to determine which grobs are
+ "Any object with a duration.  Used to determine which grobs are
 interesting enough to maintain a hara-kiri staff."
  '())
 
-
 (ly:add-interface
  'spacing-options-interface
- "Supports setting of spacing variables"
+ "Supports setting of spacing variables."
  '(spacing-increment shortest-duration-space))
 
 (ly:add-interface
  'stanza-number-interface
- "A stanza number, to be put in from of a lyrics line"
+ "A stanza number, to be put in from of a lyrics line."
  '())
 
 (ly:add-interface
  'string-number-interface
- "A string number instruction"
+ "A string number instruction."
  '())
 
 (ly:add-interface
  'stroke-finger-interface
- "A right hand finger instruction"
+ "A right hand finger instruction."
  '(digit-names))
 
 (ly:add-interface
@@ -185,18 +167,27 @@ interesting enough to maintain a hara-kiri staff."
 ;;; todo: this is not typesetting info. Move to interpretation.
 (ly:add-interface
  'tablature-interface
- "An interface for any notes set in a tablature staff"
+ "An interface for any notes set in a tablature staff."
+ '())
+
+(ly:add-interface
+ 'trill-spanner-interface
+ "A trill spanner."
+ '())
+
+(ly:add-interface
+ 'trill-pitch-accidental-interface
+ "An accidental for trill pitch."
  '())
 
 (ly:add-interface
  'unbreakable-spanner-interface
- "A spanner that should not be broken across line breaks. Override
-with @code{breakable=##t}. "
+ "A spanner that should not be broken across line breaks.  Override
+with @code{breakable=##t}."
  '(breakable))
 
 (ly:add-interface
  'vertically-spaceable-interface
- "Objects that should be kept at constant vertical distances. Typically:
+ "Objects that should be kept at constant vertical distances.  Typically:
 @internalsref{VerticalAxisGroup} objects of @internalsref{Staff} contexts."
  '())
index 847a1aa18fcf6c245a3b6aadb4d2f7150a02484e..1319cf645d225343d4f39f149284d135534dbbd2 100644 (file)
@@ -94,7 +94,7 @@ printing of the bracket.  Setting the property to @code{if-no-beam}
 makes it print only if there is no beam associated with this tuplet
 bracket.")
      (break-align-anchor ,number? "Grobs aligned to this break-align
-grob will have their X-offsets shifted by this number. In barlines,
+grob will have their X-offsets shifted by this number.  In barlines,
 for example, this is used to position grobs relative to the (visual)
 center of the barline.")
      (break-align-anchor-alignment ,number? "Read by
@@ -103,7 +103,7 @@ an anchor to a grobs extent")
      (break-align-symbol ,symbol? "This key is used for aligning and
 spacing breakable items.")
      (break-align-symbols ,list? "A list of symbols that determine
-which break-aligned grobs to align this to. If the grob selected by
+which break-aligned grobs to align this to.  If the grob selected by
 the first symbol in the list is invisible due to break-visibility,
 we will align to the next grob (and so on).")
      (break-align-orders ,vector? "Defines the order in which
@@ -172,7 +172,7 @@ but also other numerical values are permitted.")
      (dot-count ,integer? "The number of dots.")
      (dot-radius ,number? "Radius of dots.")
      (duration-log ,integer? "The 2-log of the note head duration,
-i.e. @code{0} = whole note, @code{1} = half note, etc.")
+i.e., @code{0} = whole note, @code{1} = half note, etc.")
 
      (eccentricity ,number? "How asymmetrical to make a slur.
 Positive means move the center to the right.")
@@ -221,7 +221,7 @@ include @code{medium}, @code{bold}, @code{bold-narrow}, etc.")
 include @code{upright}, @code{italic}, @code{caps}.")
      (font-size ,number? "The font size, compared to the @q{normal}
 size.  @code{0}@tie{}is style-sheet's normal size, @code{-1} is
-smaller, @code{+1} is bigger. Each step of@tie{}1 is approximately
+smaller, @code{+1} is bigger.  Each step of@tie{}1 is approximately
 12% larger, 6@tie{}steps are exactly a factor@tie{}2 larger.
 Fractional values are allowed.")
      (force-hshift ,number? "This specifies a manual shift for notes
@@ -331,7 +331,7 @@ collisions, even if they have a different number of dots.  This is
 normal notation for some types of polyphonic music.
 
 @code{merge-differently-dotted} only applies to opposing stem
-directions (i.e. voice 1 &@tie{}2).")
+directions (i.e., voice 1 &@tie{}2).")
      (merge-differently-headed ,boolean? "Merge note heads in
 collisions, even if they have different note heads.  The
 smaller of the two heads is rendered invisible.  This is used in
@@ -339,7 +339,7 @@ polyphonic guitar notation.  The value of this setting is used by
 @internalsref{note-collision-interface}.
 
 @code{merge-differently-headed} only applies to opposing stem
-directions (i.e. voice 1 &@tie{}2).")
+directions (i.e., voice 1 &@tie{}2).")
      (minimum-X-extent ,number-pair? "Minimum size of an object in
 X@tie{}dimension, measured in @code{staff-space} units.")
      (minimum-Y-extent ,number-pair? "See @code{minimum-X-extent}.")
@@ -470,11 +470,11 @@ of spacing tuples: @code{(@var{break-align-symbol} @var{type}
 @code{minimum-space} or @code{extra-space}.")
      (space-to-barline ,boolean? "If set, the distance between a note
 and the following non-musical column will be measured to the barline
-instead of to the beginning of the non-musical column. If there is a
+instead of to the beginning of the non-musical column.  If there is a
 clef change followed by a barline, for example, this means that we will
 try to space the non-musical column as though the clef is not there.")
      (spacing-increment ,number? "Add this much space for a doubled
-duration.  Typically, the width of a note head. See also
+duration.  Typically, the width of a note head.  See also
 @internalsref{spacing-spanner-interface}.")
      (springs-and-rods ,boolean? "Dummy variable for triggering
 spacing routines.")
@@ -689,7 +689,7 @@ notes that the arpeggio has to be before.")
      (begin-of-line-visible ,boolean? "Used for marking @code{ChordNames}
 that should only show changes.")
 
-     (cause ,scheme? "Any kind of causation objects (i.e. music, or perhaps
+     (cause ,scheme? "Any kind of causation objects (i.e., music, or perhaps
 translator) that was the cause for this grob.")
      (circled-tip ,boolean? "Put a circle at start/end of hairpins (al/del
 niente).")
index 7e8e2f186ec9609d7b0db72432febd1fb91dc6ea..610f7c094a44ea30ec566c9aa623ee8c4af94af2 100644 (file)
              (interface-doc-string (cdr interface) '())
              "\n\n"
              "This grob interface is used in the following graphical objects: "
-
              (human-listify
               (map ref-ify
                    (sort 
                     (map symbol->string
                          (hashq-ref iface->grob-table (car interface) '()))
-                    string<?)))))))
+                    string<?)))
+             "."))))
 
 (define (grob-alist->texi alist)
   (let* ((uprops (filter (lambda (x) (not (object-property x 'backend-internal)))
index e3582682349ade26bacab3022af1c7c51b534567..9a09fa2dc50e90150293d806c44a23ad003d875a 100644 (file)
@@ -131,10 +131,10 @@ def musicxml_attributes_to_lily (attrs):
         'key': musicxml_key_to_lily
     }
     for (k, func) in attr_dispatch.items ():
-        childs = attrs.get_named_children (k)
+        children = attrs.get_named_children (k)
 
         ## ugh: you get clefs spread over staves for piano
-        if childs:
+        if children:
             elts.append (func (attrs))
     
     return elts
@@ -168,13 +168,136 @@ def musicxml_spanner_to_lily_event (mxl_event):
 
     return ev
 
+def musicxml_direction_to_indicator (direction):
+    val = { "above": 1, "upright": 1, "below": -1, "downright": -1 }.get (direction)
+    if val:
+        return val
+    else:
+        return ''
+
+def musicxml_fermata_to_lily_event (mxl_event):
+    ev = musicexp.ArticulationEvent ()
+    ev.type = "fermata"
+    if hasattr (mxl_event, 'type'):
+      dir = musicxml_direction_to_indicator (mxl_event.type)
+      if dir:
+        ev.force_direction = dir
+    return ev
+
+def musicxml_tremolo_to_lily_event(mxl_event):
+    if mxl_event.get_name () != "tremolo": 
+        return
+    ev = musicexp.TremoloEvent ()
+    ev.bars = mxl_event.get_text ()
+    return ev
+
+# TODO: Some translations are missing!
+articulations_dict = { 
+    ##### ORNAMENTS
+    "trill-mark": "trill", 
+    "turn": "turn", 
+    #"delayed-turn": "?", 
+    "inverted-turn": "reverseturn", 
+    #"shake": "?", 
+    #"wavy-line": "?", 
+    "mordent": "mordent",
+    #"inverted-mordent": "?", 
+    #"schleifer": "?" 
+    ##### TECHNICALS
+    "up-bow": "upbow", 
+    "down-bow": "downbow", 
+    #"harmonic": "", 
+    #"open-string": "", 
+    #"thumb-position": "", 
+    #"fingering": "", 
+    #"pluck": "", 
+    #"double-tongue": "", 
+    #"triple-tongue": "", 
+    #"stopped": "", 
+    #"snap-pizzicato": "", 
+    #"fret": "", 
+    #"string": "", 
+    #"hammer-on": "", 
+    #"pull-off": "", 
+    #"bend": "", 
+    #"tap": "", 
+    #"heel": "", 
+    #"toe": "", 
+    #"fingernails": ""
+    ##### ARTICULATIONS
+    "accent": "accent", 
+    "strong-accent": "marcato", 
+    "staccato": "staccato", 
+    "tenuto": "tenuto", 
+    #"detached-legato": "", 
+    "staccatissimo": "staccatissimo", 
+    #"spiccato": "", 
+    #"scoop": "", 
+    #"plop": "", 
+    #"doit": "", 
+    #"falloff": "",
+    "breath-mark": "breathe", 
+    #"caesura": "caesura", 
+    #"stress": "", 
+    #"unstress": ""
+}
+
+def musicxml_articulation_to_lily_event(mxl_event):
+    ev = musicexp.ArticulationEvent ()
+    tp = articulations_dict.get (mxl_event.get_name ())
+    if not tp:
+        return
+    
+    ev.type = tp
+
+    # Some articulations use the type attribute, other the placement...
+    dir = None
+    if hasattr (mxl_event, 'type'):
+        dir = musicxml_direction_to_indicator (mxl_event.type)
+    if hasattr (mxl_event, 'placement'):
+        dir = musicxml_direction_to_indicator (mxl_event.placement)
+    if dir:
+        ev.force_direction = dir
+    return ev
+
+
+def musicxml_direction_to_lily( n ):
+    # TODO: Handle the <staff> element!
+    res = []
+    dirtype = n.get_maybe_exist_typed_child (musicxml.DirType)
+    if not dirtype: 
+      return res
+
+    for entry in dirtype.get_all_children ():
+        if entry.get_name () == "dynamics":
+            for dynentry in entry.get_all_children ():
+                dynamics_available = ( "p", "pp", "ppp", "pppp", "ppppp", "pppppp", 
+                    "f", "ff", "fff", "ffff", "fffff", "ffffff", 
+                    "mp", "mf", "sf", "sfp", "sfpp", "fp", 
+                    "rf", "rfz", "sfz", "sffz", "fz" )
+                if not dynentry.get_name() in dynamics_available: 
+                    continue
+                event = musicexp.DynamicsEvent ()
+                event.type = dynentry.get_name ()
+                res.append (event)
+      
+        if entry.get_name() == "wedge":
+            if hasattr (entry, 'type'):
+                wedgetype = entry.type;
+                wedgetypeval = {"crescendo" : 1, "decrescendo" : -1, 
+                                "diminuendo" : -1, "stop" : 0 }.get (wedgetype)
+                if wedgetypeval != None:
+                    event = musicexp.HairpinEvent (wedgetypeval)
+                    res.append (event)
+
+    return res
+
 instrument_drumtype_dict = {
     'Acoustic Snare Drum': 'acousticsnare',
     'Side Stick': 'sidestick',
     'Open Triangle': 'opentriangle',
     'Mute Triangle': 'mutetriangle',
-    'Tambourine': 'tambourine',
-    
+    'Tambourine': 'tambourine'
 }
 
 def musicxml_note_to_lily_main_event (n):
@@ -219,6 +342,7 @@ class NegativeSkip:
 class LilyPondVoiceBuilder:
     def __init__ (self):
         self.elements = []
+        self.pending_dynamics = []
         self.end_moment = Rational (0)
         self.begin_moment = Rational (0)
         self.pending_multibar = Rational (0)
@@ -246,6 +370,16 @@ class LilyPondVoiceBuilder:
         self.begin_moment = self.end_moment
         self.end_moment = self.begin_moment + duration 
 
+        # Insert all pending dynamics right after the note/rest:
+        if duration > Rational (0):
+            for d in self.pending_dynamics:
+                self.elements.append (d)
+            self.pending_dynamics = []
+
+    def add_dynamics (self, dynamic):
+        # store the dynamic item(s) until we encounter the next note/rest:
+        self.pending_dynamics.append (dynamic)
+
     def add_bar_check (self, number):
         b = musicexp.BarCheck ()
         b.bar_number = number
@@ -297,6 +431,11 @@ def musicxml_voice_to_lily_voice (voice):
         if n.get_name () == 'forward':
             continue
 
+        if isinstance (n, musicxml.Direction):
+            for a in musicxml_direction_to_lily (n):
+                voice_builder.add_dynamics (a)
+            continue
+        
         if not n.get_maybe_exist_named_child ('chord'):
             try:
                 voice_builder.jumpto (n._when)
@@ -353,6 +492,12 @@ def musicxml_voice_to_lily_voice (voice):
         notations = n.get_maybe_exist_typed_child (musicxml.Notations)
         tuplet_event = None
         span_events = []
+        
+        # The <notation> element can have the following children (+ means implemented, ~ partially, - not):
+        # +tied | +slur | +tuplet | glissando | slide | 
+             # ornaments | technical | articulations | dynamics |
+             # +fermata | arpeggiate | non-arpeggiate | 
+             # accidental-mark | other-notation
         if notations:
             if notations.get_tuplet():
                 tuplet_event = notations.get_tuplet()
@@ -375,6 +520,50 @@ def musicxml_voice_to_lily_voice (voice):
             mxl_tie = notations.get_tie ()
             if mxl_tie and mxl_tie.type == 'start':
                 ev_chord.append (musicexp.TieEvent ())
+                
+            fermatas = notations.get_named_children ('fermata')
+            for a in fermatas:
+                ev = musicxml_fermata_to_lily_event (a);
+                if ev: 
+                    ev_chord.append (ev)
+                
+            # Articulations can contain the following child elements:
+            #         accent | strong-accent | staccato | tenuto |
+            #         detached-legato | staccatissimo | spiccato |
+            #         scoop | plop | doit | falloff | breath-mark | 
+            #         caesura | stress | unstress
+            # Technical can contain the following child elements:
+            #         up-bow | down-bow | harmonic | open-string |
+            #         thumb-position | fingering | pluck | double-tongue |
+            #         triple-tongue | stopped | snap-pizzicato | fret |
+            #         string | hammer-on | pull-off | bend | tap | heel |
+            #         toe | fingernails | other-technical
+            # Ornaments can contain the following child elements:
+            #         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')
+            for a in ornaments:
+                for ch in a.get_named_children ('tremolo'):
+                    ev = musicxml_tremolo_to_lily_event (ch)
+                    if ev: 
+                        ev_chord.append (ev)
+
+            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)
+                    if ev: 
+                        ev_chord.append (ev)
+
+            dynamics = notations.get_named_children ('dynamics')
+            for a in dynamics:
+                for ch in a.get_all_children ():
+                    ev = musicxml_dynamics_to_lily_event (ch)
+                    if ev:
+                        ev_chord.append (ev)
 
         mxl_beams = [b for b in n.get_named_children ('beam')
                      if (b.get_type () in ('begin', 'end')
@@ -422,12 +611,11 @@ def musicxml_voice_to_lily_voice (voice):
 
 
 def musicxml_id_to_lily (id):
-    digits = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
-              'nine', 'ten']
+    digits = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight',
+              'Nine', 'Ten']
     
     for dig in digits:
-        d = digits.index (dig) + 1
-        dig = dig[0].upper() + dig[1:]
+        d = digits.index (dig)
         id = re.sub ('%d' % d, dig, id)
 
     id = re.sub  ('[^a-zA-Z]', 'X', id)
@@ -512,9 +700,13 @@ def music_xml_voice_name_to_lily_name (part, name):
     str = "Part%sVoice%s" % (part.id, name)
     return musicxml_id_to_lily (str) 
 
-def print_voice_definitions (printer, voices):
+def print_voice_definitions (printer, part_list, voices):
+    part_dict={}
     for (part, nv_dict) in voices.items():
-        
+        part_dict[part.id] = (part, nv_dict)
+
+    for part in part_list:
+        (part, nv_dict) = part_dict[part.id]
         for (name, (voice, mxlvoice)) in nv_dict.items ():
             k = music_xml_voice_name_to_lily_name (part, name)
             printer.dump ('%s = ' % k)
@@ -627,7 +819,7 @@ def convert (filename, options):
     printer.set_file (open (defs_ly_name, 'w'))
 
     print_ly_preamble (printer, filename)
-    print_voice_definitions (printer, voices)
+    print_voice_definitions (printer, part_list, voices)
     
     printer.close ()