music21.musicxml.m21ToXml

Converters for music21 objects to musicxml using ElementTree

Functions

music21.musicxml.m21ToXml.accidentalToMx(a)
>>> a = pitch.Accidental()
>>> a.set('half-sharp')
>>> a.alter == .5
True
>>> mxAccidental = musicxml.m21ToXml.accidentalToMx(a)
>>> XB = musicxml.m21ToXml.XMLExporterBase()
>>> XB.dump(mxAccidental)
<accidental>quarter-sharp</accidental>
>>> a.set('one-and-a-half-sharp')
>>> mxAccidental = musicxml.m21ToXml.accidentalToMx(a)
>>> XB.dump(mxAccidental)
<accidental>three-quarters-sharp</accidental>
>>> a.set('half-flat')
>>> mxAccidental = musicxml.m21ToXml.accidentalToMx(a)
>>> XB.dump(mxAccidental)
<accidental>quarter-flat</accidental>
>>> a.set('one-and-a-half-flat')
>>> mxAccidental = musicxml.m21ToXml.accidentalToMx(a)
>>> XB.dump(mxAccidental)
<accidental>three-quarters-flat</accidental>
music21.musicxml.m21ToXml.indent(elem, level=0)
music21.musicxml.m21ToXml.normalizeColor(color)

Normalize a css3 name to hex or leave it alone...

>>> musicxml.m21ToXml.normalizeColor('')
''
>>> musicxml.m21ToXml.normalizeColor('red')
'#FF0000'
>>> musicxml.m21ToXml.normalizeColor('#00ff00')
'#00FF00'
music21.musicxml.m21ToXml.typeToMusicXMLType(value)

Convert a music21 type to a MusicXML type.

>>> musicxml.m21ToXml.typeToMusicXMLType('longa')
'long'
>>> musicxml.m21ToXml.typeToMusicXMLType('quarter')
'quarter'

GeneralObjectExporter

class music21.musicxml.m21ToXml.GeneralObjectExporter(obj=None)

GeneralObjectExporter methods

GeneralObjectExporter.fromDiatonicScale(diatonicScaleObject)

Return a complete musicxml of the DiatonicScale

Overrides the general scale behavior to highlight the tonic and dominant.

GeneralObjectExporter.fromDuration(d)

Translate a music21 Duration into a complete MusicXML representation.

Rarely rarely used. Only if you call .show() on a duration object

GeneralObjectExporter.fromDynamic(dynamicObject)

Provide a complete MusicXML string from a single dynamic by putting it into a Stream first.

GeneralObjectExporter.fromGeneralNote(n)

Translate a music21 Note into an object ready to be parsed.

>>> n = note.Note('c3')
>>> n.quarterLength = 3
>>> GEX = musicxml.m21ToXml.GeneralObjectExporter()
>>> sc = GEX.fromGeneralNote(n)
>>> sc.show('t')
{0.0} <music21.stream.Part 0x1046afa90>
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.BassClef>
        {0.0} <music21.meter.TimeSignature 6/8>
        {0.0} <music21.note.Note C>
GeneralObjectExporter.fromGeneralObject(obj)

Converts any Music21Object (or a duration or a pitch) to something that can be passed to ScoreExporter()

>>> GEX = musicxml.m21ToXml.GeneralObjectExporter()
>>> s = GEX.fromGeneralObject(duration.Duration(3.0))
>>> s
<music21.stream.Score 0x...>
>>> s.show('t')
{0.0} <music21.stream.Part 0x...>
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.meter.TimeSignature 6/8>
        {0.0} <music21.note.Note C>
>>> s.flat.notes[0].duration
<music21.duration.Duration 3.0>
GeneralObjectExporter.fromMeasure(m)

Translate a music21 Measure into a complete MusicXML string representation.

Note: this method is called for complete MusicXML representation of a Measure, not for partial solutions in Part or Stream production.

GeneralObjectExporter.fromPart(p)

from a part, put it in a score...

GeneralObjectExporter.fromPitch(p)

Translate a music21 Pitch into an object ready to be parsed.

>>> p = pitch.Pitch('c#3')
>>> GEX = musicxml.m21ToXml.GeneralObjectExporter()
>>> sc = GEX.fromPitch(p)
>>> sc.show('t')
{0.0} <music21.stream.Part 0x1046afa90>
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.BassClef>
        {0.0} <music21.meter.TimeSignature 1/4>
        {0.0} <music21.note.Note C#>
GeneralObjectExporter.fromScale(scaleObject)

Generate the pitches from this scale and put it into a stream.Measure, then call fromMeasure on it

GeneralObjectExporter.fromScore(sc)

the best one of all – a perfectly made Score (or something like that)

GeneralObjectExporter.fromStream(st)
GeneralObjectExporter.fromTimeSignature(ts)

return a single TimeSignature as a musicxml document

GeneralObjectExporter.fromVoice(v)
GeneralObjectExporter.parse(obj=None)

return a bytes object representation of anything from a Score to a single pitch.

>>> p = pitch.Pitch('D#4')
>>> GEX = musicxml.m21ToXml.GeneralObjectExporter(p)
>>> out = GEX.parse() # out is bytes in Py3, str in Py2
>>> outStr = out.decode('utf-8') # will be unicode in Py2
>>> print(outStr.strip())
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE score-partwise
  PUBLIC '-//Recordare//DTD MusicXML 2.0 Partwise//EN'
  'http://www.musicxml.org/dtds/partwise.dtd'>
<score-partwise>
  <movement-title>Music21 Fragment</movement-title>
  <identification>
    <creator type="composer">Music21</creator>
    <encoding>
      <encoding-date>...</encoding-date>
      <software>Music21</software>
    </encoding>
  </identification>
  <defaults>
    <scaling>
      <millimeters>7</millimeters>
      <tenths>40</tenths>
    </scaling>
  </defaults>
  <part-list>
    <score-part id="...">
      <part-name />
    </score-part>
  </part-list>
  <part id="...">
    <measure number="1">
      <attributes>
        <divisions>10080</divisions>
        <time>
          <beats>1</beats>
          <beat-type>4</beat-type>
        </time>
        <clef>
          <sign>G</sign>
          <line>2</line>
        </clef>
      </attributes>
      <note>
        <pitch>
          <step>D</step>
          <alter>1</alter>
          <octave>4</octave>
        </pitch>
        <duration>10080</duration>
        <type>quarter</type>
        <accidental>sharp</accidental>
      </note>
    </measure>
  </part>
</score-partwise>
GeneralObjectExporter.parseWellformedObject(sc)

parse an object that has already gone through the .fromGeneralObject conversion. Returns bytes.

MeasureExporter

class music21.musicxml.m21ToXml.MeasureExporter(measureObj=None, parent=None)

MeasureExporter bases

MeasureExporter methods

MeasureExporter.articulationToXmlArticulation(articulationMark)

Returns a class (mxArticulationMark) that represents the MusicXML structure of an articulation mark.

>>> a = articulations.Accent()
>>> a.placement = 'below'
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxArticulationMark = MEX.articulationToXmlArticulation(a)
>>> MEX.dump(mxArticulationMark)
<accent placement="below" />
>>> a = articulations.Staccatissimo()
>>> a.placement = 'below'
>>> mxArticulationMark = MEX.articulationToXmlArticulation(a)
>>> MEX.dump(mxArticulationMark)
<staccatissimo placement="below" />
MeasureExporter.articulationToXmlTechnical(articulationMark)

Returns a tag that represents the MusicXML structure of an articulation mark that is primarily a TechnicalIndication.

>>> a = articulations.UpBow()
>>> a.placement = 'below'
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxTechnicalMark = MEX.articulationToXmlTechnical(a)
>>> MEX.dump(mxTechnicalMark)
<up-bow placement="below" />
MeasureExporter.barlineToXml(barObject)

Translate a music21 bar.Bar object to an mxBar while making two substitutions: double -> light-light and final -> light-heavy as shown below.

>>> b = bar.Barline('final')
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxBarline = MEX.barlineToXml(b)
>>> MEX.dump(mxBarline)
<barline>
  <bar-style>light-heavy</bar-style>
</barline>
>>> b.location = 'right'
>>> mxBarline = MEX.barlineToXml(b)
>>> MEX.dump(mxBarline)
<barline location="right">
  <bar-style>light-heavy</bar-style>
</barline>
MeasureExporter.beamToXml(beamObject)
>>> a = beam.Beam()
>>> a.type = 'start'
>>> a.number = 1
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> b = MEX.beamToXml(a)
>>> MEX.dump(b)
<beam number="1">begin</beam>
>>> a.type = 'continue'
>>> b = MEX.beamToXml(a)
>>> MEX.dump(b)
<beam number="1">continue</beam>
>>> a.type = 'stop'
>>> b = MEX.beamToXml(a)
>>> MEX.dump(b)
<beam number="1">end</beam>
>>> a.type = 'partial'
>>> a.direction = 'left'
>>> b = MEX.beamToXml(a)
>>> MEX.dump(b)
<beam number="1">backward hook</beam>
>>> a.direction = 'right'
>>> b = MEX.beamToXml(a)
>>> MEX.dump(b)
<beam number="1">forward hook</beam>
>>> a.direction = None
>>> b = MEX.beamToXml(a)
Traceback (most recent call last):
ToMxObjectsException: partial beam defined without a proper direction set (set to None)
>>> a.type = 'crazy'
>>> b = MEX.beamToXml(a)
Traceback (most recent call last):
ToMxObjectsException: unexpected beam type encountered (crazy)
MeasureExporter.beamsToXml(beams)

Returns a list of <beam> tags from a Beams object

>>> a = beam.Beams()
>>> a.fill(2, type='start')
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxBeamList = MEX.beamsToXml(a)
>>> len(mxBeamList)
2
>>> for b in mxBeamList:
...     MEX.dump(b)
<beam number="1">begin</beam>
<beam number="2">begin</beam>        
MeasureExporter.chordSymbolToXml(cs)

Convert a ChordSymbol object to an mxHarmony object.

>>> cs = harmony.ChordSymbol()
>>> cs.root('E-')
>>> cs.bass('B-')
>>> cs.inversion(2, transposeOnSet = False)
>>> cs.chordKind = 'major'
>>> cs.chordKindStr = 'M'
>>> cs
<music21.harmony.ChordSymbol E-/B->
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> MEX.currentDivisions = 10
>>> mxHarmony = MEX.chordSymbolToXml(cs)
>>> MEX.dump(mxHarmony)
<harmony>
  <root>
    <root-step>E</root-step>
    <root-alter>-1.0</root-alter>
  </root>
  <kind text="M">major</kind>
  <inversion>2</inversion>
  <bass>
    <bass-step>B</bass-step>
    <bass-alter>-1.0</bass-alter>
  </bass>
</harmony>        

Now give function...

>>> cs.romanNumeral = 'I64'
>>> mxHarmony = MEX.chordSymbolToXml(cs)
>>> MEX.dump(mxHarmony)
<harmony>
  <function>I64</function>
  <kind text="M">major</kind>
  <inversion>2</inversion>
  <bass>
    <bass-step>B</bass-step>
    <bass-alter>-1.0</bass-alter>
  </bass>
</harmony>
>>> hd = harmony.ChordStepModification()
>>> hd.modType = 'alter'
>>> hd.interval = -1
>>> hd.degree = 3
>>> cs.addChordStepModification(hd)
>>> mxHarmony = MEX.chordSymbolToXml(cs)
>>> MEX.dump(mxHarmony)
<harmony>
  <function>I64</function>
  <kind text="M">major</kind>
  <inversion>2</inversion>
  <bass>
    <bass-step>B</bass-step>
    <bass-alter>-1.0</bass-alter>
  </bass>
  <degree>
    <degree-value>3</degree-value>
    <degree-alter>-1</degree-alter>
    <degree-type>alter</degree-type>
  </degree>
</harmony>

Test altered chords:

Is this correct?

>>> f = harmony.ChordSymbol('F sus add 9')
>>> f
<music21.harmony.ChordSymbol F sus add 9>
>>> mxHarmony = MEX.chordSymbolToXml(f)
>>> MEX.dump(mxHarmony)
<harmony>
  <root>
    <root-step>G</root-step>
  </root>
  <kind>suspended-fourth</kind>
  <inversion>3</inversion>
  <degree>
    <degree-value>9</degree-value>
    <degree-alter />
    <degree-type>add</degree-type>
  </degree>
</harmony>

MusicXML uses “dominant” for “dominant-seventh” so check aliases back...

>>> dom7 = harmony.ChordSymbol('C7')
>>> dom7.chordKind
'dominant-seventh'
>>> mxHarmony = MEX.chordSymbolToXml(dom7)
>>> MEX.dump(mxHarmony)
<harmony>
  <root>
    <root-step>C</root-step>
  </root>
  <kind>dominant</kind>
</harmony>

set writeAsChord to not get a symbol, but the notes. Will return a list of notes.

>>> dom7.writeAsChord = True
>>> harmonyList = MEX.chordSymbolToXml(dom7)
>>> len(harmonyList)
4
>>> MEX.dump(harmonyList[0])
<note>
  <pitch>
    <step>C</step>
    <octave>3</octave>
  </pitch>
  <duration>10</duration>
  <type>quarter</type>
</note>
MeasureExporter.chordToXml(c)

Returns a list of <note> tags, all but the first with a <chord/> tag on them. And appends them to self.xmlRoot

Attributes of notes are merged from different locations: first from the duration objects, then from the pitch objects. Finally, GeneralNote attributes are added.

>>> ch = chord.Chord()
>>> ch.quarterLength = 2
>>> b = pitch.Pitch('A-2')
>>> c = pitch.Pitch('D3')
>>> d = pitch.Pitch('E4')
>>> e = [b,c,d]
>>> ch.pitches = e
>>> len(ch.pitches)
3
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> len(MEX.xmlRoot)
0
>>> mxNoteList = MEX.chordToXml(ch)
>>> len(mxNoteList) # get three mxNotes
3
>>> len(MEX.xmlRoot)
3
>>> MEX.dump(mxNoteList[0])
<note>
  <pitch>
    <step>A</step>
    <alter>-1</alter>
    <octave>2</octave>
  </pitch>
  <duration>20160</duration>
  <type>half</type>
  <accidental>flat</accidental>
</note>
>>> MEX.dump(mxNoteList[1])
<note>
  <chord />
  <pitch>
    <step>D</step>
    <octave>3</octave>
  </pitch>
  <duration>20160</duration>
  <type>half</type>
</note>
>>> MEX.dump(mxNoteList[2])
<note>
  <chord />
  <pitch>
    <step>E</step>
    <octave>4</octave>
  </pitch>
  <duration>20160</duration>
  <type>half</type>
</note>

Test that notehead translation works:

>>> g = pitch.Pitch('g3')
>>> h = note.Note('b4')
>>> h.notehead = 'diamond'
>>> ch2 = chord.Chord([g, h])
>>> ch2.quarterLength = 2.0
>>> mxNoteList = MEX.chordToXml(ch2)
>>> MEX.dump(mxNoteList[1])
<note>
  <chord />
  <pitch>
    <step>B</step>
    <octave>4</octave>
  </pitch>
  <duration>20160</duration>
  <type>half</type>
  <notehead parentheses="no">diamond</notehead>
</note>
MeasureExporter.clefToXml(clefObj)

Given a music21 Clef object, return a MusicXML clef tag.

>>> gc = clef.GClef()
>>> gc
<music21.clef.GClef>
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxc = MEX.clefToXml(gc)
>>> MEX.dump(mxc)
<clef>
  <sign>G</sign>
</clef>
>>> b = clef.Treble8vbClef()
>>> b.octaveChange
-1
>>> mxc2 = MEX.clefToXml(b)
>>> MEX.dump(mxc2)
<clef>
  <sign>G</sign>
  <line>2</line>
  <clef-octave-change>-1</clef-octave-change>
</clef>
>>> pc = clef.PercussionClef()
>>> mxc3 = MEX.clefToXml(pc)
>>> MEX.dump(mxc3)
<clef>
  <sign>percussion</sign>
</clef>

Clefs without signs get exported as G clefs with a warning

>>> generic = clef.Clef()
>>> mxc4 = MEX.clefToXml(generic)
Clef with no .sign exported; setting as a G clef
>>> MEX.dump(mxc4)
<clef>
  <sign>G</sign>
</clef>
MeasureExporter.codaToXml(coda)

returns a coda inside a direction-type inside a direction IF coda.useSymbol is True; otherwise returns a textExpression...

appends to score

>>> c = repeat.Coda()
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxCodaDir = MEX.codaToXml(c)
>>> MEX.dump(mxCodaDir)
<direction>
  <direction-type>
    <coda default-y="20" />
  </direction-type>
</direction>

turn coda.useSymbol to False to get a text expression instead

>>> c.useSymbol = False
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxCodaText = MEX.codaToXml(c)
>>> MEX.dump(mxCodaText)
<direction>
  <direction-type>
    <words default-y="20" justify="center">Coda</words>
  </direction-type>
  <offset>0</offset>
</direction>
MeasureExporter.durationXml(dur)

Convert a duration.Duration object to a <duration> tag using self.currentDivisions

>>> d = duration.Duration(1.5)
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> MEX.currentDivisions = 10
>>> mxDuration = MEX.durationXml(d)
>>> MEX.dump(mxDuration)
<duration>15</duration>
MeasureExporter.dynamicToXml(d)

return a nested tag: <direction><direction-type><dynamic><ff> or whatever...

>>> ppp = dynamics.Dynamic('ppp')
>>> print('%.2f' % ppp.volumeScalar)
0.15
>>> ppp._positionRelativeY = -10
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxDirection = MEX.dynamicToXml(ppp)
>>> MEX.dump(mxDirection)
<direction>
  <direction-type>
    <dynamics default-x="-36" default-y="-80" relative-y="-10">
      <ppp />
    </dynamics>
  </direction-type>
  <sound dynamics="19" />
</direction>        

appends to score

MeasureExporter.expressionToXml(expression)

Convert a music21 Expression (expression or ornament) to a musicxml tag; return None if no conversion is possible.

Expressions apply only to the first note of chord.

>>> t = expressions.InvertedTurn()
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxExpression = MEX.expressionToXml(t)
>>> MEX.dump(mxExpression)
<inverted-turn placement="above" />

Two special types...

>>> f = expressions.Fermata()
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxExpression = MEX.expressionToXml(f)
>>> MEX.dump(mxExpression)
<fermata type="inverted" />
>>> t = expressions.Tremolo()
>>> t.numberOfMarks = 4
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxExpression = MEX.expressionToXml(t)
>>> MEX.dump(mxExpression)
<tremolo type="single">4</tremolo>        
MeasureExporter.intervalToXmlTranspose(i=None)
>>> ME = musicxml.m21ToXml.MeasureExporter()
>>> i = interval.Interval('P5')
>>> mxTranspose = ME.intervalToXmlTranspose(i)
>>> ME.dump(mxTranspose)
<transpose>
  <diatonic>4</diatonic>
  <chromatic>7</chromatic>
</transpose>
>>> i = interval.Interval('A13')
>>> mxTranspose = ME.intervalToXmlTranspose(i)
>>> ME.dump(mxTranspose)
<transpose>
  <diatonic>19</diatonic>
  <chromatic>10</chromatic>
  <octave-shift>1</octave-shift>
</transpose>        
>>> i = interval.Interval('-M6')
>>> mxTranspose = ME.intervalToXmlTranspose(i)
>>> ME.dump(mxTranspose)
<transpose>
  <diatonic>-5</diatonic>
  <chromatic>-9</chromatic>
</transpose>
MeasureExporter.keySignatureToXml(keySignature)

returns a key tag from a music21 key.KeySignature or key.Key object

>>> ks = key.KeySignature(-3)
>>> ks
<music21.key.KeySignature of 3 flats>
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxKey = MEX.keySignatureToXml(ks)
>>> MEX.dump(mxKey)
<key>
  <fifths>-3</fifths>
</key>
>>> ks.mode = 'major'
>>> mxKey = MEX.keySignatureToXml(ks)
>>> MEX.dump(mxKey)
<key>
  <fifths>-3</fifths>
  <mode>major</mode>
</key>
MeasureExporter.lyricToXml(l)

Translate a music21 Lyric object to a <lyric> tag.

MeasureExporter.mainElementsParse()

deals with parsing all the elements in a stream, whether it has voices or not.

MeasureExporter.midmeasureClefToXml(clefObj)

given a clefObj which is in .elements insert it in self.xmlRoot as an attribute if it is not at offset 0.0.

MeasureExporter.noteToNotations(n, notFirstNoteOfChord=False, chordParent=None)

Take information from .expressions, .articulations, and spanners to make the <notations> tag for a note.

MeasureExporter.noteToXml(n, addChordTag=False, chordParent=None)

Translate a music21 Note or a Rest into a list of Note objects.

Because of “complex” durations, the number of musicxml.mxObjects.Note objects could be more than one.

Note that, some note-attached spanners, such as octave shifts, produce direction (and direction types) in this method.

>>> n = note.Note('D#5')
>>> n.quarterLength = 3
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> len(MEX.xmlRoot)
0
>>> mxNote = MEX.noteToXml(n)
>>> MEX.dump(mxNote)
<note>
  <pitch>
    <step>D</step>
    <alter>1</alter>
    <octave>5</octave>
  </pitch>
  <duration>30240</duration>
  <type>half</type>
  <dot />
  <accidental>sharp</accidental>
</note>
>>> len(MEX.xmlRoot)
1
>>> r = note.Rest()
>>> r.quarterLength = 1.0/3
>>> r.duration.tuplets[0].type = 'start'
>>> mxRest = MEX.noteToXml(r)
>>> MEX.dump(mxRest)
<note>
  <rest />
  <duration>3360</duration>
  <type>eighth</type>
  <time-modification>
    <actual-notes>3</actual-notes>
    <normal-notes>2</normal-notes>
    <normal-type>eighth</normal-type>
  </time-modification>
  <notations>
    <tuplet bracket="yes" placement="above" type="start" />
  </notations>
</note>
>>> len(MEX.xmlRoot)
2
>>> n.notehead = 'diamond'
>>> mxNote = MEX.noteToXml(n)
>>> MEX.dump(mxNote)
<note>
  ...
  <notehead parentheses="no">diamond</notehead>
</note>

TODO: Test with spanners...

MeasureExporter.noteheadToXml(n)

Translate a music21 Note object into a <notehead> tag

>>> n = note.Note('C#4')
>>> n.notehead = 'diamond'
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxN = MEX.noteheadToXml(n)
>>> MEX.dump(mxN)
<notehead parentheses="no">diamond</notehead>
>>> n1 = note.Note('c3')
>>> n1.color = 'red'
>>> n1.notehead = 'diamond'
>>> n1.noteheadParenthesis = True
>>> n1.noteheadFill = False
>>> mxN = MEX.noteheadToXml(n1)
>>> MEX.dump(mxN)
<notehead color="#FF0000" filled="no" parentheses="yes">diamond</notehead>
MeasureExporter.objectAttachedSpannersToNotations(obj, objectSpannerBundle=None)

return a list of <notations> from spanners related to the object that should appear in the notations tag (slurs, slides, etc.)

MeasureExporter.parse()

main parse call.

deals with transposing, repeat brackets, setting measureNumber and width, the first mxPrint, the first <attributes> tag, the left barline, parsing all internal elements, setting the right barline, then returns the root <measure> tag.

MeasureExporter.parseFlatElements(m)

Deals with parsing all the elements in .elements, assuming that .elements is flat.

m here can be a Measure or Voice, but flat...

If m is a ‘Voice’ class, we use the .id element to set self.currentVoiceId and then send a backup tag to go back to the beginning of the measure.

MeasureExporter.parseOneElement(obj)

parse one element completely and add it to xmlRoot, updating offsetInMeasure, etc.

MeasureExporter.pitchToXml(p)

convert a pitch to xml... does not create the <accidental> tag...

>>> p = pitch.Pitch('D#5')
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxPitch = MEX.pitchToXml(p)
>>> MEX.dump(mxPitch)
<pitch>
  <step>D</step>
  <alter>1</alter>
  <octave>5</octave>
</pitch>
MeasureExporter.placeInDirection(mxObj, m21Obj=None)

places the mxObj <element> inside <direction><direction-type>

MeasureExporter.prePostObjectSpanners(target)

return two lists or empty tuples: (1) spanners related to the object that should appear before the object to the <measure> tag. (2) spanners related to the object that should appear after the object in the measure tag.

MeasureExporter.repeatToXml(r)

returns a <repeat> tag from a barline object.

>>> b = bar.Repeat(direction='end')
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxRepeat = MEX.repeatToXml(b)
>>> MEX.dump(mxRepeat)
<repeat direction="backward" />
>>> b.times = 3
>>> mxRepeat = MEX.repeatToXml(b)
>>> MEX.dump(mxRepeat)
<repeat direction="backward" times="3" />
MeasureExporter.restToXml(r)

Convert a rest object to a <note> with a <rest> tag undeneath it.

>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> r = note.Rest(quarterLength=2.0)

Give the rest some context:

>>> m = stream.Measure()
>>> m.timeSignature = meter.TimeSignature('4/4')
>>> m.append(r)
>>> mxNoteRest = MEX.restToXml(r)
>>> MEX.dump(mxNoteRest)
<note>
  <rest />
  <duration>20160</duration>
  <type>half</type>
</note>

Now it is a full measure:

>>> m.timeSignature = meter.TimeSignature('2/4')        
>>> mxNoteRest = MEX.restToXml(r)
>>> MEX.dump(mxNoteRest)
<note>
  <rest measure="yes" />
  <duration>20160</duration>
</note>        

Unless we specify that it should not be converted to a full measure:

>>> r.fullMeasure = False
>>> mxNoteRest = MEX.restToXml(r)
>>> MEX.dump(mxNoteRest)
<note>
  <rest />
  <duration>20160</duration>
  <type>half</type>
</note>

With True or “always” it will be converted to full measure even if it does not match:

>>> m.timeSignature = meter.TimeSignature('4/4')
>>> r.duration.dots = 1
>>> r.fullMeasure = True
>>> mxNoteRest = MEX.restToXml(r)
>>> MEX.dump(mxNoteRest)
<note>
  <rest measure="yes" />
  <duration>30240</duration>
</note>  

display-step and display-octave should work:

>>> r = note.Rest()
>>> r.stepShift = 1
>>> mxNoteRest = MEX.restToXml(r)
>>> MEX.dump(mxNoteRest)
<note>
  <rest>
    <display-step>C</display-step>
    <display-octave>5</display-octave>
  </rest>
  <duration>10080</duration>
  <type>quarter</type>
</note>

Clef context matters:

>>> m = stream.Measure()
>>> m.clef = clef.BassClef()
>>> m.append(r)
>>> mxNoteRest = MEX.restToXml(r)
>>> MEX.dump(mxNoteRest)
<note>
  <rest>
    <display-step>E</display-step>
    <display-octave>3</display-octave>
  </rest>
  <duration>10080</duration>
  <type>quarter</type>
</note>
MeasureExporter.segnoToXml(segno)

returns a segno inside a direction-type inside a direction.

appends to score

>>> s = repeat.Segno()
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxSegnoDir = MEX.segnoToXml(s)
>>> MEX.dump(mxSegnoDir)
<direction>
  <direction-type>
    <segno default-y="20" />
  </direction-type>
</direction>
MeasureExporter.setBarline(barline, position)

sets either a left or right barline from a bar.Barline() object or bar.Repeat() object

MeasureExporter.setLeftBarline()
MeasureExporter.setMxAttributes()

sets the attributes (x=y) for a measure, that is, number, and layoutWidth

Does not create the <attributes> tag. That’s elsewhere...

MeasureExporter.setMxAttributesObject()

creates an <attributes> tag (always? or if needed...)

MeasureExporter.setMxPrint()
MeasureExporter.setPrintStyleAlign(m21Obj, mxObj)
MeasureExporter.setRbSpanners()

Makes a set of spanners from repeat brackets

MeasureExporter.setRightBarline()
MeasureExporter.setTranspose()
MeasureExporter.staffLayoutToXmlPrint(staffLayout, mxPrint=None)
MeasureExporter.staffLayoutToXmlStaffDetails(staffLayout)
MeasureExporter.tempoIndicationToXml(ti)

returns a <direction> tag for a single tempo indication.

note that TWO direction tags may be added to xmlroot, the second one as a textExpression.... but only the first will be returned.

>>> mm = tempo.MetronomeMark("slow", 40, note.Note(type='half'))
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxDirection = MEX.tempoIndicationToXml(mm)
>>> MEX.dump(mxDirection)
<direction>
  <direction-type>
    <metronome parentheses="no">
      <beat-unit>half</beat-unit>
      <per-minute>40</per-minute>
    </metronome>
  </direction-type>
  <sound tempo="80" />
</direction>

In this case, two directions were added to xmlRoot. Here is the other one:

>>> MEX.dump(MEX.xmlRoot.findall('direction')[1])
<direction>
  <direction-type>
    <words default-y="45.0" font-weight="bold" justify="left">slow</words>
  </direction-type>
  <offset>0</offset>
</direction>
>>> mm = tempo.MetronomeMark("slow", 40, duration.Duration(quarterLength=1.5))
>>> mxDirection = MEX.tempoIndicationToXml(mm)
>>> MEX.dump(mxDirection)
<direction>
  <direction-type>
    <metronome parentheses="no">
      <beat-unit>quarter</beat-unit>
      <beat-unit-dot />
      <per-minute>40</per-minute>
    </metronome>
  </direction-type>
  <sound tempo="60" />
</direction>
>>> mmod1 = tempo.MetricModulation()
>>> mmod1.oldReferent = .75 # quarterLength
>>> mmod1.newReferent = 'quarter' # type
>>> mxDirection = MEX.tempoIndicationToXml(mmod1)
>>> MEX.dump(mxDirection)
<direction>
  <direction-type>
    <metronome parentheses="no">
      <beat-unit>eighth</beat-unit>
      <beat-unit-dot />
      <beat-unit>quarter</beat-unit>
    </metronome>
  </direction-type>
</direction>
>>> mmod1.newReferent = 'longa' # music21 type w/ different musicxml name...
>>> mxDirection = MEX.tempoIndicationToXml(mmod1)
>>> MEX.dump(mxDirection)
<direction>
  <direction-type>
    <metronome parentheses="no">
      <beat-unit>eighth</beat-unit>
      <beat-unit-dot />
      <beat-unit>long</beat-unit>
    </metronome>
  </direction-type>
</direction>
MeasureExporter.textExpressionToXml(te)

Convert a TextExpression to a MusicXML mxDirection type. returns a musicxml.mxObjects.Direction object

MeasureExporter.tieToXmlTie(t)

returns a list of ties from a Tie object.

A ‘continue’ tie requires two <tie> tags to represent.

>>> t = tie.Tie('continue')
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> tieList = MEX.tieToXmlTie(t)
>>> for mxT in tieList: 
...     MEX.dump(mxT)
<tie type="stop" />
<tie type="start" />        
MeasureExporter.tieToXmlTied(t)

In musicxml, a tie is represented in sound by the tie tag (near the pitch object), and the <tied> tag in notations. This creates the <tied> tag.

Returns a list since a music21 “continue” tie type needs two tags in musicxml. List may be empty if tie.style == “hidden”

>>> t = tie.Tie('continue')
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> tiedList = MEX.tieToXmlTied(t)
>>> for mxT in tiedList: 
...     MEX.dump(mxT)
<tied type="stop" />
<tied type="start" />
>>> t.style = 'hidden'
>>> tiedList = MEX.tieToXmlTied(t)
>>> len(tiedList)
0
MeasureExporter.timeSignatureToXml(ts)

Returns a single <time> tag from a meter.TimeSignature object.

Compound meters are represented as multiple pairs of beat and beat-type elements

>>> a = meter.TimeSignature('3/4')
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> b = MEX.timeSignatureToXml(a)
>>> MEX.dump(b)
<time>
  <beats>3</beats>
  <beat-type>4</beat-type>
</time>
>>> a = meter.TimeSignature('3/4+2/4')
>>> b = MEX.timeSignatureToXml(a)
>>> MEX.dump(b)
<time>
  <beats>3</beats>
  <beat-type>4</beat-type>
  <beats>2</beats>
  <beat-type>4</beat-type>
</time>
>>> a.setDisplay('5/4')
>>> b = MEX.timeSignatureToXml(a)
>>> MEX.dump(b)
<time>
  <beats>5</beats>
  <beat-type>4</beat-type>
</time>
MeasureExporter.tupletToTimeModification(tup)
>>> t = duration.Tuplet(11, 8)
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxTimeMod = MEX.tupletToTimeModification(t)
>>> MEX.dump(mxTimeMod)
<time-modification>
  <actual-notes>11</actual-notes>
  <normal-notes>8</normal-notes>
  <normal-type>eighth</normal-type>
</time-modification>
MeasureExporter.tupletToXmlTuplet(tuplet)

In musicxml, a tuplet is represented by a timeModification and visually by the <notations><tuplet> tag. This method creates the latter.

Returns a list of them because a startStop type tuplet needs two tuplet brackets.

TODO: make sure something happens if makeTupletBrackets is not set.

>>> t = duration.Tuplet(11, 8)
>>> t.type = 'start'
>>> MEX = musicxml.m21ToXml.MeasureExporter()
>>> mxTup = MEX.tupletToXmlTuplet(t)
>>> len(mxTup)
1
>>> MEX.dump(mxTup[0])
<tuplet bracket="yes" placement="above" type="start" />

Methods inherited from XMLExporterBase:

PartExporter

class music21.musicxml.m21ToXml.PartExporter(partObj=None, parent=None)

Object to convert one Part stream to a <part> tag on .parse()

PartExporter bases

PartExporter methods

PartExporter.fixupNotationFlat()

Runs makeNotation on a flatStream...

TODO: test if this is redundant.

PartExporter.fixupNotationMeasured(measureStream)

Checks to see if there are any attributes in the part stream and moves them into the first measure if necessary.

Checks if makeAccidentals is run, and haveBeamsBeenMade is done, and haveTupletBracketsBeenMade is done.

PartExporter.getXmlScorePart()

make a <score-part> from a music21 Part object and a parsed mxPart (<part>) element.

contains details about instruments, etc.

called directly by the ScoreExporter as a late part of the processing.

PartExporter.instrumentSetup()

sets self.instrumentStream and self.firstInstrumentObject for the stream, checks for a unique midiChannel and then blocks it off from future use.

Note that there’s a deficiency currently that only the first instrument is fully converted.

PartExporter.instrumentToXmlMidiInstrument(i)
PartExporter.instrumentToXmlScoreInstrument(i)
PartExporter.parse()

Set up instruments, create a partId (if no good one exists) and sets it on <part>, fixes up the notation (fixupNotationFlat() or fixupNotationMeasured()) setsIdLocals on spanner bundle. runs parse() on each measure’s MeasureExporter and appends the output to the <part> object.

In other words, one-stop shopping.

Methods inherited from XMLExporterBase:

ScoreExporter

class music21.musicxml.m21ToXml.ScoreExporter(score=None)

Convert a Score (or outer stream with .parts) into a musicxml Element.

ScoreExporter bases

ScoreExporter methods

ScoreExporter.contributorToXmlCreator(c)

Return a <creator> tag from a Contributor object.

>>> md = metadata.Metadata()
>>> md.composer = 'frank'
>>> contrib = md._contributors[0]
>>> contrib
<music21.metadata.primitives.Contributor object at 0x...>
>>> SX = musicxml.m21ToXml.ScoreExporter()
>>> mxCreator = SX.contributorToXmlCreator(contrib)
>>> SX.dump(mxCreator) 
<creator type="composer">frank</creator>
ScoreExporter.emptyObject()

Creates a cheeky “This Page Intentionally Left Blank” for a blank score

>>> emptySX = musicxml.m21ToXml.ScoreExporter()
>>> mxScore = emptySX.parse() # will call emptyObject
>>> emptySX.dump(mxScore)
<score-partwise>
  <work>
    <work-title>This Page Intentionally Left Blank</work-title>
  </work>
  ...
      <note>
        <rest />
        <duration>40320</duration>
        <type>whole</type>
      </note>
    </measure>
  </part>
</score-partwise>
ScoreExporter.getSupports()

return a list of <supports> tags for what this supports. Does not append

Currently just supports new-system and new-page if s.definesExplicitSystemBreaks and s.definesExplicitPageBreaks is True.

>>> SX = musicxml.m21ToXml.ScoreExporter()
>>> SX.getSupports()
[]
>>> SX.stream.definesExplicitSystemBreaks = True
>>> SX.getSupports()
[<Element 'supports' at 0x...>]
>>> SX.dump(SX.getSupports()[0])
<supports attribute="new-system" element="print" type="yes" value="yes" />
>>> SX.stream.definesExplicitPageBreaks = True
>>> SX.dump(SX.getSupports()[1])
<supports attribute="new-page" element="print" type="yes" value="yes" />
ScoreExporter.parse()

the main function to call.

If self.stream is empty, call self.emptyObject(). Otherwise,

set scorePreliminaries(), call parsePartlikeScore or parseFlatScore, then postPartProcess(), clean up circular references for garbage collection, and returns the <score-partwise> object.

>>> b = corpus.parse('bwv66.6')
>>> SX = musicxml.m21ToXml.ScoreExporter(b)
>>> mxScore = SX.parse()
>>> SX.dump(mxScore)
<score-partwise>...</score-partwise>
ScoreExporter.parseFlatScore()

creates a single PartExporter for this Stream and parses it.

Note that the Score does not need to be totally flat, it just cannot have Parts inside it; measures are fine.

>>> c = converter.parse('tinyNotation: 3/4 c2. d e')
>>> SX = musicxml.m21ToXml.ScoreExporter(c)
>>> SX.parseFlatScore()
>>> len(SX.partExporterList)
1
>>> SX.partExporterList[0]
<music21.musicxml.m21ToXml.PartExporter object at 0x...>
>>> SX.dump(SX.partExporterList[0].xmlRoot)
<part id="...">
  <measure number="1">...</measure>
</part>
>>> del SX.partExporterList[:] # for garbage collection
ScoreExporter.parsePartlikeScore()

called by .parse() if the score has individual parts.

Calls makeRests() for the part, then creates a PartExporter for each part, and runs .parse() on that part. appends the PartExporter to self.partExporterList()

ScoreExporter.postPartProcess()

calls .setScoreHeader() then appends each PartExporter’s xmlRoot from self.partExporterList to self.xmlRoot

Called automatically by .parse()

ScoreExporter.scorePreliminaries()

Populate the exporter object with meterStream, scoreLayouts, spannerBundle, and textBoxes

>>> emptySX = musicxml.m21ToXml.ScoreExporter()
>>> emptySX.scorePreliminaries() # will call emptyObject
>>> len(emptySX.textBoxes)
0
>>> emptySX.spannerBundle
<music21.spanner.SpannerBundle of size 0>
ScoreExporter.setDefaults()

Returns a default object from self.firstScoreLayout or a very simple one if none exists.

Simple:

>>> SX = musicxml.m21ToXml.ScoreExporter()
>>> mxDefaults = SX.setDefaults()
>>> SX.dump(mxDefaults)
<defaults>
  <scaling>
    <millimeters>7</millimeters>
    <tenths>40</tenths>
  </scaling>
</defaults>

These numbers come from the defaults module:

>>> defaults.scalingMillimeters
7
>>> defaults.scalingTenths
40

More complex:

>>> s = corpus.parse('schoenberg/opus19', 2)
>>> SX = musicxml.m21ToXml.ScoreExporter(s)
>>> SX.setScoreLayouts() # necessary to call before .setDefaults()
>>> mxDefaults = SX.setDefaults()
>>> mxDefaults.tag
'defaults'
>>> mxScaling = mxDefaults.find('scaling')
>>> SX.dump(mxScaling)
<scaling>
  <millimeters>6.1472</millimeters>
  <tenths>40</tenths>
</scaling>
>>> mxPageLayout = mxDefaults.find('page-layout')
>>> SX.dump(mxPageLayout)
<page-layout>
  <page-height>1818</page-height>
  <page-width>1405</page-width>
  <page-margins>
    <left-margin>83</left-margin>
    <right-margin>83</right-margin>
    <top-margin>103</top-margin>
    <bottom-margin>103</bottom-margin>
  </page-margins>
</page-layout>
>>> mxSystemLayout = mxDefaults.find('system-layout')
>>> SX.dump(mxSystemLayout)
<system-layout>
  <system-margins>
    <left-margin>0</left-margin>
    <right-margin>0</right-margin>
  </system-margins>
  <system-distance>121</system-distance>
  <top-system-distance>70</top-system-distance>
</system-layout>
>>> mxStaffLayoutList = mxDefaults.findall('staff-layout')
>>> len(mxStaffLayoutList)
1
>>> SX.dump(mxStaffLayoutList[0])
<staff-layout>
  <staff-distance>98</staff-distance>
</staff-layout>
ScoreExporter.setEncoding()

Returns an encoding object that might have information about <supports> also. and appends to mxIdentification (if any)

Will use the date of generation as encoding-date.

>>> SX = musicxml.m21ToXml.ScoreExporter()
>>> mxEncoding = SX.setEncoding()
>>> SX.dump(mxEncoding)
<encoding>
  <encoding-date>20...-...-...</encoding-date>
  <software>Music21</software>
</encoding>

Encoding-date is in YYYY-MM-DD format.

ScoreExporter.setIdentification()

Returns an identification object from self.scoreMetadata. And appends to the score...

For defaults:

>>> SX = musicxml.m21ToXml.ScoreExporter()
>>> mxIdentification = SX.setIdentification()
>>> SX.dump(mxIdentification)
<identification>
  <creator type="composer">Music21</creator>
  <encoding>
    <encoding-date>20...-...-...</encoding-date>
    <software>Music21</software>
  </encoding>
</identification>

More realistic:

>>> md = metadata.Metadata()
>>> md.composer = 'Francesca Caccini'
>>> c = metadata.Contributor(role='arranger', name='Aliyah Shanti')
>>> md.addContributor(c)

need a fresh ScoreExporter ...otherwise appends to existing mxIdentification

>>> SX = musicxml.m21ToXml.ScoreExporter()
>>> SX.scoreMetadata = md
>>> mxIdentification = SX.setIdentification()
>>> SX.dump(mxIdentification)
<identification>
  <creator type="composer">Francesca Caccini</creator>
  <creator type="arranger">Aliyah Shanti</creator>
  <encoding>
    <encoding-date>...</encoding-date>
    <software>Music21</software>
  </encoding>
</identification>
ScoreExporter.setMeterStream()

sets self.meterStream or uses a default.

Used in makeNotation in Part later.

>>> b = corpus.parse('bwv66.6')
>>> SX = musicxml.m21ToXml.ScoreExporter(b)
>>> SX.setMeterStream()
>>> SX.meterStream
<music21.stream.Score 0x...>
>>> len(SX.meterStream)
4
>>> SX.meterStream[0]
<music21.meter.TimeSignature 4/4>
ScoreExporter.setPartList()

Returns a <part-list> and appends it to self.xmlRoot.

This is harder than it looks because MusicXML and music21’s idea of where to store staff-groups are quite different.

We find each stream in self.partExporterList, then look at the StaffGroup spanners in self.spannerBundle. If the part is the first element in a StaffGroup then we add a <staff-group> object with ‘start’ as the starting point (and same for multiple StaffGroups) this is in staffGroupToXmlPartGroup(sg). then we add the <score-part> descriptor of the part and its instruments, etc. (currently just one!), then we iterate again through all StaffGroups and if this part is the last element in a StaffGroup we add a <staff-group> descriptor with type=”stop”.

This Bach example has four parts and one staff-group bracket linking them:

>>> b = corpus.parse('bwv66.6')
>>> SX = musicxml.m21ToXml.ScoreExporter(b)

Needs some strange setup to make this work in a demo. .parse() takes care of all this.

>>> SX.scorePreliminaries()    
>>> SX.parsePartlikeScore()
>>> mxPartList = SX.setPartList()
>>> SX.dump(mxPartList)
<part-list>
  <part-group number="1" type="start">...
  <score-part id="P1">...
  <score-part id="P2">...
  <score-part id="P3">...
  <score-part id="P4">...
  <part-group number="1" type="stop" />
</part-list>
ScoreExporter.setPartsAndRefStream()

Transfers the offset of the inner stream to elements and sets self.highestTime

>>> b = corpus.parse('bwv66.6')
>>> SX = musicxml.m21ToXml.ScoreExporter(b)
>>> SX.highestTime
0.0
>>> SX.setPartsAndRefStream()
>>> SX.highestTime
36.0
>>> SX.refStreamOrTimeRange
[0.0, 36.0]
>>> len(SX.parts)
4
ScoreExporter.setScoreHeader()

Sets the group score-header in <score-partwise>. Note that score-header is not a separate tag, but just a way of crouping things from the tag.

runs setTitles(), setIdentification(), setDefaults(), changes textBoxes to <credit> and does the major task of setting up the part-list with setPartList()

ScoreExporter.setScoreLayouts()

sets self.scoreLayouts and self.firstScoreLayout

>>> b = corpus.parse('schoenberg/opus19', 2)
>>> SX = musicxml.m21ToXml.ScoreExporter(b)
>>> SX.setScoreLayouts()
>>> SX.scoreLayouts
<music21.stream.Score 0x...>
>>> len(SX.scoreLayouts)
1
>>> SX.firstScoreLayout
<music21.layout.ScoreLayout>
ScoreExporter.setTitles()

puts work (with work-title), movement-number, movement-title into the self.xmlRoot

ScoreExporter.staffGroupToXmlPartGroup(staffGroup)

Create and configure an mxPartGroup object for the ‘start’ tag from a staff group spanner. Note that this object is not completely formed by this procedure. (number isn’t done...)

>>> b = corpus.parse('bwv66.6')
>>> SX = musicxml.m21ToXml.ScoreExporter(b)
>>> firstStaffGroup = b.spannerBundle.getByClass('StaffGroup')[0]
>>> mxPartGroup = SX.staffGroupToXmlPartGroup(firstStaffGroup)
>>> SX.dump(mxPartGroup)
<part-group type="start">
  <group-symbol>bracket</group-symbol>
  <group-barline>yes</group-barline>
</part-group>

At this point, you should set the number of the mxPartGroup, since it is required:

>>> mxPartGroup.set('number', str(1))        

What can we do with it?

>>> firstStaffGroup.name = 'Voices'
>>> firstStaffGroup.abbreviation = 'Ch.'
>>> firstStaffGroup.symbol = 'brace' # 'none', 'brace', 'line', 'bracket', 'square'
>>> firstStaffGroup.barTogether = False  # True, False, or 'Mensurstrich'
>>> mxPartGroup = SX.staffGroupToXmlPartGroup(firstStaffGroup)
>>> SX.dump(mxPartGroup)
<part-group type="start">
  <group-name>Voices</group-name>
  <group-abbreviation>Ch.</group-abbreviation>
  <group-symbol>brace</group-symbol>
  <group-barline>no</group-barline>
</part-group>
ScoreExporter.textBoxToXmlCredit(textBox)

Convert a music21 TextBox to a MusicXML Credit.

>>> tb = text.TextBox('testing')
>>> tb.positionVertical = 500
>>> tb.positionHorizontal = 300
>>> tb.page = 3
>>> SX = musicxml.m21ToXml.ScoreExporter()
>>> mxCredit = SX.textBoxToXmlCredit(tb)
>>> SX.dump(mxCredit)
<credit page="3">
  <credit-words default-x="300" default-y="500" 
       halign="center" valign="top">testing</credit-words>
</credit>

Default of page 1:

>>> tb = text.TextBox('testing')
>>> tb.page
1
>>> mxCredit = SX.textBoxToXmlCredit(tb)
>>> SX.dump(mxCredit)
<credit page="1">...</credit>

Methods inherited from XMLExporterBase:

XMLExporterBase

class music21.musicxml.m21ToXml.XMLExporterBase

contains functions that could be called at multiple levels of exporting (Score, Part, Measure).

XMLExporterBase methods

XMLExporterBase.asBytes(noCopy=True)

returns the xmlRoot as a bytes object (str in Py2). If noCopy is True (default), modifies the file for pretty-printing in place. Otherwise, make a copy.

XMLExporterBase.dump(obj)

wrapper around xml.etree.ElementTree as ET that returns a string in every case, whether Py2 or Py3...

>>> from music21.musicxml.m21ToXml import Element
>>> e = Element('accidental')
>>> XB = musicxml.m21ToXml.XMLExporterBase()
>>> XB.dump(e)
<accidental />
>>> e.text = u'∆'
>>> e.text == u'∆'
True
>>> XB.dump(e)
<accidental>...</accidental>

Output differs in Python2 vs 3.

XMLExporterBase.indent(elem, level=0)

helper method, indent an element in place:

XMLExporterBase.pageLayoutToXmlPageLayout(pageLayout, mxPageLayoutIn=None)

get a <page-layout> element from a PageLayout

Called out from pageLayoutToXmlPrint because it is also used in the <defaults> tag

XMLExporterBase.pageLayoutToXmlPrint(pageLayout, mxPrintIn=None)

Given a PageLayout object, set object data for <print>

>>> pl = layout.PageLayout()
>>> pl.pageHeight = 4000
>>> pl.isNew = True
>>> pl.rightMargin = 30.25
>>> pl.leftMargin = 20
>>> pl.pageNumber = 5
>>> XPBase = musicxml.m21ToXml.XMLExporterBase()
>>> mxPrint = XPBase.pageLayoutToXmlPrint(pl)
>>> XPBase.dump(mxPrint)
<print new-page="yes" page-number="5">
  <page-layout>
    <page-height>4000</page-height>
    <page-margins>
      <left-margin>20</left-margin>
      <right-margin>30.25</right-margin>
    </page-margins>
  </page-layout>
</print>
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> pl2 = MP.xmlPrintToPageLayout(mxPrint)
>>> pl2.isNew
True
>>> pl2.rightMargin
30.25
>>> pl2.leftMargin
20
>>> pl2.pageNumber
5    
>>> pl2.pageHeight
4000
XMLExporterBase.setPosition(m21Object, mxObject)
XMLExporterBase.staffLayoutToXmlStaffLayout(staffLayout, mxStaffLayoutIn=None)

get a <staff-layout> tag from a StaffLayout object

In music21, the <staff-layout> and <staff-details> are intertwined in a StaffLayout object.

>>> sl = layout.StaffLayout()
>>> sl.distance = 40.0
>>> sl.staffNumber = 1
>>> XPBase = musicxml.m21ToXml.XMLExporterBase()
>>> mxSl = XPBase.staffLayoutToXmlStaffLayout(sl)
>>> XPBase.dump(mxSl)
<staff-layout number="1">
  <staff-distance>40.0</staff-distance>
</staff-layout>
XMLExporterBase.systemLayoutToXmlPrint(systemLayout, mxPrintIn=None)

Given a SystemLayout tag, set a <print> tag

>>> sl = layout.SystemLayout()
>>> sl.distance = 55
>>> sl.isNew = True
>>> sl.rightMargin = 30.25
>>> sl.leftMargin = 20
>>> XPBase = musicxml.m21ToXml.XMLExporterBase()
>>> mxPrint = XPBase.systemLayoutToXmlPrint(sl)
>>> XPBase.dump(mxPrint)
<print new-system="yes">
  <system-layout>
    <system-margins>
      <left-margin>20</left-margin>
      <right-margin>30.25</right-margin>
    </system-margins>
    <system-distance>55</system-distance>
  </system-layout>
</print>

Test return conversion

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> sl2 = MP.xmlPrintToSystemLayout(mxPrint)
>>> sl2.isNew
True
>>> sl2.rightMargin
30.25
>>> sl2.leftMargin
20
>>> sl2.distance
55
XMLExporterBase.systemLayoutToXmlSystemLayout(systemLayout, mxSystemLayoutIn=None)

get given a SystemLayout object configure <system-layout> or <print>

Called out from xmlPrintToSystemLayout because it is also used in the <defaults> tag

>>> sl = layout.SystemLayout()
>>> sl.distance = 40.0
>>> sl.topDistance = 70.0
>>> XPBase = musicxml.m21ToXml.XMLExporterBase()
>>> mxSl = XPBase.systemLayoutToXmlSystemLayout(sl)
>>> XPBase.dump(mxSl)
<system-layout>
  <system-distance>40.0</system-distance>
  <top-system-distance>70.0</top-system-distance>
</system-layout>
>>> sl = layout.SystemLayout()
>>> sl.leftMargin = 30.0
>>> mxSl = XPBase.systemLayoutToXmlSystemLayout(sl)
>>> XPBase.dump(mxSl)
<system-layout>
  <system-margins>
    <left-margin>30.0</left-margin>
  </system-margins>
</system-layout>
XMLExporterBase.xmlHeader()