
    rh>                   x   % S SK Jr  S SKrS SKrS SKrS SKrS SKJr  S SKrS SK	r
S SKrS SKJs  Jr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  S SKJr  S SKJrJr  S SKJr  S SKJ r   S SKJ!r!  S SKJ"r"  S SKJ#r#  S SKJ$r$  S SKJ%r%  S SKJ&r&  S SKJ'r'  S SKJ(r(  S SKJ)r)  S SK*J+r+J,r,  S SKJ-r-  S SKJ.r.  S SKJ/r/  S SKJ0r0  S SKJ1r1  S S KJ2r2  S S!KJ3r3  S S"KJ4r4  S S#KJ5r5  S S$KJ6r6  S S%KJ7r7  S S&K8J9r9  S S'K8J:r:  S S(K;J<r<  S S)K=J>r>J?r?  \:R                  rA\:R                  rC\
R                  (       a   S S*KJErE  S S+KFJGrG  \H\I\J\ER                     4   rL\ R                  " S,5      rNS rO\J" \(R                  R                  \(R                  R                  -   \(R                  R                  -   5      rTS-\US.'   SAS/ jrVSBS0 jrWSCS1 jrXS2 rYSDSS3.S4 jjrZSES5 jr[ " S6 S75      r\ " S8 S95      r] " S: S;\\5      r^ " S< S=\\5      r_ " S> S?\<\\5      r`\aS@:X  a  S SKr\R                  " 5         gg)F    )annotationsN)isclose)articulations)bar)beam)chord)clef)common)defaultsduration)dynamics)OrnamentDelay)opFracnearestMultiple)	editorial)environment)exceptions21)expressions)harmony)
instrument)intervalkey)layout)metadata)meter)MIDIPercussionExceptionPercussionMapper)note)
percussion)pitch)repeat)spanner)stream)style)	tablature)tempo)text)tie)
xmlObjects)helpers)SoundTagMixin)MusicXMLImportExceptionMusicXMLWarning)base)OffsetQLzmusicxml.xmlToM21z	list[str]_recognizableKeysc                R    U c  g U R                  5       n U R                  SS5      nU$ )N
 )stripreplace)badStrgoodStrs     S/home/james-whalen/.local/lib/python3.13/site-packages/music21/musicxml/xmlToM21.py_cleanr;   [   s*    ~\\^FnnT3'GN    c                l    U c  g U R                   nUc  gUR                  5       $ ! [         a     gf = f)a  
Returns the `mxObj.text.strip()` from an Element (or None)
taking into account that `.text` might be None, or the
Element might be undefined.

Replacement for the older textStripValid()

>>> from xml.etree.ElementTree import Element
>>> e = Element('an-element')
>>> musicxml.xmlToM21.strippedText(e)
''
>>> e.text = '    '
>>> musicxml.xmlToM21.strippedText(e)
''
>>> e.text = '  hello  '
>>> musicxml.xmlToM21.strippedText(e)
'hello'

>>> musicxml.xmlToM21.strippedText(None)
''
>>> musicxml.xmlToM21.strippedText(440.0)
''

New in v9.
 )r)   r6   AttributeError)mxObjtxts     r:   strippedTextrB   d   s@    4 }jj;yy{ s   & & 
33c                f    U [         R                  ;  a  U S:X  a  gU S:X  a  g[        SU  35      eU $ )a1  
Utility function to convert a MusicXML duration type to a music21 duration type.

Changes 'long' to 'longa' and deals with a Guitar Pro 5.2 bug in MusicXML
export, that exports a 32nd note with the type '32th'.

>>> musicxml.xmlToM21.musicXMLTypeToType('long')
'longa'
>>> musicxml.xmlToM21.musicXMLTypeToType('32th')
'32nd'
>>> musicxml.xmlToM21.musicXMLTypeToType('quarter')
'quarter'
>>> musicxml.xmlToM21.musicXMLTypeToType(None)
Traceback (most recent call last):
music21.musicxml.xmlObjects.MusicXMLImportException:
    found unknown MusicXML type: None
longlonga32th32ndzfound unknown MusicXML type: )r   typeToDurationr.   )values    r:   musicXMLTypeToTyperJ      s>    & H+++F?f_),I%*QRRr<   c                ~    U c  g [        U 5      nU[        U5      :X  a  [        U5      nU$ ! [         a    U s $ f = f)z
Convert a string to float or int if possible.

>>> _f = musicxml.xmlToM21._floatOrIntStr
>>> _f('20.3')
20.3
>>> _f('20.0')
20
>>> _f(None) is None
True
>>> _f('hi')
'hi'
N)floatint
ValueError)strObjvals     r:   _floatOrIntStrrQ      sG     ~Fm#c(?c(C
 s   &- <<	transformc                   UR                  U5      nUc  gUR                  nUS;   a  gUb  U" U5      nUc  [        R                  " U5      n[	        XU5        g)a  
If xmlEl has at least one element of tag==tag with some text. If
it does, set the attribute either with the same name (with "foo-bar" changed to
"fooBar") or with attributeName to the text contents.

Pass a function or lambda function as `transform` to transform the value before setting it

>>> from xml.etree.ElementTree import Element, SubElement

This is essentially `<accidental><alter>-2</alter></accidental>`:

>>> e = Element('accidental')
>>> a = SubElement(e, 'alter')
>>> a.text = '-2'

>>> seta = musicxml.xmlToM21._setAttributeFromTagText
>>> acc = pitch.Accidental()

Transform the alter text to a float.

>>> seta(acc, e, 'alter', transform=float)
>>> acc.alter
-2.0

>>> e2 = Element('score-partwise')
>>> a2 = SubElement(e2, 'movement-title')
>>> a2.text = 'Trout'
>>> md = metadata.Metadata()
>>> seta(md, e2, 'movement-title', 'movementName')
>>> md.movementName
'Trout'

set a different attribute

>>> seta(md, e2, 'movement-title', 'composer')
>>> md.composer
'Trout'
NNr>   )findr)   r
   hyphenToCamelCasesetattr)m21ElxmlEltagattributeNamerS   matchElrI   s          r:   _setAttributeFromTagTextr^      s^    N jjoGLLE
% 005E%(r<   c                v    UR                  U5      nUc  g UR                  nUS;   a  g U R                  X55        g )NrU   )rV   r)   add)m21mdrZ   r[   mdUniqueNamer]   rI   s         r:   _addMetadataItemFromTagTextrc      s7    jjoGLLE
	IIl"r<   c                      \ rS rSrSrSSSSSSS	.rSS jrS rS rS r	S r
S rS rS rS rS rS rSS jrSS jrSS jrSS jrSS jrSrg
)XMLParserBasei  z_
contains functions that could be called
at multiple levels of parsing (Score, Part, Measure).
z
half-sharpzone-and-a-half-sharpz	half-flatzone-and-a-half-flatzdouble-flatzdouble-sharp)zquarter-sharpzthree-quarters-sharpzquarter-flatzthree-quarters-flatz	flat-flatzsharp-sharpNc                *   [        U[        R                  5      (       a  UnOSn[        R                  " U5      (       d  U4nUc
  S U 5       nO[        R                  " U5      (       d  U4n[        X45       H  u  pgUR                  U5      nUc  M  U[        R                  ;   a  [        R                  " U5      n USLa  USLa  [        R                  " U5      nUc  UR                  n[        XWU5        M     g! [        [        4 a     N2f = f)aY  
Takes an mxObject, a music21Object, and a list/tuple of musicXML names and
a list/tuple of m21Names, and assigns each of the mxObject's attributes
that fits this style name to the corresponding style object's m21Name attribute.

>>> from xml.etree.ElementTree import fromstring as El
>>> XP = musicxml.xmlToM21.XMLParserBase()
>>> mxObj = El('<a x="20.1" y="10.0" z="yes" />')
>>> m21Obj = base.Music21Object()
>>> musicXMLNames = ('w', 'x', 'y', 'z')
>>> m21Names = ('justify', 'absoluteX', 'absoluteY', 'hideObjectOnPrint')

>>> XP.setStyleAttributes(mxObj, m21Obj, musicXMLNames, m21Names)

`.justify` requires a TextStyle object.

>>> m21Obj.style.justify
Traceback (most recent call last):
AttributeError: 'Style' object has no attribute 'justify'

>>> m21Obj.style.absoluteX
20.1
>>> m21Obj.style.absoluteY
10
>>> m21Obj.style.hideObjectOnPrint
True
Nc              3  N   #    U  H  n[         R                  " U5      v   M     g 7fN)r
   rW   ).0xs     r:   	<genexpr>3XMLParserBase.setStyleAttributes.<locals>.<genexpr>:  s     K]0033]s   #%TF)
isinstancer&   Styler
   
isIterablezipgetr+   STYLE_ATTRIBUTES_YES_NO_TO_BOOLyesNoToBooleannumToIntOrFloatrN   	TypeErrorrX   )	selfmxObject	m21ObjectmusicXMLNamesm21NamesstObjxmlNamem21NamemxValues	            r:   setStyleAttributes XMLParserBase.setStyleAttributes  s    : i--EE  //*,MK]KH""8,, {H #M <Gll7+G*DDD$33G<$&7%+?$44W=G
 }!EG,# != 	* s   ? C??DDc                R    SnSnU R                  XX45        U R                  X5        g)a<  
sets the justification, print-style-align group, and
text-decoration, text-rotation,
letter-spacing, line-height, lang, text-direction, and
enclosure, on an
m21Object, which must have style.TextStyle as its Style class,
and then calls setPrintStyleAlign

conforms to attr-group %text-formatting in the MusicXML DTD
)justifyztext-decorationztext-rotationzletter-spacingzline-heightlangztext-direction	enclosure)r   textDecorationtextRotationletterSpacing
lineHeightlanguagetextDirectionr   N)r   setPrintStyleAlignrv   rw   rx   ry   rz   s        r:   setTextFormattingXMLParserBase.setTextFormattingQ  s2    OL 	]M4r<   c                    Sn[        US5      (       a  UR                  S5      nUb  XBl        U R                  XU5        g)z
Sets four additional elements for line elements, conforms to entity
%line-shape, %line-type, %dashed-formatting (dash-length and space-length)
)
line-shape	line-typezdash-lengthzspace-lengthlineTyper   N)hasattrrq   r   r   )rv   rw   rx   ry   
mxLineTypes        r:   setLineStyleXMLParserBase.setLineStyled  sA    
 S9j))!k2J%%/"]Cr<   c                    UR                  S5      S:w  a  g[        US5      (       a  SUR                  l        g SUl        g! [         a     gf = f)zI
convert 'print-object="no"' to m21Object.style.hideObjectOnPrint = True
print-objectnoNr&   T)rq   r   r&   hideObjectOnPrintr?   rv   rw   rx   s      r:   setPrintObjectXMLParserBase.setPrintObjectr  sP     <<'4/9g&&04IOO-.2	+! s   A 
AAc                N    U R                  X5        U R                  UUSS5        g)z
runs setPrintStyle and then sets horizontalAlign and verticalAlign, on an
m21Object, which must have style.TextStyle as its Style class.

conforms to attr-group %print-style-align in the MusicXML DTD
)valignhalign)alignVerticalalignHorizontalN)setPrintStyler   r   s      r:   r    XMLParserBase.setPrintStyleAlign  s,     	8/ ) 4 D	Fr<   c                j    U R                  X5        U R                  X5        U R                  X5        g)z
get position, font, and color information from the mxObject
into the m21Object, which must have style.TextStyle as its Style class.

conforms to attr-group %print-style in the MusicXML DTD
N)setPositionsetFontsetColorr   s      r:   r   XMLParserBase.setPrintStyle  s*     	-X)h*r<   c                *    U R                  XSS5        g)z5
Sets m21Object.style.color to be the same as color.
colorNr   r   s      r:   r   XMLParserBase.setColor  s     	WgFr<   c                0    SnSnU R                  XX45        g)a  
sets font-family, font-style, font-size, and font-weight as
fontFamily (list), fontStyle, fontSize and fontWeight from
an object into a TextStyle object

conforms to attr-group %font in the MusicXML DTD

>>> from xml.etree.ElementTree import fromstring as El
>>> XP = musicxml.xmlToM21.XMLParserBase()
>>> mxObj = El('<text font-family="Courier,monospaced" font-style="italic" '
...            + 'font-size="24" font-weight="bold" />')

>>> te = expressions.TextExpression('hi!')
>>> XP.setFont(mxObj, te)
>>> te.style.fontFamily
['Courier', 'monospaced']
>>> te.style.fontStyle
'italic'
>>> te.style.fontSize
24
>>> te.style.fontWeight
'bold'
)zfont-familyz
font-stylez	font-sizezfont-weight)
fontFamily	fontStylefontSize
fontWeightNr   r   s        r:   r   XMLParserBase.setFont  s    0 RH]Mr<   c                0    SnSnU R                  XX45        g)z
get positioning information for an object from
default-x, default-y, relative-x, relative-y into
the .style attribute's absoluteX, relativeX, etc. attributes'

conforms to attr-group %position in the MusicXML DTD
)z	default-xz	default-yz
relative-xz
relative-y)	absoluteX	absoluteY	relativeX	relativeYNr   r   s        r:   r   XMLParserBase.setPosition  s     OG]Mr<   c                ~    UR                  S5      nUc  g[        US5      (       a  X2l        gX2R                  l        g)z
Sets the placement for objects that have a .placement attribute
(most but not all spanners) and sets the `style.placement` for those
that don't.
	placementN)rq   r   r   r&   )rv   rw   rx   r   s       r:   setPlacementXMLParserBase.setPlacement  s8     LL-	9k**"+(1OO%r<   c                   UR                  S5      nUR                  S5      nUc  Uc  g[        R                  " 5       nUb)  UR                  Ul        SUl        U R                  X55        Ub/  UR                  Ul        UR                  S5      nUS:X  a  SUl        UR                  (       a&  UR                  R                  R                  U5        gUR                  R                  R                  U5        g)a  
Set editorial information from an mxObj

>>> from xml.etree.ElementTree import fromstring as El
>>> XP = musicxml.xmlToM21.XMLParserBase()
>>> mxObj = El('<a/>')
>>> n = note.Note('C#4')

Most common case:

>>> XP.setEditorial(mxObj, n)
>>> n.hasEditorialInformation
False

>>> mxObj = El('<note><footnote>Sharp is conjectural</footnote>'
...            + '<level reference="yes">2</level></note>')
>>> XP.setEditorial(mxObj, n)
>>> n.hasEditorialInformation
True
>>> len(n.editorial.footnotes)
1
>>> fn = n.editorial.footnotes[0]
>>> fn
<music21.editorial.Comment 'Sharp is conjectu...'>
>>> fn.isFootnote
True
>>> fn.levelInformation
'2'
>>> fn.isReference
True

If no <footnote> tag exists, the editorial information will be found in
comments:

>>> mxObj = El('<note><level reference="no">ed</level></note>')
>>> n = note.Note('C#4')
>>> XP.setEditorial(mxObj, n)
>>> len(n.editorial.footnotes)
0
>>> len(n.editorial.comments)
1
>>> com = n.editorial.comments[0]
>>> com.isReference
False
>>> com.text is None
True
>>> com.levelInformation
'ed'
footnotelevelNT	referenceyes)rV   r   Commentr)   
isFootnoter   levelInformationrq   isReference	footnotesappendcomments)rv   r@   m21Obj
mxFootnotemxLevelcreferenceAttributes          r:   setEditorialXMLParserBase.setEditorial  s    f ZZ
+
**W%'/!__AFAL"":1!(A!([!9!U* $
 <<&&--a0%%,,Q/r<   c                    Uc  [         R                  " 5       nOUn[        nU" X1SS[        R                  S9  U" X1S[
        S9  U H$  nUR                  S:X  d  M  U R                  XSS9    O   Uc  U$ g)a  
Given an mxPrint object, set object data for
the print section of a layout.PageLayout object


>>> from xml.etree.ElementTree import fromstring as El
>>> MP = musicxml.xmlToM21.MeasureParser()


>>> mxPrint = El('<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>')

>>> pl = MP.xmlPrintToPageLayout(mxPrint)
>>> pl.isNew
True
>>> pl.rightMargin
30.25
>>> pl.leftMargin
20
>>> pl.pageNumber
5
>>> pl.pageHeight
4000
Nnew-pageisNewrR   page-numberpage-layoutinputM21)r   
PageLayoutsetAttributeFromAttributer+   rs   rM   r[   xmlPageLayoutToPageLayout)rv   mxPrintr   
pageLayoutsetbrj   s         r:   xmlPrintToPageLayout"XMLParserBase.xmlPrintToPageLayout(  s    : **,J!J(Z*gAZAZ[Z-3?Auu%..q.F 
  r<   c                    Uc  [         R                  " 5       nOUn[        nU" X1S[        S9  U" X1S[        S9  UR	                  S5      nUb  S H  nU" X5US-   [        S9  M     Uc  U$ g)z
get a PageLayout object from an mxPageLayout

Called out from mxPrintToPageLayout because it
is also used in the <defaults> tag
Nzpage-heightrR   z
page-widthzpage-marginstopbottomleftright-margin)r   r   r^   rQ   rV   )rv   mxPageLayoutr   r   setamxPageMargins	directions          r:   r   'XMLParserBase.xmlPageLayoutToPageLayoutV  s     **,J!J'Z}OZ|~N %)).9$?	Z	I0E-/ @  r<   c                    Uc  [         R                  " 5       nOUn[        nU" X1SS[        R                  5        UR                  S5      nUb  U R                  XSS9  Uc  U$ g)a3  
Given an mxPrint object, set object data

>>> from xml.etree.ElementTree import fromstring as El
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxPrint = El('<print new-system="yes">'
...    + '    <system-layout><system-distance>55</system-distance>'
...    + '        <system-margins><left-margin>20</left-margin>'
...    + '                 <right-margin>30.25</right-margin></system-margins>'
...    + '</system-layout></print>')
>>> sl = MP.xmlPrintToSystemLayout(mxPrint)
>>> sl.isNew
True
>>> sl.rightMargin
30.25
>>> sl.leftMargin
20
>>> sl.distance
55
N
new-systemr   system-layoutr   )r   SystemLayoutr   r+   rs   rV   xmlSystemLayoutToSystemLayout)rv   r   r   systemLayoutr   mxSystemLayouts         r:   xmlPrintToSystemLayout$XMLParserBase.xmlPrintToSystemLayoutq  sn    . !..0L#L(\L':;T;TU !o6%..~.U r<   c                    Uc  [         R                  " 5       nOUn[        nUR                  S5      nUb  S H  nU" X5US-   [        S9  M     U" X1SS[        S9  U" X1SS	[        S9  Uc  U$ g)
z
get a SystemLayout object from an <system-layout> element

Called out from xmlPrintToSystemLayout because it
is also used in the <defaults> tag
Nzsystem-marginsr   r   rR   zsystem-distancedistanceztop-system-distancetopDistance)r   r   r^   rV   rQ   )rv   r   r   r   r   mxSystemMarginsr   s          r:   r   +XMLParserBase.xmlSystemLayoutToSystemLayout  s     !..0L#L' )--.>?&?	\I	4I-/ @ 	\+<j%	'\+@-%	'
  r<   c                B   Uc  [         R                  " 5       nOUn[        nU" X1SS[        S9  UR	                  S5      nUb  [        U5      nXSl        [        U S5      (       a6  [        U S5      (       a%  U=(       d    SU R                  4nX0R                  U'   Uc  U$ g)	z
get a StaffLayout object from an <staff-layout> tag

In music21, the <staff-layout> and <staff-details> are
intertwined in a StaffLayout object.
Nzstaff-distancer   rR   numberstaffLayoutObjectsoffsetMeasureNote   )
r   StaffLayoutr^   rQ   rq   rM   staffNumberr   r   r   )rv   mxStaffLayoutr   staffLayoutr   r   staffLayoutKeys          r:   xmlStaffLayoutToStaffLayout)XMLParserBase.xmlStaffLayoutToStaffLayout  s      ,,.K"K'[z^	E $''1"k*K&1#4-..74AT3U3U*/a$2H2HIN6A##N3 r<    rh   )__name__
__module____qualname____firstlineno____doc__mxAccidentalNameToM21r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  __static_attributes__r  r<   r:   re   re     s}     /;5K-84I*7,:;-z5&DF	+GN8
N2M0^,\6& P >r<   re   c                  $    \ rS rSrSrS rS rSrg)	PartGroupi  zz
Small helper class for keeping track of part-groups from XML since they
are converted to StaffGroup spanners much later.
c                n    Xl         / U l        UR                  S5      nUb  [        U5      nOSnX l        g )Nr   r   )mxPartGrouppartGroupIdsrq   rM   r   )rv   r  r   s      r:   __init__PartGroup.__init__  s7    &*[FFr<   c                :    U R                   R                  U5        g)z(
Add a partGroupId to self.partGroupIds
N)r  r   )rv   partGroupIds     r:   r`   PartGroup.add  s     	  -r<   )r  r   r  N)r  r  r	  r
  r  r  r`   r  r  r<   r:   r  r    s    
.r<   r  c                     ^  \ rS rSrSrU 4S jrS rS rS rSS jr	S r
S	 rS
 rSS jrS rS rS rSS jr S   SS jjr\SS j5       rSS jr S   SS jjrS rSrU =r$ )MusicXMLImporteri  zJ
Object for importing .xml, .mxl, .musicxml, MusicXML files into music21.
c                B  > [         TU ]  5         S U l        S U l        S U l        [
        R                  " 5       U l        SU l        SU l        U R
                  R                  U l	        0 U l
        0 U l        / U l        / U l        [        R                  U l        SU l        g )NF)superr  xmlTextxmlFilenamexmlRootr%   ScoredefinesExplicitSystemBreaksdefinesExplicitPageBreaksspannerBundlemxScorePartDictm21PartObjectsByIdpartGroupListpartsr   musicxmlVersionmusicXmlVersionapplyFinaleWorkarounds)rv   	__class__s    r:   r  MusicXMLImporter.__init__  s    lln+0().&![[66!"$
'77
 ',#r<   c                <    U R                  U5        U R                  $ )z\
main program: opens a file given by filename and returns a complete
music21 Score from it.
)readFiler%   )rv   filenames     r:   scoreFromFileMusicXMLImporter.scoreFromFile
  s     	h{{r<   c                &   [         R                  " U5      nUR                  5       U l        U R                  R                  S:w  a&  [        SSU R                  R                   S3-   5      eU R                  U R                  U R                  5        g )Nscore-partwise3Cannot parse MusicXML files not in score-partwise. Root tag was '')ETparsegetrootr  r[   r.   xmlRootToScorer%   )rv   r.  etrees      r:   r-  MusicXMLImporter.readFile  sw    "}}<<//)*_.<T\\=M=M<Na,P+Q R RDLL$++6r<   c                d   [        U R                  [        5      (       a   U R                  R                  S5      U l        [        R
                  " U R                  5      n [        R                  " U5      nUR                  5       U l	        U R                  R                  S:w  a&  [        SSU R                  R                   S3-   5      eU R                  U R                  U R                  5        g ! [        R                   a(    [        R                  " U R                  5      U l	         Nf = f)Nzutf-8r2  r3  r4  r5  )rm   r  bytesdecodeioStringIOr6  r7  r8  r  
ParseErrorXMLr[   r.   r9  r%   )rv   sior:  s      r:   parseXMLTextMusicXMLImporter.parseXMLText  s    dllE**<<..w7DLkk$,,'	0 HHSME ==?DL
 <<//)*_.<T\\=M=M<Na,P+Q R RDLL$++6 }} 	066$,,/DL	0s   !+C3 39D/.D/c                   Uc  [         R                  " 5       nOUnUR                  S5      nUb  X@l        U R	                  U5      nUR                  SU5        UR                  S5      nUb#  U R                  U5      nUR                  SU5        UR                  S5       H&  nU R                  U5      n	UR                  SU	5        M(     U R                  U5        UR                  S5       H  n
U
R                  S5      nUc&  [        U R                  R                  5       5      S   n U R                  U   nU R#                  X5      nUc  Mc  UR                  S
U5        XR$                  U'   M     U R'                  5         U R(                  R+                  [,        R.                  5       H
  nSUl        M     / nU R(                  R3                  S5       H0  nU R                   R                  SU5        UR5                  U5        M2     U H  nU R(                  R7                  U5        M      UR9                  5         U R:                  Ul        U R<                  Ul        UR>                   H%  n
U R:                  U
l        U R<                  U
l        M'     URA                  5         Uc  U$ g! [         a     [        R!                  SU 3S	-   5         GM  f = f)z*
parse an xml file into a Score() object.
Nversionr   r   creditpartidz$Cannot find info for part with name z, skipping the part        T)!r%   r  rq   r(  xmlMetadata
coreInsertrV   xmlDefaultsToScoreLayoutfindallxmlCreditToTextBoxparsePartListlistr#  keysKeyErrorenvironLocal
printDebugxmlPartToPartr$  
partGroupsr"  
getByClassr   ArpeggioMarkSpannercompleteStatusgetByCompleteStatusr   removecoreElementsChangedr   r!  r&  sort)rv   mxScorer   s	mxVersionmd
mxDefaultsscoreLayoutmxCreditrH  ppartIdmxScorePartrI  sprms                   r:   r9  MusicXMLImporter.xmlRootToScore.  s    AAKK	*	 #, g&	Q\\*-
!77
CKLLK(1H,,X6FLLF# 2 	7#(AUU4[F~d22779:1="226: %%a5DS$'26''/! )$ 	 $$//0O0OPB $B Q $$88>BKK""1b)IIbM ? B%%b)  	
(,(H(H%&*&D&D#A,0,L,LA)*.*H*HA'  	
H E  ''*Nvh(W*?)@ As   +J--%KKc                n    [        XU S9nUR                  5         UR                  SL a  UR                  $ g)zK
Given a <part> object and the <score-part> object, parse a complete part.
)ri  parentTN)
PartParserr7  appendToScoreAfterParser%   )rv   mxPartri  parsers       r:   rW  MusicXMLImporter.xmlPartToPartt  s4     FDI))T1== r<   c                p   UR                  S5      nUc  g/ nU GH  nUR                  S:X  a;  UR                  S5      nX@R                  U'   U H  nUR	                  U5        M     MO  UR                  S:X  d  Ma  UR                  S5      S:X  a9  [        U5      nU R                  R                  U5        UR                  U5        M  UR                  S5      S:X  d  M  UR                  S	5      nUb  [        U5      nOS
n/ nU H&  nUR                  U:w  d  M  UR                  U5        M(     UnGM     g)z
Parses the <part-list> tag and adds
<score-part> entries into self.mxScorePartDict[partId]
and adds them to any open <part-group> entries,
stored as PartGroup objects in self.partGroupList

z	part-listNz
score-partrJ  z
part-grouptypestartstopr   r   )
rV   r[   rq   r#  r`   r  r%  r   rM   r   )	rv   r`  
mxPartListopenPartGroupspartListElementrh  pgr   opgTemps	            r:   rQ  MusicXMLImporter.parsePartList  s    \\+.
)O""l2(,,T2/>$$V,(BFF6N ) $$4"&&v.'9"?3B&&--b1"))"-$((0F:,00:F)!$V!" G,99.#NN2. - &-N+  *r<   c                "   [         R                  " 5       nSUR                  l        SUR                  l        UR                  S5      nUc  SnO[        U5      nX2l        / nUR                  S5       H0  nUR                   S;  d  M  UR                  UR                   5        M2     U(       d	  SUl
        U$ SR                  U5      Ul
        UR                  S5      nU R                  Xb5        UR                  S5      UR                  l        U$ )	a  
Convert a MusicXML credit to a music21 TextBox

>>> import xml.etree.ElementTree as ET
>>> credit = ET.fromstring(
...               '<credit page="2"><credit-words>Testing</credit-words></credit>')

>>> MI = musicxml.xmlToM21.MusicXMLImporter()
>>> tb = MI.xmlCreditToTextBox(credit)
>>> tb.page
2
>>> tb.content
'Testing'

OMIT_FROM_DOCS

Capella generates empty credit-words

>>> credit = ET.fromstring('<credit><credit-words/></credit>')
>>> tb = MI.xmlCreditToTextBox(credit)
>>> tb
<music21.text.TextBox ''>
Npager   zcredit-wordsrU   r>   r4   r   )r)   TextBoxr&   r   r   rq   rM   r  rO  r   contentjoinrV   r   r   )rv   rf  tbpageNumr  cwcw1s          r:   rP  #MusicXMLImporter.xmlCreditToTextBox  s    2 \\^ $( !%,,v&?G'lG"">2Bwwj(rww' 3 BJIYYw'
mmN+(779- 	r<   c                   Uc  [         R                  " 5       nOUn[        nUR                  S5      nUb  U" X5SS[        S9  U" X5SS[        S9  UR                  S5      nUb  U R                  U5      Ul        UR                  S5      nUb  U R                  U5      Ul        UR                  S	5       H/  nU R                  U5      n	UR                  R                  U	5        M1     U R                  U5        U$ )
zK
Convert a <defaults> tag to a :class:`~music21.layout.ScoreLayout`
object
scalingmillimetersscalingMillimetersrR   tenthsscalingTenthsr   r   staff-layout)r   ScoreLayoutr^   rV   rQ   r   r   r   r   rO  r  staffLayoutListr   styleFromXmlDefaults)
rv   rd  r   re  r   	mxScalingr   r   r  r  s
             r:   rN  )MusicXMLImporter.xmlDefaultsToScoreLayout  s    
  ,,.K"K'OOI.	 8L)+?n] "}5#%)%C%CL%QK"#9%'+'I'I.'YK$'//?M::=IK''..{; @ 	!!*-r<   c                   UR                  S5      nUb  U R                  U5        UR                  S5      nUb@  [        R                  " 5       nU R	                  X45        X@R
                  R                  l        UR                  S5      nUb@  [        R                  " 5       nU R	                  XT5        X@R
                  R                  l        UR                  S5       Hl  n[        R                  " 5       nU R	                  Xd5        UR                  S5      nXt4nU R
                  R                  R                  R                  U5        Mn     UR                  S5       H  n	Sn
U	R                  S5      nU	R                  R                  5        H  u  pUR                  S	5      (       d  M  Un
  O   Xz4nU R
                  R                  R                  R                  U5        M     g)
a  
Set the appearance and font information from mxDefault
<appearance>, <music-font>, <word-font>, <lyric-font> (multiple),
and <lyric-language> tags.

Here the demo does not include the <appearance> tag since that is
documented in `xmlAppearanceToStyle`

>>> import xml.etree.ElementTree as ET
>>> defaults = ET.fromstring('<defaults>'
...          + '<music-font font-family="Maestro, Opus" font-weight="bold" />'
...          + '<word-font font-family="Garamond" font-style="italic" />'
...          + '<lyric-font name="verse" font-size="12" />'
...          + '<lyric-font name="chorus" font-size="14" />'
...          + '<lyric-language name="verse" xml:lang="fr" />'
...          + '<lyric-language name="chorus" xml:lang="en" />'
...          + '</defaults>')

>>> MI = musicxml.xmlToM21.MusicXMLImporter()
>>> MI.styleFromXmlDefaults(defaults)
>>> st = MI.stream.style
>>> st.musicFont
<music21.style.TextStyle object at 0x10535c0f0>
>>> st.musicFont.fontFamily
['Maestro', 'Opus']
>>> st.musicFont.fontWeight
'bold'
>>> st.wordFont.fontFamily
['Garamond']
>>> st.wordFont.fontStyle
'italic'
>>> len(st.lyricFonts)
2
>>> st.lyricFonts[0]
('verse', <music21.style.TextStyle object at 0x10535d438>)
>>> st.lyricFonts[0][1].fontSize
12
>>> st.lyricLanguages
[('verse', 'fr'), ('chorus', 'en')]

appearanceNz
music-fontz	word-fontz
lyric-fontnamezlyric-languageenz}lang)rV   xmlAppearanceToStyler&   	TextStyler   r%   	musicFontwordFontrO  rq   
lyricFontsr   attribitemsendswithlyricLanguages)rv   rd  mxAppearancemxMusicFontst
mxWordFontmxLyricFont	lyricName
styleTuplemxLyricLanguagelyricLanguageaKeyrI   
lyricTuples                 r:   r  %MusicXMLImporter.styleFromXmlDefaults  s   T "|4#%%l3 ool3""BLL)*,KK'__[1
!"BLL()+KK&%--l;K"BLL)#/I#JKK((//
; <  *112BCO M'++F3I.55;;===))$)M	  >
 #1JKK,,33J?  Dr<   c                   UR                  S5       Hf  nUR                  S5      n[        R                  " UR                  5      nX44nU R
                  R                  R                  R                  U5        Mh     UR                  S5       Hf  nUR                  S5      n[        R                  " UR                  5      nXx4n	U R
                  R                  R                  R                  U	5        Mh     UR                  S5       Hf  n
U
R                  S5      n[        R                  " U
R                  5      nX4nU R
                  R                  R                  R                  U5        Mh     UR                  S5       HS  nUR                  S5      nUR                  nUU4nU R
                  R                  R                  R                  U5        MU     g)a  
Parse the appearance tag for information about line widths and note sizes

>>> import xml.etree.ElementTree as ET
>>> appear = ET.fromstring('<appearance>'
...          + '<line-width type="beam">5</line-width>'
...          + '<line-width type="ledger">1.5625</line-width>'
...          + '<note-size type="grace">60</note-size>'
...          + '<distance type="hyphen">0.5</distance>'
...          + '<other-appearance type="sharps">dotted</other-appearance>'
...          + '</appearance>')

>>> MI = musicxml.xmlToM21.MusicXMLImporter()
>>> MI.xmlAppearanceToStyle(appear)
>>> st = MI.stream.style

>>> st.lineWidths
[('beam', 5), ('ledger', 1.5625)]

>>> st.noteSizes
[('grace', 60)]

>>> st.distances
[('hyphen', 0.5)]

>>> st.otherAppearances
[('sharps', 'dotted')]
z
line-widthru  z	note-sizer   zother-appearanceN)rO  rq   r
   rt   r)   r%   r&   
lineWidthsr   	noteSizes	distancesotherAppearances)rv   r  mxLineWidthlineWidthTypelineWidthValuelineWidthInfo
mxNoteSizenoteSizeTypenoteSizeValuenoteSizeInfo
mxDistancedistanceTypedistanceValuedistanceInfomxOther	otherType
otherValue	otherInfos                     r:   r  %MusicXMLImporter.xmlAppearanceToStyleI  sy   < (//=K'OOF3M#33K4D4DEN*;MKK((//>	 > '..{;J%>>&1L"22:??CM(8LKK''..|<	 < '..z:J%>>&1L"22:??CM(8LKK''..|<	 ; $++,>?GF+I J"J/IKK..55i@	 @r<   c                <   [         nU R                   H  n[        R                  " 5       nUR                   H"  n UR                  U R                  U   5        M$     UR                  nU" X8SS	5        U" X8S
S5        UR                  S5      n	U	b-  U" X8SS5        U R                  X5        U R                  X5        OSUl        U" X8SS5        U R!                  X5        SUl        U R$                  R'                  U5        M     g! [         a  nSn[        U R                  5       H>  nUR                  US-   5      (       d  M  UR                  U R                  U   5        SnM@     USL a   [        SSU SU R                  < S3-   5      e SnAGM_  SnAff = f)z4
set StaffGroup objects from the <part-group> tags.
F-StaffTz8Cannot find part in m21PartObjectsById dictionary by Id:r5   z 
   Full Dict:
   Nz
group-namer  zgroup-abbreviationabbreviationzgroup-symbolsymbolbracezgroup-barlinebarTogether)r^   r%  r   
StaffGroupr  addSpannedElementsr$  rT  sorted
startswithr.   r  rV   r   r   r  r   r[  r"  r   )
rv   r   pgObj
staffGrouprh  kefoundOne
partIdTestr  mxGroupSymbols
             r:   rX  MusicXMLImporter.partGroups  s    (''E**,J,,Y11$2I2I&2QR -  ++K,?*>O',,^<M(ZnhG  ;m8$+
!/=I k6(,J%%%j1G (   
Y$H&,T-D-D&E
%00(1BCC&99$:Q:QR\:]^'+H 'F
  5(5V !"%:4;R;R:UUVWXY Y )
Ys   D
F1FA	FFc                f   Uc  U R                   nUc  [        R                  " 5       nOUn[        nUR	                  S5      nUb  U" X5SS5        U" X5SS5        U" X5SS5        U" X1S	S
5        U" X1SS5        US   US   :X  a  SUS'   UR	                  S5      nUb  U R                  Xc5        Uc  U$ g)z
Converts part of the root element into a metadata object

Supported: work-title, work-number, opus, movement-number,
movement-title, identification
Nworkz
work-titletitlezwork-numberr   opus
opusNumberzmovement-numbermovementNumberzmovement-titlemovementNameidentification)r  r   Metadatarc   rV   identificationToMetadata)rv   elr   rc  add_mr  r  s          r:   rL  MusicXMLImporter.xmlMetadata  s     :B""$BB+ wwv"L'2"M84"FL1b')9:b&7 g;"^,,BwK!12%)).=I r<   c                   Ub  UnO[         R                  " 5       nUR                  S5       Hd  nU R                  U5      nUR	                  UR
                  5      (       a  UR                  UR
                  U5        MR  UR                  SU5        Mf     UR                  S5       H&  nU R                  U5      nUR                  SU5          O   UR                  S5      nUb  U R                  Xs5        UR                  S5      nUby  UR                  S5       Hd  n	U	R                  S	5      n
U
c  M  U	R                  nUc  S
nU R                  U
5      (       a  UR                  X5        MS  UR                  X5        Mf     Uc  U$ g)a5  
Convert an <identification> tag, containing <creator> tags, <rights> tags, and
<miscellaneous> tag.

Not supported: source, relation

Only the first <rights> tag is supported

Encoding only parses "supports" and that only has
new-system (definesExplicitSystemBreaks) and
new-page (definesExplicitPageBreaks)
NcreatorotherContributorrights	copyrightencodingmiscellaneouszmiscellaneous-fieldr  r>   )r   r  rO  creatorToContributorisContributorUniqueNameroler`   rightsToCopyrightrV   processEncodingrq   r)   isRecognizableMetadataKey	addCustom)rv   r  r   rc  r  r   r  r  r  mxMiscFieldmiscFieldNamemiscFieldValues               r:   r  )MusicXMLImporter.identificationToMetadata  sq    B""$B%--i8G))'2A))!&&11qvvq! )1- 9 %,,X6F&&v.AFF;" 7
 "&&z2  . '++O<$,445JK + 7 (!,!1!1!)%'N11-@@FF=9 LL?  L I r<   c                    U [         ;   $ )a4  
Returns bool on whether `miscFieldName` is a one of the names
that is among the list of names we might see in <miscellaneous>,
that this parser will interpret as supported metadata keys.
Currently, this is all the uniqueName keys (e.g. 'dateCreated'),
the 'namespace:name' keys (e.g. 'dcterms:created'),
and the pre-v8 music21 workIds (e.g. 'date').

>>> MI = musicxml.xmlToM21.MusicXMLImporter()
>>> MI.isRecognizableMetadataKey('dateCreated')
True
>>> MI.isRecognizableMetadataKey('dcterms:created')
True
>>> MI.isRecognizableMetadataKey('dateDestroyed')
False
)r2   )r  s    r:   r  *MusicXMLImporter.isRecognizableMetadataKey  s    $  111r<   c                   SnSnUR                  S5       H:  n[        U5      =n(       d  M  U(       d  SU;   a  SnSnUR                  SU5        M<     U(       a  SU l        UR                  S5       HY  nUR	                  S5      nUR	                  S5      n	U	c  UR	                  S	5      n	X4S
:X  a	  SU l        MI  X4S:X  d  MR  SU l        M[     g)a  
Process all information in the <encoding> element and put it into the
Metadata object passed in as `md`.

Currently only processes 'software' and these `supports` attributes:

    * new-system = Metadata.definesExplicitSystemBreaks
    * new-page = Metadata.definesExplicitPageBreaks
FsoftwareFinaleTsupports	attributerI   Nru  )r   r   )r   r   )rO  rB   r`   r)  rq   r   r!  )
rv   r  rc  foundOneSoftwareTagfinaleIsFirstr  softwareTextr  attrrI   s
             r:   r   MusicXMLImporter.processEncoding)  s      %*# ((4H+H55|5*</(,&*#z<0 5 *.D' ((4H <<,DLL)E} V, } 55370"5515.! 5r<   c                    Uc  [         R                  " 5       nOUnUR                  S5      nUb  XCl        UR                  nUb  UR                  5       Ul        Uc  U$ g)a3  
Given a <creator> tag, fill the necessary parameters of a Contributor.

>>> import xml.etree.ElementTree as ET
>>> creator = ET.fromstring('<creator type="composer">Beethoven, Ludwig van</creator>')

>>> MI = musicxml.xmlToM21.MusicXMLImporter()
>>> c = MI.creatorToContributor(creator)
>>> c
<music21.metadata.primitives.Contributor composer:Beethoven, Ludwig van>
>>> c.role
'composer'
>>> c.name
'Beethoven, Ludwig van'

Pass in a Contributor object and set it:

>>> c2 = metadata.Contributor()
>>> MI.creatorToContributor(creator, c2)
>>> c2.role
'composer'
Nru  )r   Contributorrq   r  r)   r6   r  )rv   r  r   r   creatorTypecreatorTexts         r:   r  %MusicXMLImporter.creatorToContributorW  sg    4 $$&AAkk&)"
 !Fll" &&(AFH r<   c                    UR                   nUb  UR                  5       n[        R                  " U5      nUR	                  S5      nUb  XCl        U$ )a  
Given a <rights> tag, fill the necessary parameters of a
:class:`~music21.metadata.primitives.Copyright` object.

>>> import xml.etree.ElementTree as ET
>>> rights = ET.fromstring('<rights type="owner">CC-SA-BY</rights>')

>>> MI = musicxml.xmlToM21.MusicXMLImporter()
>>> c = MI.rightsToCopyright(rights)
>>> c
<music21.metadata.primitives.Copyright CC-SA-BY>
>>> c.role
'owner'
>>> str(c)
'CC-SA-BY'
ru  )r)   r6   r   	Copyrightrq   r  )rv   r  rtr   copyrightTypes        r:   r  "MusicXMLImporter.rightsToCopyright  sK    $ [[>Br"

6*$"Fr<   )r)  r!  r   r$  r(  r#  r%  r&  r"  r%   r  r  r  rh   NN)r  
ET.Elementr   zmetadata.Metadata | None)r  strreturnbool)r  r
  rc  metadata.Metadatar  None)r  r
  r   z&metadata.primitives.Contributor | None)r  r  r	  r
  r  r  r/  r-  rD  r9  rW  rQ  rP  rN  r  r  rX  rL  r  staticmethodr  r  r  r  r  __classcell__r*  s   @r:   r  r    s    ,.77$DL	!-F8tBJ@X4Al(2V.d EI91;9+A9v 2 2&,6` OS+&0+'K+Z r<   r  c                    ^  \ rS rSrSr   S     SU 4S jjjrSS jr    SS jr      SS jrS r	SSS jjr
\      SS	 j5       rS
 rSS jrSS jr      SS jrSS jrS S jrS!S jrS"S jrS"S jrS#S jrSrU =r$ )$ro  i  z^
parser to work with a single <part> tag.

called out for multiprocessing potential in future
c                  > [         TU ]  5         Xl        X l        UbR  UR	                  S5      U l        U R
                  c.  Ub+  [        UR                  R                  5       5      S   U l        OSU l        Ub  UO	[        5       U l
        U R                  R                  U l        [        R                  " 5       U l        U R                  ba  U R                  R                  S5       HB  n[        U5      nU(       d  M  [!        U5      S:  d  M(  [        R"                  " 5       U l          O   SU l        / U l        S U l        SU l        SU l        [.        [0        R2                  " 5       0U l        S /S	-  U l        SU l        SU l        S U l        SU l        S U l         S U l!        SU l"        S U l#        [H        RJ                  U l&        SU l'        S U l(        g )
NrJ  r   r>   zmeasure/attributes/stavesr   TFrK     ))r  r  rq  ri  rq   rh  rR  r#  rS  r  rn  r"  r%   PartrO  rB   rM   	PartStaffatSoundingPitchstaffReferenceListlastTimeSignaturelastMeasureWasShortlastMeasureOffsetNO_STAFF_ASSIGNEDr	   
TrebleClef	lastClefsactiveTuplets	maxStaveslastMeasureNumberlastNumberSuffixmultiMeasureRestsToCaptureactiveMultiMeasureRestSpanneractiveInstrumentfirstMeasureParsedactiveAttributesr   divisionsPerQuarterlastDivisionsrp  lastMeasureParser)rv   rq  ri  rn  mxStaves
stavesTextr*  s         r:   r  PartParser.__init__  s    	& **T*DK{{"v'9"6#9#9#>#>#@A!DDK & 2f8H8J![[66#);;=;;" KK//0KL)(3
:#j/A"5"("2"2"4DK	 M  $ =?;?#( !$ 6GHY4Z:>!!"*.*+'LP*<@"' $"*">">'+$59r<   c                    U R                  5         U R                  5         U R                  U R                  l        / nU R                  R                  S5       HO  n[        U[        R                  5      (       d  U R                  R                  SU5        UR                  U5        MQ     U H  nU R                  R                  U5        M      U R                  R                  5         / nU R                  S:  a  U R                  5       nOaU R                  bT  U R                  R!                  U R                  5        U R                  R"                  R                  U R                  5        U R%                  X5        g)z!
Run the parser on a single part
Tr   r   N)parseXmlScorePartparseMeasuresr  r%   r"  r\  rm   r$   OttavarM  r   r]  r^  r!  separateOutPartStavesrh  addGroupForElementsgroups _fillAndInsertOttavasInPartStaff)rv   completedSpannersrj  
partStavess       r:   r7  PartParser.parse  s     	 &*&:&:# 46$$88>Bb'..11&&q"-$$R(	 ? $B%%b) $ 	'')-/
>>A335J[[$KK++DKK8KK%%dkk2--.?Lr<   c                4   U H  n[        U[        R                  5      (       d  M$  S nU(       a!  U R                  UR	                  5       U5      nOU R
                  nUc  M_  UR                  SU5        UR                  5         UR                  U5        M     g )Nr   )	rm   r$   r2  _findFirstPartStaffContaininggetFirstr%   rM  r^  fill)rv   spannersr8  rj  spannerParts        r:   r6  +PartParser._fillAndInsertOttavasInPartStaff  sz     Bb'..11,0K"@@PZ["kk&&&q"-//1$ r<   c                H    Uc  g U H  nUR                  USS9c  M  Us  $    g )NFsetActiveSite)containerInHierarchy)rv   objr8  	partStaffs       r:   r;  (PartParser._findFirstPartStaffContaining  s7    
 ;#I--c-GS   $
 r<   c                @   U R                   nU R                  n[        nU" XS[        S9  UR	                  S5      nUb(  UR                  S5      nUS:X  a  SUR                  l        U" XS[        S9  UR	                  S5      nUb(  UR                  S5      nUS:X  a  SUR                  l        U R                  5       nUR                  5       b  UR                  5       Ul        Xpl        UR                  Ul        UR                  Ul        UR                  SU5        g)	a  
The <score-part> tag contains a lot of information about the
Part itself.  It was found in the <part-list> in the ScoreParser but
was not parsed and instead passed into the PartParser as .mxScorePart.

Sets the stream.partName, stream.partAbbreviation, self.activeInstrument,
and inserts an instrument at the beginning of the stream.

The instrumentObj being configured comes from self.getDefaultInstrument.
z	part-namerR   Nr   r   Fzpart-abbreviationrK  )r%   ri  r^   r;   rV   rq   r&   printPartNameprintPartAbbreviationgetDefaultInstrumentbestNamerJ  r&  partNamepartAbbreviationrM  )rv   rI  ri  r   
mxPartNameprintObjectmxPartAbbreviationinstrumentObjs           r:   r0  PartParser.parseXmlScorePart*  s    {{&&' 	Tv> %%k2
!$..8Kd"+0

(
 	T 3vF(--.AB),00@Kd"38

0 113!!#/#,,.DG -%.. - > >]+r<   c                `   Uc  U R                   nUc  [        S5      eS n[        nUR                  S5      nSnUb  UR                  S5      nUR                  S5      n[	        U5      =n(       a#  [        5       n	 U	R                  U" U5      5      nO7[	        U5      =n(       a%   [        R                  " U" U5      5      nU" XTSUS9  Uc  [        R                   " 5       nUR                  S	5      nUbk  [#        U[        R                  5      (       dL  U R%                  X]5      nUR&                  UR&                  :X  d  [#        U[        R(                  5      (       a  UnU R*                  Ul        U R*                  b%  UR,                  R/                  U R*                  5        U R0                  R2                  Ul        U R0                  R4                  Ul        Ub!  U" X]S
[6        S9  U" X]S[6        S9  U" X]S5        U$ ! [         aL  n
[        R                  " [        U
5      5        [        R                  " 5       nU" U5      Ul         Sn
A
GNSn
A
ff = f! [        R                   a?  n[        R                  " [        U5      5        [        R                   " 5       n SnAGNSnAff = f)a&  
Get a default instrument from the mxScorePart tag.

>>> scorePart = ('<score-part id="P4"><part-name>Bass</part-name>'
...     + '<part-abbreviation>B.</part-abbreviation>'
...     + '<score-instrument id="P4-I4">'
...     + '    <instrument-name>Instrument 4</instrument-name>'
...     + '</score-instrument>'
...     + '<midi-instrument id="P4-I4">'
...     + '   <midi-channel>4</midi-channel>'
...     + '<midi-program>1</midi-program>'
...     + '</midi-instrument>'
...     + '</score-part>')
>>> from xml.etree.ElementTree import fromstring as EL
>>> pp = musicxml.xmlToM21.PartParser()

>>> mxScorePart = EL(scorePart)
>>> i = pp.getDefaultInstrument(mxScorePart)
>>> i
<music21.instrument.Instrument ': Instrument 4'>
>>> i.instrumentName
'Instrument 4'

Non-default transpositions captured as of v7.3:

>>> scorePart = ('<score-part id="P5"><part-name>C Trumpet</part-name>'
...     + '<part-abbreviation>C Tpt.</part-abbreviation>'
...     + '<score-instrument id="P5-I5">'
...     + '    <instrument-name>C Trumpet</instrument-name>'
...     + '</score-instrument>'
...     + '<midi-instrument id="P5-I5">'
...     + '   <midi-channel>2</midi-channel>'
...     + '<midi-program>57</midi-program>'
...     + '</midi-instrument>'
...     + '</score-part>')
>>> from xml.etree.ElementTree import fromstring as EL
>>> pp = musicxml.xmlToM21.PartParser()

>>> mxScorePart = EL(scorePart)
>>> i = pp.getDefaultInstrument(mxScorePart)
>>> i
<music21.instrument.Trumpet ': C Trumpet'>
>>> i.instrumentName
'C Trumpet'
>>> i.transposition
<music21.interval.Interval P1>
Nz/score-part must be defined before calling this.c                2    [        U 5      S-
  nUS:X  a  SnU$ )Nr   r   )rM   )mcadjusteds     r:   _adjustMidiData8PartParser.getDefaultInstrument.<locals>._adjustMidiData  s     2w{H2~Or<   zmidi-instrumentzmidi-programzmidi-unpitchedzmidi-channelrR   zscore-instrumentinstrument-namezinstrument-abbreviationzinstrument-sound)ri  r.   r^   rV   rB   r   midiPitchToInstrumentr   warningswarnr/   r   UnpitchedPercussionpercMapPitchinstrumentFromMidiProgramInstrumentException
Instrumentrm   reclassifyInstrumentFromNamemidiProgramPianorh  r5  r   r%   rM  rN  r;   )rv   ri  rY  r   mxMIDIInstrumentimxMidiProgrammxMidiUnpitchedmidiUnpitchedTextpmmpemidiProgramTextiemxScoreInstrumentinst_from_names                  r:   rK  PartParser.getDefaultInstrument\  sZ   b **K)A 	 ( '++,=>(,',11.AM.334DEO$0$AA A%'H00AR1STA %1$???0"<<__=]^A
 Q.OT9%%'A (,,-?@(Az?]?]1^1^!>>qTN ))Q]]:jJL\L\>]>]";;;;"HHOODKK([[))
![[99 ('8FK'@FS'9:
 Y / HMM/#"67"668A%45F%GANN	H "55 0MM/""56"--/A0s1   <H 'I 
IAIIJ-.4J((J-c                    UR                  S5      n[        U5      =n(       a)  U R                  n [        R                  " U5      n X@l        U $ ! [        R
                   a    [        R                  " 5       n  N3f = f)Nr[  )rV   rB   midiChannelr   
fromStringrb  rc  )rh  rp  mxInstrumentNameinstrumentNameTextprevious_midi_channels        r:   rd  'PartParser.reclassifyInstrumentFromName  sy    
 -112CD!-.>!???$%MM!,))*<= 2M 11 ,))+,s   A )A;:A;c                    U R                   nU R                  R                  S5       H  nU R                  U5        M     U R	                  5         UR                  5         g)z9
Parse each <measure> tag using self.xmlMeasureToMeasure
measureN)r%   rq  iterfindxmlMeasureToMeasure&removeFinaleIncorrectEndingForwardRestr^  )rv   rI  	mxMeasures      r:   r1  PartParser.parseMeasures  sN     {{--i8I$$Y/ 9 	335  "r<   c                $   U R                   nUc  gSU l         UR                  c  gUR                  (       a  gUR                  nUR                  [        R
                     R                  5       UL a  Ub  UR                  R                  USS9  ggg)a  
If Finale generated the file AND it ended with an incomplete
measure (like 4/4 beginning with a quarter pickup and ending
with a 3-beat measure) then the file might have ended with a
`<forward>` tag, which Finale used to create hidden rests.

If this forward tag is at the end of the piece, then it
will create rests that "complete" the measure in an incorrect way
If voices are not involved (e.g., NOT bwv66.6) then we should
remove this forward tag.

* New in v7.
NT)recurse)r+  lastForwardTagCreatedByFinale	useVoicesr%   r    GeneralNotelastr]  )rv   lmpendingForwardRests      r:   r~  1PartParser.removeFinaleIncorrectEndingForwardRest  s     $$;!%,,4==,/,M,MJJt''(--/3DD%1JJ/> 2 Er<   c                  ^^ / SQm[        S/5      nU R                  5       n/ n[        5       m      SUU4S jjnU R                  R	                  [        R
                  5      n[        U5       GH{  u  pgTSS nUS:w  a  UR                  S5        U R                  R                  USUS9n	U R                   S	U 3n
Xl
        U	R                  U
SS
9  U	R                  R                  U
5        UR                  U	5        XR                  R                  U
'   [        5       nU R                   H8  nU R!                  UU5      nU H  nUR#                  [        U5      5        M     M:     [%        UU	R	                  [        R
                  5      5       HT  u  nnU" UUU5        [%        UR&                  UR&                  5       H  u  nnU" UUU5        M     UR)                  SSS9  MV     GM~     U R                  R                  n[*        R,                  " X0R                  R.                  SS9nSUR0                  l        UR5                  SU5        U H  nUR5                  SU5        M     UR7                  5         SU l        U$ )z
Take a `Part` with multiple staves and make them a set of `PartStaff` objects.

There must be more than one staff to do this.
)ClefDynamic
Expressionr  KeySignaturer   TempoIndicationTimeSignatureRepeatBracketc                `  > U R                  T5      nSUl        U H  n[        U5      nXR;   a  M  UT	;   a  [        R                  " U5      nOUnT	R                  U5        U R                  USS9nUS:w  a  UR                  Xv5        Mn  UR                  U5        M     UR                  5         g )NFT)returnSpecialhighestTime)
getElementsByClassrestoreActiveSitesrJ  copydeepcopyr`   elementOffsetrM  coreStoreAtEndr^  )
sourcetargetomitTheseElementIdselementIterator
sourceElemidSource
targetElemsourceOffsetSTAFF_SPECIFIC_CLASSESappendedElementIdss
           r:   copy_into_partStaff=PartParser.separateOutPartStaves.<locals>.copy_into_partStaff0  s     %778NOO16O.-
j>211!%z!:J!+J&**84%33Jd3S=0%%l?))*5 . &&(r<   Nr   SpannerF)removeClassesfillWithRestsexemptFromRemover  rB  T)forceinPlacer  )r  r  )r  stream.Streamr  r  r  zset[int]r  r  )	frozenset_getUniqueStaffKeyssetr%   r  Measure	enumerater   templaterh  rJ  r4  r5  rn  r$  r  _getStaffExcluder`   rp   voicesflattenUnnecessaryVoicesr   r  rM  r&   r   rM  r^  rp  )rv   EXEMPT_FROM_REMOVEuniqueStaffKeysr8  r  sourceMeasureIterator
staffIndexstaffKeyr  newPartStaffpartStaffIdelementsIdsNotToGoInThisStaffstaffReferenceexcludeOneMeasurer  sourceMeasurecopyMeasuresourceVoice	copyVoicescorer  rF  r  r  s                         @@r:   r3   PartParser.separateOutPartStaves  s~   	"
 '
 &*%=%=%?-/
'*u	)(5	)5=	)BF	) 	)* !% > >v~~ N$-o$> J215MQ$$Y/;;//m>CAS 0 UL "[[Mz:K)O,,[,N&&{3l+:FKK**;769e) #'"9"9 %)$9$9"%! ,B155bf= , #: /2%//?/*{ $M;@]^.1-2F2FHZHZ.[*K'Y@]^ /\445$4O/9 %?J ""&&z8L8LU\]
-1
*J'#IQ	* $!!#',$ r<   c                h    U[         :X  a  / $ / nU H  nU[         :X  a  M  XB:X  a  M  X1U   -  nM     U$ )a  
Given a staff reference dictionary (for a single measure),
remove and combine in a list all elements that
are NOT part of the given targetKey. Thus, return a list of all entries to remove.
It keeps those elements under the staff key None (common to all) and
those under given key. This then is the list of all elements that should be deleted.

If targetKey is NO_STAFF_ASSIGNED (0) then returns an empty list
)r  )rv   r  	targetKeypostks        r:   r  PartParser._getStaffExcludez  sI     ))IA%%1%%D   r<   c                    / nU R                    H0  nU H'  nU[        :w  d  M  X1;  d  M  UR                  U5        M)     M2     UR                  5         U$ )zx
Given a list of staffReference dictionaries,
collect and return a list of all unique keys except NO_STAFF_ASSIGNED (0)
)r  r  r   r_  )rv   r  r  r  s       r:   r  PartParser._getUniqueStaffKeys  sK    
 "55N#))amKKN $ 6 			r<   c                *   [        XS9n UR                  5         X l        [        U R                  UR                  5      U l        UR                  b  U R!                  UR                  5        SU l        U R$                  R'                  UR(                  5        UR
                  nU R+                  U5        UR,                  SL a  U[.        R0                     R3                  5       n[4        R6                  (       a  Uc   eU R8                  b!  U R8                  R:                  R<                  nOSnUR>                  SL di  UR@                  R<                  U:w  af  UR@                  RB                  S	;   aL  UR@                  RD                  S
:X  a2  UR@                  RF                  (       d  XeR@                  l        SUl        U R
                  RI                  U RJ                  U5        U RM                  U5        U$ ! [         a<  n[        UR                  5      Ul        U R
                  R                  Ul        UeSnAf[         aK  n[        R                  " SUR                   S3SU R
                  R                   S3-   [        5        UeSnAff = f)as  
Convert a measure element to a Measure, using
:class:`~music21.musicxml.xmlToM21.MeasureParser`

>>> from xml.etree.ElementTree import fromstring as EL

Full-measure rests get auto-assigned to match the time signature if they
do not have a type, or have a type of "whole".

Here is a measure with a rest that lasts 4 beats, but we will put it in a 3/4 context.

>>> scoreMeasure = '<measure><note><rest/><duration>40320</duration></note></measure>'
>>> mxMeasure = EL(scoreMeasure)
>>> pp = musicxml.xmlToM21.PartParser()
>>> pp.lastDivisions
10080
>>> 40320 / 10080
4.0
>>> pp.lastTimeSignature = meter.TimeSignature('3/4')
>>> m = pp.xmlMeasureToMeasure(mxMeasure)

Test that the rest lasts three, not four beats:

>>> measureRest = m.notesAndRests[0]
>>> measureRest
<music21.note.Rest dotted-half>
>>> measureRest.duration.type
'half'
>>> measureRest.duration.quarterLength
3.0
)rn  Nz)The following exception took place in m.  in zpart .T      @wholebrever   )'MeasureParserr7  r.   r  measureNumberr%   rM  	Exceptionr]  r^  r/   r+  maxr!  stavestranspositionupdateTranspositionr'  r  r   r  setLastMeasureInfofullMeasureRestr    RestfirsttTYPE_CHECKINGr  barDurationquarterLengthfullMeasurer   ru  dotstupletsinsertr  adjustTimeAttributesFromMeasure)rv   r  measureParseremr1lastTSQls          r:   r}  PartParser.xmlMeasureToMeasure  s   B &i=	! "/T^^]-A-AB&&2$$]%@%@A"&&&}'C'CD  " ((D0499##%B~%~%%111==KK$&KK--9((,>>((A-KK//,4)!% 	41115,,Q/ k ' 	!-"="=>AO--AJG 	MM;M<W<W;XX\]$++../q12
 G	s$   G9 9
J7H::JAJJc                    U R                   b  U R                   R                  c  U R                  SL a  OU R                   R                  U:w  aL  [        R                  " U R                   5      nX l         U R
                  R                  U R                  U5        O\[        R                  " S[        5        [        R                  " 5       nX0l         U R
                  R                  U R                  U5        XR                   l        SU l        g)as  
As one might expect, a measureParser that reveals a change
in transposition is going to have an effect on the
Part's instrument list.  This (totally undocumented) method
deals with it.

If `measureParser.transposition` is None, does nothing.

NOTE: Need to test a change of instrument w/o a change of
transposition such as: Bb clarinet to Bb Soprano Sax to Eb clarinet?
NFz=Received a transposition tag, but no instrument to put it on!)r&  r  r'  r  r  r%   rM  r  r]  r^  r/   r   rc  r  )rv   newTranspositionnewInstfakeInsts       r:   r  PartParser.updateTransposition  s       ,%%33;//58 &&448HH
 --(=(=>(/%&&t'='=wG
 MMO! ",,.H$,!KK""4#9#98D
 /?+$r<   c                   UR                   U R                  :X  a  O"UR                   U l        UR                  U l        UR                  b  UR                  U l        gU R
                  c  [        R                  " S5      nX l        gg)a  
Sets self.lastMeasureNumber and self.lastMeasureSuffix from the measure,
which is used in fixing Finale unnumbered measure issues.

Also sets self.lastTimeSignature from the timeSignature found in
the measure, if any.

>>> pp = musicxml.xmlToM21.PartParser()

Here are the defaults:

>>> pp.lastMeasureNumber
0
>>> pp.lastNumberSuffix is None
True
>>> pp.lastTimeSignature is None
True

After setLastMeasureInfo:

>>> m = stream.Measure(number=4)
>>> m.numberSuffix = 'b'
>>> ts38 = meter.TimeSignature('3/8')
>>> m.timeSignature = ts38
>>> pp.setLastMeasureInfo(m)

>>> pp.lastMeasureNumber
4
>>> pp.lastNumberSuffix
'b'
>>> pp.lastTimeSignature
<music21.meter.TimeSignature 3/8>
>>> pp.lastTimeSignature is ts38
True

Note that if there was no timeSignature defined in m,
and no lastTimeSignature exists,
the PartParser gets a default of 4/4, because
after the first measure there's going to be routines
that need some sort of time signature:

>>> pp2 = musicxml.xmlToM21.PartParser()
>>> m2 = stream.Measure(number=2)
>>> pp2.setLastMeasureInfo(m2)
>>> pp2.lastTimeSignature
<music21.meter.TimeSignature 4/4>


For obscure reasons relating to how Finale gives suffixes
to unnumbered measures, if a measure has the same number
as the lastMeasureNumber, the lastNumberSuffix is not updated:

>>> pp3 = musicxml.xmlToM21.PartParser()
>>> pp3.lastMeasureNumber = 10
>>> pp3.lastNumberSuffix = 'X1'

>>> m10 = stream.Measure(number=10)
>>> m10.numberSuffix = 'X2'
>>> pp3.setLastMeasureInfo(m10)
>>> pp3.lastNumberSuffix
'X1'
Nz4/4)r   r"  numberSuffixr#  timeSignaturer  r   r  )rv   r  tss      r:   r  PartParser.setLastMeasureInfo.  sq    @ 88t--- &'XXD"$%NND!??&%&__D"##+$$U+B%'" ,r<   c                :   UR                   nU R                  b!  U R                  R                  R                  nOSnX#:X  a  UnGOX#:  a  X#-
  nSnUS:  d&  [	        US5      S   U:  d  [	        US5      S   U:  a  UnGOUn[
        R                  " SUR                   S	U R                  R                   S
U SU SU S3[        5        GO9US:X  ao  UR                  5       R                  R                  S5      (       dA  [        R                  " 5       nX7R                   l        UR#                  SU5        UnSU l        OU R&                  S:X  a'  UR)                  5       S:  a  UR+                  5         UnOUnU R$                  SL a,  UR)                  5       S:  a  UR+                  5         SU l        OPUR)                  5       S:  a(  UR                  R                  UR                   -
  Ul        X#:  a  SU l        OSU l        U =R&                  U-  sl        g)a3  
Adds padAsAnacrusis to pickup measures and other measures that
do not fill the whole tile, if the first measure of the piece, or
immediately follows an incomplete measure (such as a repeat sign mid-measure
in a piece where each phrase begins with a pickup and ends with an
incomplete measure).

Fills an empty measure with a measure of rest (bug in PDFtoMusic and
other MusicXML writers).

Sets self.lastMeasureWasShort to True or False if it is an incomplete measure
that is not a pickup and sets paddingRight.

>>> m = stream.Measure([meter.TimeSignature('4/4'), harmony.ChordSymbol('C7')])
>>> m.highestTime
0.0
>>> pp = musicxml.xmlToM21.PartParser()
>>> pp.setLastMeasureInfo(m)
>>> pp.adjustTimeAttributesFromMeasure(m)
>>> m.highestTime
4.0
>>> pp.lastMeasureWasShort
False

Incomplete final measure:

>>> m = stream.Measure([meter.TimeSignature('6/8'), note.Note(), note.Note()])
>>> m.offset = 24.0
>>> pp = musicxml.xmlToM21.PartParser()
>>> pp.lastMeasureOffset = 21.0
>>> pp.setLastMeasureInfo(m)
>>> pp.adjustTimeAttributesFromMeasure(m)
>>> m.paddingRight
1.0
Nr  gư>g      ?g      ?r   gUUUUUU?zWarning: measure z	 in part zis overfull: z > z
,assuming z is correct.rK  HarmonyFg      ?T)r  r  r  r  r   r]  r^  r   r%   rM  r/   r  notesAndRestsgetElementsNotOfClassr    r  r   r  r  r  barDurationProportionpadAsAnacrusispaddingRight)rv   r  mHighestTimelastTimeSignatureQuarterLengthmOffsetShiftdifftolrs           r:   r  *PartParser.adjustTimeAttributesFromMeasure  s   T }}
 !!--1-C-C-O-O-]-]*-0*9'L:@DC s
$T6215;$T6215;+='z4;;;O;O:P#L>5S4T U  ,~\; $	 c!iik//EEiPP
 		A'EJJ$HHS!9L',D$
 %%,**,s2$$&  ,+++t3..036((*380 ..036)*)D)Dq}})T#D370380,.r<   c                    U R                   c  gU R                   R                  U5        U =R                  S-  sl        U R                  S:X  a.  U R                  R	                  SU R                   5        SU l         gg)a  
If there is an active MultiMeasureRestSpanner, add the Rest, r, to it:

>>> pp = musicxml.xmlToM21.PartParser()
>>> mmrSpanner = spanner.MultiMeasureRest()
>>> mmrSpanner
<music21.spanner.MultiMeasureRest 0 measures>

>>> pp.activeMultiMeasureRestSpanner = mmrSpanner
>>> pp.multiMeasureRestsToCapture = 2
>>> r1 = note.Rest(type='whole', id='r1')
>>> pp.applyMultiMeasureRest(r1)
>>> pp.multiMeasureRestsToCapture
1
>>> pp.activeMultiMeasureRestSpanner
<music21.spanner.MultiMeasureRest 1 measure>

>>> pp.activeMultiMeasureRestSpanner is mmrSpanner
True
>>> pp.stream.show('text')  # Nothing shown!

>>> r2 = note.Rest(type='whole', id='r2')
>>> pp.applyMultiMeasureRest(r2)
>>> pp.multiMeasureRestsToCapture
0
>>> pp.activeMultiMeasureRestSpanner is None
True

# spanner added to stream

>>> pp.stream.show('text')
{0.0} <music21.spanner.MultiMeasureRest 2 measures>

>>> r3 = note.Rest(type='whole', id='r3')
>>> pp.applyMultiMeasureRest(r3)
>>> pp.stream.show('text')
{0.0} <music21.spanner.MultiMeasureRest 2 measures>

Nr   r   )r%  r  r$  r%   r  )rv   r  s     r:   applyMultiMeasureRest PartParser.applyMultiMeasureRest  sn    P --5**==a@''1,'**a/KKq$"D"DE15D. 0r<   )r(  r&  r%  r   rp  r  r'  r  r*  r"  r  r+  r  r#  r  r!  r$  rq  ri  rn  rh  r"  r  r%   )NNN)rq  ET.Element | Noneri  r
  rn  zMusicXMLImporter | None)r  r  )r>  zlist[spanner.Spanner]r8  list[stream.PartStaff])rE  zbase.Music21Object | Noner8  r  r  zstream.PartStaff | Nonerh   )ri  r
  r  instrument.Instrument)rh  r  rp  r
  r  r  )r  r  )r  StaffReferenceTyper  rM   r  zlist[base.Music21Object])r  z	list[int])r  r
  r  stream.Measure)r  zinterval.Interval)r  r  )r  z	note.Rest)r  r  r	  r
  r  r  r7  r6  r;  r0  rK  r  rd  r1  r~  r3  r  r  r}  r  r  r  r  r  r  r  s   @r:   ro  ro    s    ,004154:(4:-4: /4: 4:l"MH%'% +%,$ + 
	.,dB  % 
 	#?:dL*  
"	4Zx/%bO(bm/^.6 .6r<   ro  c                    ^  \ rS rSrSrSSSSSS.rS	S
SSSSSSSSSSS.r  SY   SZU 4S jjjr\S[S j5       r	S r
S rS rS\S jrS\S jrS]S jrS^S jrS_S jrS`SaS jjrSbScS jjrSbS jrS  rSbS! jr Sb     SdS" jjr Sb     SeS# jjrS$ rS`S% jrSbS& jrS' rSfS( jrS) rS* r\S+ 5       r S, r!S- r"SS.. SgS/ jjr#  SY     ShS0 jjr$S1 r%S2 r&S3S4.S5 jr'S6 r(SiS7 jr)S8 r*SbSjS9 jjr+S: r, Sb   SkS; jjr-S< r.SbS= jr/SbS> jr0S? r1    SlS@ jr2SA r3        SmSB jr4          SnSC jr5SD r6SE r7SbSF jr8SG r9SH r:SI r;SJ r<SK r=    SoSL jr>SM r?SN r@SO rASP rBSQ rCSR rDSS rE Sb   SpST jjrFSU rGSbSV jrHSW rISXrJU =rK$ )qr  i 	  a  
parser to work with a single <measure> tag.

called out for simplicity.

>>> from xml.etree.ElementTree import fromstring as EL

>>> scoreMeasure = '<measure><note><rest/><duration>40320</duration></note></measure>'
>>> mxMeasure = EL(scoreMeasure)
>>> mp = musicxml.xmlToM21.MeasureParser(mxMeasure)
>>> mp.parse()
>>> mp.restAndNoteCount['rest']
1
>>> mp.restAndNoteCount['note']
0

fullMeasureRest indicates that a rest lasts the full measure of the current time signature.

>>> mp.fullMeasureRest
True
handleTimeSignature
handleClefhandleKeySignaturehandleStaffDetailshandleMeasureStyle)timer	   r   staff-detailsmeasure-style	xmlToNote	xmlBackup
xmlForwardxmlDirectionparseAttributesTag
xmlHarmonyNxmlSound
xmlBarline)r    backupforwardr   
attributesr   zfigured-basssoundbarlinegroupinglinkbookmarkc                  > [         TU ]  5         Xl        / U l        Ub  UO	[	        5       U l        S U l        U R
                  R                  U l        0 U l        U R
                  R                  U l	        SU l
        0 U l        [        5       U l        SU l        S U l        SU l        SU l        SU l        U R
                  R&                  U l        0 U l        [,        R.                  " 5       U l        / U l        / U l        S U l        S U l        SU l        SSS.U l        U R
                  R<                  U l        SU l        SU l         S U l!        [D        RF                  " 5       U l$        g )NFr   Tr   r>   )restr    rK  )%r  r  r  mxMeasureElementsro  rn  r  r"  r  r   r  
voicesByIdr  voiceIndicesr  r(  attributesAreInternalr  r  r*  	divisionsr   r%   r  
mxNoteListmxLyricListnLast	lastVoicer  restAndNoteCountr  
parseIndexr   r  weakrefWeakKeyDictionarypedalToStartOffset)rv   r  rn  r*  s      r:   r  MeasureParser.__init__M	  sD    	"35,2,>&JL!![[66249=9R9R$79*-% $%)"22
 UWnn&,.-/,0
 (,
  % *+A 648KK4I4I ,/ >B* >E=V=V=Xr<   c                P   [        U [        5      (       a  U $ [        U [        5      (       a  [        U 5      $ U c  [        $ U nUR                  S;   aB   UR                  S5      nUb&   UR                  R                  5       n[        U5      $  [        $ UR                  S;   a   UR                  S5      n[        U5      $ [        $ ! [         a	    [        s $ [         a     [        $ f = f! [         a     [        $ f = f! [         a     [        $ [         a     [        $ f = f)a  
gets an int representing a staff number, or 0 (representing no staff assigned)
from an mxObject or a number:

>>> mp = musicxml.xmlToM21.MeasureParser()
>>> from xml.etree.ElementTree import fromstring as EL

>>> gsn = mp.getStaffNumber
>>> gsn(1)
1
>>> gsn('2')
2

<note> tags store their staff numbers in a <staff> tag's text:

>>> gsn(EL('<note><staff>2</staff></note>'))
2

Or if there is no <staff> tag, they get a special NO_STAFF_ASSIGNED value.

>>> el = EL('<note><pitch><step>C</step><octave>4</octave></pitch></note>')
>>> gsn(el) == musicxml.xmlToM21.NO_STAFF_ASSIGNED
True

Clefs, however, store their staff numbers in a `number` attribute.

>>> gsn(EL('<clef number="2"/>'))
2
>>> gsn(None) == musicxml.xmlToM21.NO_STAFF_ASSIGNED
True
)r   r!  r    r   staff)r  r  r  r	   r   r  	transposer   )rm   rM   r  r  r[   rV   r)   r6   ru   r?   rq   )mxObjectOrNumberrw   staffObjectr  s       r:   getStaffNumberMeasureParser.getStaffNumber	  s?   B &,,##(#..'((%$$# <<FF&mmG4*',,224"1v + %$\\ + +LL*1v %$3 % 100)  %$	! $$   %$ " $$sT   C. )$C &D C+C. 	C+#C. *C++C. .
D ?D 
D%	D%$D%c                v    U R                   nU R                  U5      nXC;  a  / X4'   X4   R                  U5        g)a  
Utility routine for importing musicXML objects;
here, we store a reference to the music21 object in a dictionary,
where keys are the staff values. Staff values may be None, 1, 2, etc.

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.addToStaffReference(1, note.Note('C5'))
>>> MP.addToStaffReference(2, note.Note('D3'))
>>> MP.addToStaffReference(2, note.Note('E3'))
>>> len(MP.staffReference)
2
>>> list(sorted(MP.staffReference.keys()))
[1, 2]
>>> MP.staffReference[1]
[<music21.note.Note C>]
>>> MP.staffReference[2]
[<music21.note.Note D>, <music21.note.Note E>]

>>> from xml.etree.ElementTree import fromstring as EL
>>> mxNote = EL('<note><staff>1</staff></note>')
>>> MP.addToStaffReference(mxNote, note.Note('F5'))
>>> MP.staffReference[1]
[<music21.note.Note C>, <music21.note.Note F>]

No staff reference.

>>> mxNote = EL('<note />')
>>> MP.addToStaffReference(mxNote, note.Note('G4'))
>>> len(MP.staffReference)
3
>>> MP.staffReference[0]
[<music21.note.Note G>]
N)r  r>  r   )rv   r<  rx   r  r  s        r:   addToStaffReference!MeasureParser.addToStaffReference	  s@    D ,,&&'78)')N$ ''	2r<   c                \    U R                  X#5        U R                  R                  X5        g)a  
runs addToStaffReference and then insertCore.

>>> from xml.etree.ElementTree import fromstring as EL
>>> mxNote = EL('<note><staff>1</staff></note>')

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.insertCoreAndRef(1.0, mxNote, note.Note('F5'))

This routine leaves MP.stream in an unusable state, because
it runs insertCore.  Thus, before querying the stream we need to run at end:

>>> MP.stream.coreElementsChanged()
>>> MP.stream.show('text')
{1.0} <music21.note.Note F>
N)rA  r%   rM  )rv   offsetr<  rx   s       r:   insertCoreAndRefMeasureParser.insertCoreAndRef
  s%    " 	  !1=v1r<   c                   U R                   R                  S5       H  nU R                  U5        M     U R                  5         U R	                  5         [        U R                   5      U l        [        U R                  5       HX  u  p#X l        UR                  U R                  ;   d  M'  U R                  UR                     nUc  ME  [        X5      nU" U5        MZ     U R                  (       aD  U R                  R                  5       R                   H  nU(       d  M  UR!                  5         M     U R                  R!                  5         U R"                  S   S:X  a  U R"                  S   S:X  a  SU l        g g g )Nprintr)  r   r    r   T)r  rO  xmlPrintparseMeasureAttributesupdateVoiceInformationrR  r*  r  r4  r[   musicDataMethodsgetattrr  r%   iterr  r^  r3  r  )rv   r   rh  r@   methNamemethvs          r:   r7  MeasureParser.parse%
  s0    ~~--g6GMM'" 7 	##%##%!%dnn!5!$"8"89HAOyyD11100;'"42DK : >>[[%%'..1 ))+	 /
 	'')!!&)Q.))&1Q6#'D  7 /r<   c                    UR                  S5      n[        U5      =n(       aR  [        [        U5      U R                  -  5      nU =R
                  U-  sl        [        U R
                  S5      U l        gg)a  
Parse a backup tag by changing :attr:`offsetMeasureNote`.

A floor of 0.0 is enforced in case of float rounding issues.

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.divisions = 100
>>> MP.offsetMeasureNote = 1.9979

>>> from xml.etree.ElementTree import fromstring as EL
>>> mxBackup = EL('<backup><duration>100</duration></backup>')
>>> MP.xmlBackup(mxBackup)
>>> MP.offsetMeasureNote
0.9979

>>> MP.xmlBackup(mxBackup)
>>> MP.offsetMeasureNote
0.0
r   rK  N)rV   rB   r   rL   r.  r   r  )rv   r@   
mxDurationdurationTextchanges        r:   r  MeasureParser.xmlBackupE
  sg    ( ZZ
+
'
33<3E,/$..@AF""f," &))?)?%ED" 4r<   c                   UR                  S5      n[        U5      =n(       a  [        [        U5      U R                  -  5      nU R
                  (       a  U R
                  R
                  (       ar  U R
                  R
                  R                  (       aM  [        R                  " US9nSUR                  l
        U R                  X5        U R                  X5        XPl        U =R                  U-  sl        gg)z<
Parse a forward tag by changing :attr:`offsetMeasureNote`.
r   r  TN)rV   rB   r   rL   r.  rn  r)  r    r  r&   r   rA  insertInMeasureOrVoicer  r   )rv   r@   rT  rU  rV  r  s         r:   r  MeasureParser.xmlForwardb
  s     ZZ
+
'
33<3E,/$..@AF****AA IIF3,0)((2++E5 672 ""f,"' 4r<   c                V  ^ U4S jnU4S jnU" 5       nU" 5       nTR                  S5      SLnU R                  nUSL a#  U R                  T5      nUR                  SU5        USL d  USL a#  U R	                  T5      n	UR                  SU	5        USL a  U R
                  n
TR                  S5       Vs/ s H
  o" U5      PM     nnU H;  nUb  UR                  c  M  U R                  S[        UR                  5      U5        M=     U R                  R                  5         TR                  S5      nUbo  [        R                  " [        R                  UR                  5      nUR                  Ul        [        R"                  " 5       nU R%                  UU5        UUl        ggs  snf )	z
<print> handles changes in pages, numbering, layout,
etc. so can generate PageLayout, SystemLayout, or StaffLayout
objects.

Should also be able to set measure attributes on `self.stream`
c                 ~   > T R                  S5      S;  a  gT R                  S5      b  gT R                  S5      b  gg)Nr   Nr   Tr   r   Frq   rV   r   s   r:   hasPageLayout-MeasureParser.xmlPrint.<locals>.hasPageLayout
  s>    {{:&l:{{=)5||M*6r<   c                 X   > T R                  S5      S;  a  gT R                  S5      b  gg)Nr   r^  Tr   Fr_  r`  s   r:   hasSystemLayout/MeasureParser.xmlPrint.<locals>.hasSystemLayout
  s,    {{<(<||O,8r<   r  NTrK  Fzmeasure-numbering)rV   r%   r   r  r   r  r|  r   rE  r  r^  r  castr&   StreamStyler)   measureNumberingr  r   measureNumberStyle)rv   r   ra  rd  addPageLayoutaddSystemLayoutaddStaffLayoutr  plslslFuncmxstlListstlmxMeasureNumberingm_styler  s    `               r:   rI  MeasureParser.xmlPrint|
  s   		 &)+%ll>:dB KKD **73BHHS"d"mu&<,,W5BHHS"T!55F,3,<,<^,LM,Lbvbz,LGM ;#//"9%%c3s+?E  KK++-$\\*=>) ffU..8G'9'>'>G$"B##$6;)+G& * Ns   4F&c                F    U R                   U R                  S-      nUR                  S:X  a  UR                  S5      b  SnOSn SnSnSnUR                  S5      b  SnUR                  S5      b  SnU(       aI  SnUR                  S	5      nUb3  UR
                  n[        U[        5      (       a   [        U5      nXl
        USL aQ  Sn	U R                  R                  U5        UR                  S
5       H  n
U R                  R                  U
5        M      O[USL a.  USL a)  U R                  S==   S-  ss'   U R!                  U5      n	O(U R                  S==   S-  ss'   U R#                  U5      n	USL a  [$        R&                  (       a!  [        U	[(        R*                  5      (       d   eU R-                  XR                  S
5      5        U R/                  X5        U R1                  X5        U	R2                  R4                  nXl        U R                  (       a  USL a  U R9                  U R                  5      nU R-                  XR                  5        U R/                  U R                  S   U5        U R                   H(  nUR                  S	5      c  M  U R1                  X5          O   U R1                  X5        / U l        / U l        UR4                  nXl        U =R:                  U-  sl        SU l        g! [         a    Sn GNf = f! [         a     GNaf = f)a  
Handles everything for creating a Note or Rest or Chord

Does not actually return the note, but sets self.nLast to the note.

This routine uses coreInserts for speed, so it can leave either
`self.stream` or a `Voice` object within `self.stream` in an unstable state.
r   r    r   NTFrK  r)  voicelyricr   )r*  r4  r[   rV   
IndexErrorr)   rm   r  rM   rN   r2  r/  r   rO  r0  r3  xmlToSimpleNote	xmlToRestr  r  r    r  updateLyricsFromListrA  rZ  r   r  r1  
xmlToChordr   r  )rv   mxNote	mxObjNextnextNoteIsChordisChordisRestoffsetIncrementvoiceOfChordvIndexnmxLyricr   
thisMxNotes                r:   r  MeasureParser.xmlToNote
  s   	$..t/BCI}}&9>>'+B+N"&"'  58;;v*F;;w+G G!;;w/L''3'8'8fc**!$V "(d?AOO""6*!>>'2  ''0 3&E/!!&)Q.)$$V,A!!&)Q.)v&Ae!!T%5%56666%%a)@A$$V/''2jj66OJ
 ??%70A%%a)9)9:$$T__Q%7;"oo
??7+7//
>	 . ++F6 DO!DooOJ 	/1-1*a  	$#O	$: & s*   A K? K? 3L ?LL
L L c                .   / nU H"  nUR                  U R                  USS95        M$     [        S U 5       5      (       a  [        R                  " U5      nO[
        R                  " U5      nU(       a1  US   R                  Ul        [        R                  " 5       US   l        [        5       n[        5       nS n[        X'S9 GH.  nUR                  5       n	U	 H  n
U
R                  X5        M     UR                   H  n[        U5      U;   a  M  UR                  R                  U5        [!        U[        R"                  [        R$                  [        R&                  45      (       a  Mo  UR)                  [        U5      5        M     UR*                   HI  n[        U5      U;   a  M  UR*                  R                  U5        UR)                  [        U5      5        MK     / Ul        / Ul        GM1     U R,                  R/                  U5        U$ )a  
Given a list of mxNotes, fill the necessary parameters

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.divisions = 10080

>>> qnDuration = r'<duration>7560</duration><type>quarter</type>'

>>> a = EL(r'<note><pitch><step>A</step><octave>3</octave></pitch>'
...          + qnDuration + '</note>')
>>> b = EL(r'<note><chord/><pitch><step>B</step><octave>3</octave></pitch>'
...          + qnDuration + '</note>')

>>> c = MP.xmlToChord([a, b])
>>> len(c.pitches)
2
>>> c.pitches[0]
<music21.pitch.Pitch A3>
>>> c.pitches[1]
<music21.pitch.Pitch B3>
>>> c.duration
<music21.duration.Duration unlinked type:quarter quarterLength:0.75>

>>> a = EL('<note><pitch><step>A</step><octave>3</octave></pitch>'
...        + qnDuration
...        + '<notehead>diamond</notehead></note>')
>>> c = MP.xmlToChord([a, b])
>>> c.getNotehead(c.pitches[0])
'diamond'

>>> a = EL('<note><unpitched><display-step>A</display-step>'
...        + '<display-octave>3</display-octave></unpitched>'
...        + qnDuration
...        + '<notehead>diamond</notehead></note>')
>>> MP.xmlToChord([a, b])
<music21.percussion.PercussionChord [unpitched[A3] B3]>
FfreeSpannersc              3  F   #    U  H  oR                  S 5      SLv   M     g7f)	unpitchedN)rV   )ri   r~  s     r:   rk   +MeasureParser.xmlToChord.<locals>.<genexpr>I  s     M*{{;'t3*s   !r   c                    [        U S5      (       a  U R                  R                  $ U R                  5       R                  $ )Nr"   )r   r"   psdisplayPitchmidi)rj   s    r:   <lambda>*MeasureParser.xmlToChord.<locals>.<lambda>[  s-    '!W*=*=AGGJJX1>>CSCXCXXr<   r   )r   rz  anyr!   PercussionChordr   Chordbeamsr   Beamsr  r  getSpannerSitesreplaceSpannedElementr   ru  rm   	FingeringStringIndicationFretIndicationr`   r   r"  #freePendingSpannedElementAssignment)rv   r/  notesr~  r   seenArticulationsseenExpressionssortKeyr  ssrj  artexps                r:   r}  MeasureParser.xmlToChord  s   P  FLL--f5-IJ ! M*MMM**51AE"A AhnnAG!ZZ\E!HN  E%X+A""$B((. 9 11&&s+!#(?(?(5(F(F(5(D(D(F G G &))$s)4 ' }}9/$$S)##DI.	 % !AOAM) ,, 	>>qAr<   c                   U R                  U5      nUR                  S5      nUc0  [        R                  " US9nU R	                  XR
                  5        O%[        R                  " US9nU R                  XE5        UR                  S5      nU(       a  U R                  U5      Ul
        UR                  S5      nUb  UR                  R                  5       Ul        UR                  (       al  [        R                   " 5       nU R#                  Xx5        U R%                  Xx5        [&        R(                  " [        R*                  UR                  5      n	Xl        UR                  S5      n
U
b  U R/                  XZ5        U R1                  XQUS9$ )aC  
Translate a MusicXML <note> (without <chord/>)
to a :class:`~music21.note.Note`.

The `spannerBundle` parameter can be a list or a Stream
for storing and processing Spanner objects.

if freeSpanners is False then pending spanners will not be freed.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> MP.divisions = 10080

>>> mxNote = EL('<note pizzicato="yes"><pitch><step>D</step>'
...             + '<alter>-1</alter><octave>6</octave></pitch>'
...             + '<duration>7560</duration>'
...             + '<type>eighth</type><dot/></note>')

>>> n = MP.xmlToSimpleNote(mxNote)
>>> n
<music21.note.Note D->
>>> n.octave
6
>>> n.duration
<music21.duration.Duration 0.75>
>>> n.articulations
[<music21.articulations.Pizzicato>]


>>> beams = EL('<beam>begin</beam>')
>>> mxNote.append(beams)
>>> n = MP.xmlToSimpleNote(mxNote)
>>> n.beams
<music21.beam.Beams <music21.beam.Beam 1/start>>

>>> stem = EL('<stem>up</stem>')
>>> mxNote.append(stem)
>>> n = MP.xmlToSimpleNote(mxNote)
>>> n.stemDirection
'up'

# TODO: beams over rests?
r  r   r   stemnoteheadr  )xmlToDurationrV   r    Note
xmlToPitchr"   	UnpitchedxmlToUnpitchedrO  
xmlToBeamsr  r)   r6   stemDirectionr  r&   rn   r   r   r  rf  	NoteStyle	stemStylexmlNoteheadxmlNoteToGeneralNoteHelper)rv   r~  r  dmxUnpitchedr  beamListmxStemr  this_note_style
mxNoteheads              r:   rz  MeasureParser.xmlToSimpleNotev  s4   \ v& kk+.		1%AOOFGG,*A/>>&)ooh/AGV$$kk//1AO}}!KKM	f0  3"#&&!''"B,5) [[,
!Q+ ..q|.TTr<   c                   Uc  [         R                  " 5       nOUnU R                  X5        U R                  XSS5        [	        UR
                  [        5      (       a  UR
                  R                  5       nOSnUS:X  a  SUl        OUUS:X  a  SUl        OGUS:X  a  SUl        O9US:X  a  S	Ul        S
Ul	        O$US:X  a  S	Ul        SUl	        O[        SU S35      eUc  U$ g)am  
given an mxBeam object return a :class:`~music21.beam.Beam` object

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxBeam = EL('<beam>begin</beam>')
>>> a = MP.xmlToBeam(mxBeam)
>>> a.type
'start'

>>> mxBeam = EL('<beam>continue</beam>')
>>> a = MP.xmlToBeam(mxBeam)
>>> a.type
'continue'

>>> mxBeam = EL('<beam>end</beam>')
>>> a = MP.xmlToBeam(mxBeam)
>>> a.type
'stop'

>>> mxBeam = EL('<beam>forward hook    </beam>')
>>> a = MP.xmlToBeam(mxBeam)
>>> a.type
'partial'
>>> a.direction
'right'

>>> mxBeam = EL('<beam>backward hook</beam>')
>>> a = MP.xmlToBeam(mxBeam)
>>> a.type
'partial'
>>> a.direction
'left'

>>> mxBeam = EL('<beam>crazy</beam>')
>>> a = MP.xmlToBeam(mxBeam)
Traceback (most recent call last):
music21.musicxml.xmlObjects.MusicXMLImportException:
     unexpected beam type encountered (crazy)
Nfanbeginrv  continueendrw  zforward hookpartialr   zbackward hookr   z"unexpected beam type encountered ())r   Beamr   r   rm   r)   r  r6   ru  r   r.   )rv   mxBeamr   beamOutmxTypes        r:   	xmlToBeamMeasureParser.xmlToBeam  s    V iikGG 	f&>fkk3''[[&&(FFW"GLz!%GLu_!GL~%$GL 'G&$GL &G),NvhVW*XYYN r<   c                    Uc  [         R                  " 5       nOUn[        U5       H;  u  pEU R                  U5      nUS-   Ul        UR
                  R                  U5        M=     Uc  U$ g)a  
given a list of mxBeam objects, sets the beamsList

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxBeam1 = EL('<beam>begin</beam>')
>>> mxBeam2 = EL('<beam>begin</beam>')
>>> mxBeamList = [mxBeam1, mxBeam2]
>>> b = MP.xmlToBeams(mxBeamList)
>>> b
<music21.beam.Beams <music21.beam.Beam 1/start>/<music21.beam.Beam 2/start>>
Nr   )r   r  r  r  r   	beamsListr   )rv   
mxBeamListr   beamsOutrh  r  beamObjs          r:   r  MeasureParser.xmlToBeams  sj     zz|HH":.IAnnV,GUGN%%g. /
 O r<   c                h   UR                   S;  a  UR                   Ul        UR                  S5      nUb  [        R                  " U5      Ul        UR                  S5      b   UR                  S5      UR                  l        UR                  S5      nUb  [        R                  " U5      Ul        gg)a  
Set notehead information from the mxNotehead object

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> n = note.Note()
>>> nh = EL('<notehead color="#FF0000" filled="no" parentheses="yes">'
...         + 'diamond</notehead>')

>>> MP.xmlNotehead(n, nh)
>>> n.notehead
'diamond'
>>> n.noteheadFill
False
>>> n.noteheadParenthesis
True
>>> n.style.color
'#FF0000'
)r>   NfilledNr   parentheses)	r)   r  rq   r+   rs   noteheadFillr&   r   noteheadParenthesis)rv   r  r  nhfnhps        r:   r  MeasureParser.xmlNotehead4  s    , ??*,#AJnnX&?'66s;AN>>'".&NN73AGGM nn]+?$.$=$=c$BA! r<   c                   [         nUc  [        R                  " 5       nOUnUR                  S:X  a  UnOUR	                  S5      nUc  U$ U" XESS5        U" XESS[
        S9  UR	                  S5      nSn[        U5      =n(       a  [        U5      nUR	                  S5      n	Sn
[        U	5      =n(       a  Un
U
bX   U R                  U	5      nXl	        SUR                  l
        Ub*  X|R                  :w  a  UR                  S[        U5      5        U$ Ub-   [        R                  " U5      Ul	        SUR                  l
        U$ ! [        R                   a     U$ f = f! [        R                   a    [        S	U S
U 35      ef = f)a  
Given a MusicXML Note object, set this Pitch object to its values.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> b = EL('<note><pitch><step>E</step><alter>-1</alter>'
...        + '<octave>3</octave></pitch></note>')
>>> a = MP.xmlToPitch(b)
>>> print(a)
E-3

Conflicting alter and accidental -- alter is still stored, but name is :

>>> b = EL('<note><pitch><step>E</step><alter>-1</alter><octave>3</octave></pitch>'
...              + '<accidental>sharp</accidental></note>')
>>> a = MP.xmlToPitch(b)
>>> print(a)
E#3
>>> a.fullName
'E-sharp in octave 3'

>>> a.accidental.alter
-1.0

>>> a.accidental.name
'sharp'

>>> a.accidental.modifier
'#'
Nr"   stepoctaverR   alter
accidentalTzincorrect accidental z for pitch F)r^   r"   Pitchr[   rV   rM   rB   rL   xmlToAccidentalr  displayStatusr  setAttributeIndependentlyAccidentalException
Accidentalr.   )rv   r~  r   r   rg  mxPitchmxAlteraccAlter	alterTextmxAccidentalmxAccidentalNameaccidentalTextaccObjs                r:   r  MeasureParser.xmlToPitchX  s   @ (AA:: Gkk'*GQ(Q8s;,,w'$W--9-Y'H{{<0),77>7  .'
--l;%-1*'H,D44WeHoN  !F$//9
 */ALL& ,,   ,, F-+H:[DF FFs   =AE E! EE!&Fc                    Uc  [         R                  " 5       nOUnUR                  S5      nUR                  S5      n[        U5      =n(       a  Xcl        [        U5      =n(       a  [        U5      Ul        U$ )aD  
Set `displayStep` and `displayOctave` from `mxUnpitched`.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.divisions = 10080

>>> mxNote = EL('<note><duration>7560</duration><type>eighth</type></note>')
>>> unpitched = EL('<unpitched>'
...                + '<display-step>E</display-step>'
...                + '<display-octave>5</display-octave>'
...                + '</unpitched>')
>>> mxNote.append(unpitched)
>>> n = MP.xmlToSimpleNote(mxNote)
>>> n.displayStep
'E'
>>> n.displayOctave
5
>>> n.displayPitch().midi
76
display-stepdisplay-octave)r    r  rV   rB   displaySteprM   displayOctave)rv   r  r   unpmxDisplayStepmxDisplayOctavedisplayStepTextdisplayOctaveTexts           r:   r  MeasureParser.xmlToUnpitched  su    4 .."CC#((8%**+;<*=99?9-O ,_ === #$5 6C
r<   c                   Uc  [         R                  " 5       nOUn [        U5      R                  5       nX@R
                  ;   a  U R
                  U   nOUnUR                  USS9  U R                  X5        UR                  S5      nUR                  S5      nUS:X  a  US:X  a  SUl	        OUS:X  a  SUl	        OUS:X  a  SUl	        U R                  X5        U$ ! [         a    Us $ f = f)a  
>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> a = EL('<accidental parentheses="yes">sharp</accidental>')
>>> b = MP.xmlToAccidental(a)
>>> b.name
'sharp'
>>> b.alter
1.0
>>> b.displayStyle
'parentheses'

>>> a = EL('<accidental>half-flat</accidental>')
>>> b = pitch.Accidental()
>>> unused = MP.xmlToAccidental(a, b)
>>> b.name
'half-flat'
>>> b.alter
-0.5


>>> a = EL('<accidental bracket="yes">sharp</accidental>')
>>> b = MP.xmlToAccidental(a)
>>> b.displayStyle
'bracket'

>>> a = EL('<accidental bracket="yes" parentheses="yes">sharp</accidental>')
>>> b = MP.xmlToAccidental(a)
>>> b.displayStyle
'both'
T)allowNonStandardValuer  bracketr   both)r"   r  rB   lowerr?   r  r  r   rq   displayStyler   )rv   r  r   accmxNamer  r  r  s           r:   r  MeasureParser.xmlToAccidental  s    J ""$CC	!,/557F ///--f5DD 	D1<- #&&}5""9-%Gu$4%CE!,C(C 	,,
5  	J	s   C C+*C+c                2   U R                  U5      n[        R                  " US9nUR                  S5      nUc  [	        S5      eUR                  S5      nUS:X  a5  [        UR                  S5      5      =n(       a  US;   a  SU l        SUl        U R                  (       a  U R                  R                  U5        UR                  S	5      n[        U5      =n(       a  UR                  S
5      n	[        U	5      =n
(       a  XR                  5       -  n[        R                  " U5      nU R                  U5      n U R                  U   nUc  SnOUR                   S-   n UR$                  U-
  Ul        U R)                  X15      $ ! ["         a    Sn N3f = f)a.  
Takes a <note> tag that has been shown to have a <rest> tag in it
and return a rest.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.divisions = 10

>>> mxr = EL('<note><rest/><duration>5</duration><type>eighth</type></note>')
>>> r = MP.xmlToRest(mxr)
>>> r
<music21.note.Rest eighth>
>>> r.duration.quarterLength
0.5

>>> mxr = EL('<note><rest><display-step>G</display-step>' +
...              '<display-octave>4</display-octave>' +
...              '</rest><duration>5</duration><type>eighth</type></note>')
>>> r = MP.xmlToRest(mxr)
>>> r
<music21.note.Rest eighth>

A rest normally lies at B4 in treble clef, but here we have put it at
G4, so we'll shift it down two steps.

>>> r.stepShift
-2

Clef context matters, here we will set it for notes that don't specify a staff:

>>> MP.lastClefs[musicxml.xmlToM21.NO_STAFF_ASSIGNED] = clef.BassClef()
>>> r = MP.xmlToRest(mxr)

Now this is a high rest:

>>> r.stepShift
10

Test full measure rest defined with measure="yes" and a duration indicating
four quarter notes:

>>> mxr = EL('<note><rest measure="yes"/><duration>40</duration></note>')
>>> r = MP.xmlToRest(mxr)
>>> MP.fullMeasureRest
True

Note that here set `r`'s `.fullMeasure` to True or always because it has no type.

>>> r.fullMeasure
True

Same goes for rests which define type of whole (or breve), regardless of duration:

>>> mxr = EL('<note><rest measure="yes"/><duration>40</duration><type>whole</type></note>')
>>> r = MP.xmlToRest(mxr)
>>> MP.fullMeasureRest
True
>>> r.fullMeasure
True

But a rest that defines `measure="yes"` but has a type other than whole or breve
will set MeasureParser to fullMeasureRest but not set fullMeasure = True
on the music21 Rest object itself because pickup measures often use
measure="yes" in Finale, but display as quarter rests, etc.
See https://github.com/w3c/musicxml/issues/478

>>> mxr = EL('<note><rest measure="yes"/><duration>10</duration>'
...          + '<type>quarter</type></note>')
>>> r = MP.xmlToRest(mxr)
>>> MP.fullMeasureRest
True
>>> r.fullMeasure
'auto'
r   r)  z@do not call xmlToRest on a <note> unless it contains a rest tag.r{  r   ru  r  Tr  r  #      )r  r    r  rV   r.   rq   rB   r  r  rn  r  r6   r"   r  r>  r  
lowestLinerT  diatonicNoteNum	stepShiftr  )rv   mxRestr  r  	mxRestTagisFullMeasurerTypedsds_textdodo_texttempP	restStaffcc	ccMidLines                  r:   r{  MeasureParser.xmlToRest  s~   X v&IIq!KK'	) +C D D!i0E!)&++f*=>>E>5L^C^'+$ $ ;;KK--a0^^N+"2&&7& 01B&r**w*==?*KK(E ++F3I^^I.: "I " 1I  //);AK..q99  	s   =F F FFc                   U R                   nUSL a  UR                  U5        U R                  X!5        U R                  X!5        UR	                  S5      nUb/  UR
                  (       d  [        U5      S-  nXaR                  l        UR	                  S5      S:X  a.  UR                  R                  [        R                  " 5       5        UR                  S5      nSnUbH  SnUR                  S5      n	U	c  [        R                  " US	5        U R                  X!R                   5        UR                  S5      n
U
b  U R#                  XS
S5        UR                  S5      b  U R%                  U5      Ul        USL a  U R)                  Xq5      nUR+                  S5      nU H  nU R-                  X5        M     U R/                  X!5        U$ )aA  
Combined function to work on all <note> tags, where n can be
a Note or Rest.

>>> from xml.etree.ElementTree import fromstring as EL
>>> n = note.Note()
>>> mxNote = EL('<note color="silver"></note>')
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> n = MP.xmlNoteToGeneralNoteHelper(n, mxNote)
>>> n.style.color
'silver'
Tr   gmЁ}?	pizzicator   graceFru  z<type>eighth</type>sizenoteSizer*   	notations)r"  r  r   r   rq   r  rL   volumevelocityScalarr   r   	PizzicatorV   r6  
SubElementr  r   r   xmlToTier*   xmlGraceToGracerO  xmlNotationsr   )rv   r  r~  r  r"  dynamPercentage
dynamFloatmxGraceisGrace	graceTyper  mxNotationsmxNs                r:   r  (MeasureParser.xmlNoteToGeneralNoteHelper  s    **4==a@ 	6% 	F& !**Z0&qxx/:>J&0HH# ::k"e+OO""=#:#:#<= ++g&GF+I  f&;<vzz2 V$##FvzB;;u)MM&)AE
 d?$$W0A nn[1Cc%  	&$r<   c                   SnSnUc  SnOUnU R                   nUR                  S5      nUb1  [        UR                  R	                  5       5      n[        X-  5      n	OSn	UR                  S5      n
[        U
5      =n(       aP  [        U5      nSn[        UR                  S5      5      nUR                  S	5      nUb  U R                  U5      nOSnOSnS
nUb7  [        R                  " U	S9nUR                  Ul        UR                  Ul        O[        R                  " U	S9nU(       d  [        R                  " X5      nUR                   U	:X  a  U(       d  Uc  U$ S$ Ub)  UR#                  5         SUl        UR%                  U5        O[        R                  " US9nU H  nUR'                  U5        M     [)        UR                   U	SS9(       d  SUl        Xl        Uc  U$ g)aJ  
Translate a `MusicXML` <note> object's
<duration>, <type>, <dot>, tuplets, etc.
to a music21 :class:`~music21.duration.Duration` object.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> MP.divisions = 10080

>>> mxNote = EL('<note><pitch><step>D</step>' +
...     '<alter>-1</alter><octave>6</octave></pitch>' +
...     '<duration>7560</duration>' +
...     '<type>eighth</type><dot/></note>')

>>> c = duration.Duration()
>>> MP.xmlToDuration(mxNote, c)
>>> c
<music21.duration.Duration 0.75>
>>> c.quarterLength
0.75
>>> c.type
'eighth'
>>> c.dots
1

If the `<duration>` doesn't match the `<type>` and `<dots>`,
an unlinked duration is created so that `.quarterLength` agrees with
`<duration>` but the notated types can still be represented.

Create a second dot on `mxNote` and parse again, observing the identical
`quarterLength`:

>>> from xml.etree.ElementTree import SubElement
>>> unused = SubElement(mxNote, 'dot')
>>> c2 = MP.xmlToDuration(mxNote)
>>> c2
<music21.duration.Duration unlinked type:eighth quarterLength:0.75>
>>> c2.quarterLength
0.75
>>> c2.type
'eighth'
>>> c2.dots
2

Grace note durations will be converted later to GraceDurations:

>>> mxDuration = mxNote.find('duration')
>>> mxNote.remove(mxDuration)
>>> mxGrace = SubElement(mxNote, 'grace')
>>> MP.xmlToDuration(mxNote, inputM21=c2)
>>> c2
<music21.duration.Duration unlinked type:eighth quarterLength:0.0>
>>> gn1 = note.Note(duration=c2)
>>> gn2 = MP.xmlGraceToGrace(mxGrace, gn1)
>>> gn2.duration
<music21.duration.GraceDuration unlinked type:eighth quarterLength:0.0>
r   r  Nr   rK  ru  Fdottime-modificationTrY  )durationTuplegHz>)abs_tol)r.  rV   rL   r)   r6   r   rB   rJ   lenrO  xmlToTupletsr   Duration
componentsr  durationTupleFromTypeDotsr  clearaddDurationTupleappendTupletr   linked)rv   r~  r   numDotsr  r  r.  rT  noteDivisionsqLenr  typeStrdurationTypeforceRawmxTimeModificationdurRawdttups                     r:   r  MeasureParser.xmlToDuration  s   x AANN	[[,
!!*//"7"7"9:M-34DDV$"6**7*-g6LH &../0G "(-@!A!-++F3   LH =&&T:F!,,ALAI !!5A33LJB  D(' %,q6$6}		""2&%%B7s# 
 1??D$? "&H r<   c                   UR                  5       nUR                  S5      S;   a  SUR                  l        OSUR                  l         [	        UR                  S5      5      S-  UR                  l         [	        UR                  S5      5      S-  UR                  l        U$ ! [         a     N;f = f! [         a     U$ f = f)z~
Given a completely formed, non-grace Note or Chord that should become one
create and return a m21 grace version of the same.
slash)r   NTFzsteal-time-previousd   zsteal-time-following)getGracerq   r   rC  rM   stealTimePreviousru   stealTimeFollowing)rv   r#  noteOrChordr  s       r:   r  MeasureParser.xmlGraceToGracer  s    
 ##%;;w=0"&DMM"'DMM	.1'++>S2T.UX[.[DMM+	/27;;?U3V/WZ]/]DMM,   		
  	 	s$   
,B% 7,B5 %
B21B25
CCc                  ^ UR                  S5      nUS:X  a  SmOSmU4S jnS nU" US5       H<  nU R                  U5      nU" U5        Uc  M!  UR                  R                  U5        M>     U" US	5       H<  nU R	                  U5      nU" U5        Uc  M!  UR                  R                  U5        M>     UR                  S
5       H~  n[        R                  " 5       n	U" U	5        U R                  X5        UR                  S5      n
U
b  Xl	        [        U5      =n(       a  Xl        UR                  R                  U	5        M     S GH,  nUR                  U5       GH  nSnUS:X  a  SnOUR                  S5      =(       d    SnUR                  S5      nUc3  [        R                  " U5      nUR                  R                  U5        Mp  U R                  R                  [        R                  US5      nU(       a)  [         R"                  " [        R                  US   5      nO6[        R                  " US9nUUl        U R                  R                  U5        UR'                  U5        GM     GM/     SnU" US5       GH.  nUR(                  [*        R,                  ;   d  UR(                  S:X  ar  U R/                  UUS9nUb!  UR(                  S:X  a  UR1                  U5        U" U5        U R                  UU5        Ub  UnUR                  R                  U5        M  M  UR(                  S:X  a<  U R3                  Xb[        R4                  5      nU" U5        U R                  UU5        M  UR(                  S:X  d  GM  U R7                  Xb5      nU" U5        U R                  UU5        GM1     U R9                  X5        g)a  
>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxNotations = EL('<notations>' +
...     '<fermata type="upright">angled</fermata>' +
...     '</notations>')
>>> n = note.Note()
>>> MP.xmlNotations(mxNotations, n)
>>> n.expressions
[<music21.expressions.Fermata>]
>>> n.expressions[0].type
'upright'
>>> n.expressions[0].shape
'angled'
r   r   TFc                8   > T(       d  g SU R                   l        g )NT)r&   r   )rE  
hideObjects    r:   optionalHideObject6MeasureParser.xmlNotations.<locals>.optionalHideObject  s    *.CII'r<   c                P    U R                  U5      n[        R                  " U5      $ rh   )rO  r
   flattenList)rp  r  rO  s      r:   flatten+MeasureParser.xmlNotations.<locals>.flatten  s!    jj&G%%g..r<   	technicalNr   fermataru  )
arpeggiatenon-arpeggiatenormalrV  znon-arpeggior   r   r   )arpeggioType	ornamentsaccidental-markmostRecentOrnamentz	wavy-linetremolo)rq   xmlTechnicalToArticulationr   r   xmlToArticulationrO  r   Fermatar   ru  rB   shapeArpeggioMarkr"  getByClassIdLocalCompleterZ  r  rf  idLocalr  r[   r+   ORNAMENT_MARKSxmlOrnamentToExpressionresolveOrnamentalPitchesxmlOneSpannerTrillExtensionxmlToTremoloxmlNotationsToSpanners)rv   r&  r  printObjectValuerM  rQ  r@   technicalObjarticulationObjrT  fermataTypenotationText	tagSearchrX  idFoundarpeggiosbarpeggioSpannerr\  r  trillExtObjtremrL  s                         @r:   r   MeasureParser.xmlNotations  s]   & '??>:t#JJ	/	/ [+6E::5AL|,'&&|4	 7 [/:E"44U;O/*&&7	 ; !((3E!))+Gw'k3))F+K&*+E22|2 ,MM  ) 4 :I$,,Y7$, 00#1L#(99[#9#EXL$)IIh$7?*77EHMM((2++EE#77%IB*+&&1P1PRTUVRW*X*5*I*IWc*d29/**11/B#66q9) 8 :0 9=[+6EyyJ555FW9W33.@ 4  &1eiiCT6T&??B"4(!!+t4#)-&MM((. $ k)"00;;U;UV";/!!+{;i'((2"4(!!+t4/ 74 	##K3r<   c                   UR                   nU[        R                  ;   Ga  [        R                  U   " 5       n[        X5        US:X  a  U R	                  X15        US;   a   [        U5      (       a  [        U5      Ul        US;   a   [        UR                  5      Ul	        US:X  a  U R                  X5        US;   a<  UR                  S5      b*  [        R                  " UR                  S5      5      Ul        US:X  a  U R!                  X5        U R#                  X5        U$ [$        R'                  S	U S
U S35        g! [        [        4 a
  n SnANSnAff = f)al  
Convert an mxArticulationMark to a music21.articulations.Articulation
object or one of its subclasses.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxTech = EL('<down-bow placement="below"/>')
>>> a = MP.xmlTechnicalToArticulation(mxTech)
>>> a
<music21.articulations.DownBow>
>>> a.placement
'below'

Fingering might have substitution or alternate

>>> mxTech = EL('<fingering substitution="yes">5</fingering>')
>>> f = MP.xmlTechnicalToArticulation(mxTech)
>>> f
<music21.articulations.Fingering 5>
>>> f.substitution
True
>>> f.alternate
False

FingerNumbers get converted to ints if possible

>>> f.fingerNumber
5


>>> mxTech = EL('<fingering alternate="yes">4-3</fingering>')
>>> f = MP.xmlTechnicalToArticulation(mxTech)
>>>
<music21.articulations.Fingering 4-3>
>>> f.alternate
True
>>> f.fingerNumber
'4-3'
	fingering)handbellzother-technical)fretstringNharmonic)heeltoesubstitutionbendCannot translate r  r  )r[   r+   TECHNICAL_MARKSsynchronizeIdshandleFingeringrB   displayTextrM   r)   r   rN   ru   setHarmonicrq   rs   r  setBendr   rU  rV  )rv   r@   r[   tech
unused_errs        r:   r^  (MeasureParser.xmlTechnicalToArticulation  s:   R ii*,,,--c24D5'k!$$T155,u:M:M $0#6 (("%ejj/DK j   -o%99^,8(2(A(A%))NB[(\D%f}U) e*K##&7uDq$IJ! #I. s   	E EEc                2   UR                  S5      nUb;  UR                  b.  [        R                  " [	        UR                  5      5      Ul        UR                  S5      b  SUl        UR                  S5      b   UR                  S5      R                  Ul        UR                  S5      bG   [	        UR                  S5      R                  S5      5      n[        X@R                  -  5      Ul        gg! [        [        4 a  nSUl         SnAgSnAff = f)	a4  
Gets the bend amplitude from the bend-alter tag,
then optional pre-bend and with-bar tags are processed,
as well as release which is converted from divisions to music21 time.

Called from xmlTechnicalToArticulation

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxTech = EL('<bend><bend-alter>2</bend-alter></bend>')
>>> a = MP.xmlTechnicalToArticulation(mxTech)
>>> a
<music21.articulations.FretBend 0>
>>> a.bendAlter.semitones
2
>>> a.release

>>> a.withBar

>>> a.preBend
False

>>> mxTech = EL('<bend><bend-alter>-2</bend-alter><pre-bend/></bend>')
>>> a = MP.xmlTechnicalToArticulation(mxTech)
>>> a.bendAlter.semitones
-2
>>> a.preBend
True

>>> mxTech = EL('<bend><bend-alter>-2</bend-alter><release offset="1"/></bend>')
>>> a = MP.xmlTechnicalToArticulation(mxTech)
>>> a.bendAlter.semitones
-2
>>> a.release
Fraction(1, 10080)

>>> mxTech = EL('<bend><bend-alter>-1</bend-alter><with-bar>dip</with-bar></bend>')
>>> a = MP.xmlTechnicalToArticulation(mxTech)
>>> a.bendAlter.semitones
-1
>>> a.withBar
'dip'
z
bend-alterNzpre-bendTzwith-barreleaserD  rK  )rV   r)   r   IntervalrL   	bendAlterpreBendwithBarrq   r   r.  r  rN   ru   )rv   mxhr  r  r.  r  s         r:   r  MeasureParser.setBendN  s    Z &zz%!)!2!253D!E88J+DL88J+88J/44DL88I*#!#((9"5"9"9("CD	%i..&@A + 	* #"#s   .AC5 5DDDc                   U R                  S5      b  SUl        OU R                  S5      b  SUl        U R                  S5      b  SUl        gU R                  S5      b  SUl        gU R                  S5      b  S	Ul        gg)
a  
From the artificial or natural tag (or no tag) and
zero or one of base-pitch, sounding-pitch, touching-pitch,
sets .harmonicType and .pitchType on an articulations.Harmonic object

Called from xmlTechnicalToArticulation

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxTech = EL('<harmonic><artificial/><sounding-pitch/></harmonic>')
>>> a = MP.xmlTechnicalToArticulation(mxTech)
>>> a
<music21.articulations.StringHarmonic>

>>> a.harmonicType
'artificial'
>>> a.pitchType
'sounding'

artificialNnaturalz
base-pitchr0   zsounding-pitchsoundingztouching-pitchtouching)rV   harmonicType	pitchType)r  harms     r:   r  MeasureParser.setHarmonic  s{    , 88L!- ,DXXi , )D88L!-#DNXX&'3'DNXX&'3'DN 4r<   c                   UR                   Ul         [        UR                  5      Ul        UR                  S5      b*  [        R                  " UR                  S5      5      Ul        UR                  S5      b+  [        R                  " UR                  S5      5      Ul	        gg! [        [        4 a
  n SnANSnAff = f)z@
A few specialized functions for dealing with fingering objects
Nr  	alternate)
r)   fingerNumberrM   rN   ru   rq   r+   rs   r  r  )rv   r  r@   r  s       r:   r  MeasureParser.handleFingering  s     "JJ	 #D$5$5 6D 99^$0 * 9 9%))N:S TD99[!-'66uyy7MNDN .	 I& 		s   B' 'C<Cc                   UR                   nU[        R                  ;   a  [        R                  U   " 5       n[        X5        U R	                  X5        U R                  X5        US:X  a  UR                  S5      nUb  XCl        U$ US;   a  U R                  X5        U$ US:X  a  [        U5      =n(       a  XSl
        U$ US:X  a  [        U5      =n(       a  Xcl        U$ [        R                  SU SU S	35        g)
ax  
Return an articulation from an mxObj, setting placement

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxArt = EL('<spiccato placement="above"/>')
>>> a = MP.xmlToArticulation(mxArt)
>>> a
<music21.articulations.Spiccato>
>>> a.placement
'above'

>>> mxArt = EL('<doit dash-length="2" default-x="5" default-y="2" '
...            + 'line-shape="curved" line-type="dashed" space-length="1" />')
>>> a = MP.xmlToArticulation(mxArt)
>>> a
<music21.articulations.Doit>
>>> a.placement is None
True
>>> a.style.dashLength
2
>>> a.style.absoluteX
5
>>> a.style.lineShape
'curved'
zstrong-accentru  N)doitfalloffplopscoopzbreath-markzother-articulationr  r  r  )r[   r+   ARTICULATION_MARKSr  r   r   rq   pointDirectionr   rB   r  r  rU  rV  )rv   r@   r[   rn  r  
breathText	otherTexts          r:   r_  MeasureParser.xmlToArticulation  s   8 ii*///(;;C@BO52u6e5 o%!&6!2!-5C2 #" <<!!%9 #" %e9L+L:+L)3& #" ,,|E?R2R)2R.7+""##&7uDq$IJr<   r[  c                  UR                   nUS:X  a  Uc  gU R                  U5      nSUl        [        U[        R
                  5      (       a'  UR                  SS5      nUS:X  a  XBl        gXBl         g[        U[        R                  [        R                  45      (       a  XBl        g US;   a&  [        R                  U   " [        R                  S9nOEUS	;   a&  [        R                  U   " [        R                   S9nO[        R                  U   " 5       n U R%                  X5        U R'                  X5        U$ ! ["         a     gf = f)
a  
Convert mxOrnament into a music21 ornament.

This only processes non-spanner ornaments.
Many mxOrnaments are spanners: these are handled elsewhere.

Returns None if it cannot be converted or is not defined, or if the
mxObj is an accidental-mark (in which case the accidental is placed
in the mostRecentOrnament instead).

Return an articulation from an mxObj, setting placement

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxOrn = EL('<inverted-turn placement="above" font-size="24"/>')
>>> a = MP.xmlOrnamentToExpression(mxOrn)
>>> a
<music21.expressions.InvertedTurn>
>>> a.placement
'above'
>>> a.style.fontSize
24

If it can't be converted, return None

>>> mxOrn = EL('<crazy-slide placement="above"/>')
>>> a = MP.xmlOrnamentToExpression(mxOrn)
>>> a is None
True

If it is 'accidental-mark', add to mostRecentOrnament, and return None

>>> turn = expressions.Turn()
>>> turn.lowerAccidental is None
True
>>> turn.upperAccidental is None
True
>>> mxOrn = EL('<accidental-mark placement="below">flat</accidental-mark>')
>>> a = MP.xmlOrnamentToExpression(mxOrn, mostRecentOrnament=turn)
>>> a is None
True
>>> turn.lowerAccidental
<music21.pitch.Accidental flat>
>>> turn.upperAccidental is None
True

Not supported currently: 'vertical-turn'
rZ  NTr   abovebelow)zdelayed-turnzdelayed-inverted-turn)delay)turnzinverted-turn)r[   r  r  rm   r   Turnrq   lowerAccidentalupperAccidentalGeneralMordentTrillr  r+   re  r   DEFAULT_DELAYNO_DELAYrT  r   r   )rv   r@   r\  r[   accidr   orns          r:   rf  %MeasureParser.xmlOrnamentToExpression  s?   n ii##!)&*&:&:5&AE"&E,k.>.>?? "';!@	'9>6
  :?6  .1K1K[M^M^0_``05-	?? //4=;V;VW11 //4=;Q;QR //46 	5&%%
  		s   ,+E +E E 
EEc                   U R                   n/ nUb  [        U5      nUR                  S:X  a  UR                  S5      nUS:X  a  [        R
                  nO=US:X  a  [        R                  nO&US:X  a  [        R                  nO[        SU S35      eUS:w  a@  U R                  USUS	S
9nUR                  U5        U R                  R                  US5        OOUR                  S5      n	U R                  R                  SU	S5      n
 U
S   nS	Ul        Ub  UR!                  U5        UR                  S;   Ga  UR                  S5      nUR                  S5      n	US:X  a  ["        R$                  " 5       nXl        UR                  S:X  a  SUl        SUl        OPUR                  S5      nUb  [-        U5      Ul        UR                  S5      Ul        UR                  S5      Ul        U R                  R                  U5        UR                  U5        U R                  R                  US5        OUS:X  a   U R                  R                  SU	S5      S   nS	Ul        UR                  S:X  a  SUl        SUl        OPUR                  S5      Ul        UR                  S5      nUb  [-        U5      Ul        UR                  S5      Ul        Ub  UR!                  U5        O[        SU 35      eUR                  S:X  GaE  UR                  S5      nUR                  S5      nUR                  S5      n	US;   a  ["        R:                  " 5       nSUl        US :X  a
  S!nS"Ul        O	S nS#Ul        Xl        U=(       d    S$U4Ul         U R                  R                  U5        UR                  U5        U R                  R                  US5        OvUS%;   ab  U R                  R                  S&U	S5      n
 U
S   nUS(:X  a  U R                  R                  US5        O*S	Ul        Ub  UR!                  U5        O[        S)U 35      eUR                  S*:X  Ga  UR                  S5      nUR                  S+5      nUR                  S,5      nUR                  S-5      nUR                  S5      n	US.;   Ga  [B        RD                  " 5       nXl        X0RF                  U'   US:X  a   [B        RH                  RJ                  Ul&        O%US/:X  a  [B        RH                  RN                  Ul&        US0:X  a   [B        RP                  R$                  Ul)        O+US1:X  d  US0:X  a  [B        RP                  RT                  Ul)        US0:X  a  S	Ul+        U R                  R                  U5        UR                  U5        U R                  R                  US5        U$ US2;   Ga{  U R                  R                  S3U	S5      n
 U
S   nUS(:X  a   U$ US5:X  a:  [B        RX                  " 5       nU R[                  X2U5        UR!                  U5        U$ US6:X  a  U RF                  R                  US5      nURR                  [B        RP                  RT                  :X  a'  UU:X  a!  [B        RP                  R\                  Ul)        U$ [B        R^                  " 5       nU R[                  X2U5        UR!                  U5         U$ US7:X  a:  [B        R`                  " 5       nU R[                  X2U5        UR!                  U5        U$ US:X  a  S	Ul        Ub  UR!                  U5        U$ [        S8U 35      eU$ ! [         a    [        S5      ef = f! [         a0    [0        R2                  " SUR                  -   S-   [4        5        / s $ f = f! [         a    [        S'5      ef = f! [         a    [        S45      ef = f)9a	  
Some spanners, such as MusicXML wedge, bracket, dashes, pedal,
and ottava are encoded as MusicXML directions.

:param mxObj: the specific direction element (e.g. <wedge>).
:param staffKey: staff number (required for <pedal>)
:param totalOffset: offset in measure of this direction (required for <pedal>)

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> n1 = note.Note('D4')
>>> MP.nLast = n1

>>> len(MP.spannerBundle)
0
>>> mxDirectionType = EL('<wedge type="crescendo" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType)
>>> retList
[<music21.dynamics.Crescendo>]

>>> len(MP.spannerBundle)
1
>>> sp = MP.spannerBundle[0]
>>> sp
<music21.dynamics.Crescendo>

>>> mxDirectionType2 = EL('<wedge type="stop" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType2)

retList is empty because nothing new has been added.

>>> retList
[]

>>> len(MP.spannerBundle)
1
>>> sp = MP.spannerBundle[0]
>>> sp
<music21.dynamics.Crescendo <music21.note.Note D>>

>>> mxDirection = EL('<direction place="below"/>')
>>> mxDirectionType = EL('<pedal type="sostenuto" sign="yes" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType, 1, 0.5)
>>> retList
[<music21.expressions.PedalMark>]
>>> pedalMark = retList[0]
>>> pedalMark.pedalType
<PedalType.Sostenuto>
>>> pedalMark.pedalForm
<PedalForm.Symbol>

>>> mxDirectionType1a = EL('<pedal type="resume" line="yes" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType1a, 1, 0.5)
>>> retList
[]
>>> pedalMark.pedalForm
<PedalForm.SymbolLine>

>>> mxDirectionType2 = EL('<pedal type="change" line="yes" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType2, 1, 1.0)
>>> retList
[]

>>> mxDirectionType3 = EL('<pedal type="discontinue" line="yes" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType3, 1, 2.0)
>>> retList
[]

>>> mxDirectionType4 = EL('<pedal type="resume" line="yes" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType4, 1, 3.5)
>>> retList
[]

>>> mxDirectionType5 = EL('<pedal type="stop" line="yes" number="2"/>')
>>> retList = MP.xmlDirectionTypeToSpanners(mxDirectionType5, 1, 4.0)
>>> retList
[]
>>> pedalMark.getFirst()
<music21.expressions.PedalBounce at 1.0>
>>> pedalMark.getLast() is n1
True
>>> MP.stream.elements
(<music21.expressions.PedalBounce at 1.0>, <music21.expressions.PedalGapStart at 2.0>,
<music21.expressions.PedalGapEnd at 3.5>)
Nwedgeru  	crescendo
diminuendorw  zUnknown type, r  TallowDuplicateIdsr  r   DynamicWedgeFr   zError in getting DynamicWedges)r  dashesrv  r  nonedashedz
end-lengthzline-endr   LinezLine <z> stop without startz"unidentified mxType of mxBracket: octave-shiftr  )updownr  r  r  r     )r  rw  r2  zError in getting Ottavar  z%unidentified mxType of octave-shift: pedalabbreviatedlinesign)rv  	sostenutor  r   r   )r  rw  discontinueresumerV  	PedalMarkzError in getting PedalMarkr  r  rV  zunidentified mxType of pedal: )1r1  r   r[   rq   r   	Crescendo
Diminuendor  r.   rh  r   r"  "setPendingSpannedElementAssignmentrc  ry  r[  r  r$   r  rd  	startTickr   rL   startHeightr]  r^  r/   endTick	endHeightr2  transposingr   ru  r   r  r7  	PedalTypeSustain	pedalType	Sostenuto	PedalForm	pedalFormSymbolr  PedalGapStartrE  
SymbolLinePedalGapEndPedalBounce)rv   r@   r  totalOffset
targetLast
returnListmTypespClassrj  rr  spbr  heightmxSizem21TypemxAbbreviatedmxLinemxSignpgStartpedalStartOffsetpgEndpbs                         r:   xmlDirectionTypeToSpanners(MeasureParser.xmlDirectionTypeToSpannersH  s|   x ZZ

" -K99IIf%E#7?7I7I,&"--&"//-ugQ.GHH''tWPT'U!!"%""EEb-X))H-((BB"GU4TQB %)!)))*599--YYv&Fii)G \\^$
99(#)BL"*BK"YY|4F)).v#(99Z#8BL"'))K"8BK""))"-!!"% ""EEb-X6!++EE0013B %)!99(!'BJ"*BK!&:!6BJ"YY|4F)',V}"'))K"8BK )))*5-0RSYRZ.[\\99&YYv&FYYv&Fii)G'^^% "'T>$G#*BL"G#*BL$
!;Q0""))"-!!"%""EEb-X//((BBguMQB Z'&&II"m\(,B%!---j9-0UV\U].^__99YYv&F!IIm4MYYv&FYYv&Fii)G// **,$
.9''+W$#.#8#8#@#@BL{*#.#8#8#B#BBLU?#.#8#8#=#=BLt^v#.#8#8#?#?BL E)%)BN""))"-!!"%""EEb-X` _ RR((BB%PQB Z' B ? },)779G))+I))'26 5 x'
 7;6M6M6Q6QRTVZ6[$(=(=(D(DD 0K ?'2'<'<'G'G$  !, 7 7 9--kUK--e4  x'$002B))+D))"-  v%(,B%!---j9  .0Nvh.WXXU " T12RSSTF " MM(UYY"69O"OQ`aIb " M12KLLMZ " P12NOOPs6   ]$ : ]= 7^: 7_ $]:=7^76^7:__)c                `   UR                  S5       Hz  nU R                  X2[        R                  5      nU R	                  X45        U R                  X45        U R                  X45        U R                  UUS5        U R                  X45        M|     UR                  S5       H#  nU R                  X2[        R                  5        M%     UR                  S5       H#  nU R                  X2[        R                  5        M%     S H  nUR                  U5       H  nU R                  X2[        R                  5      nUS:X  a  SUl        U R	                  X65        UR                  S5      (       d  US:X  a  S	Ul        S	UR                   l        U R#                  X65        [%        X65        M     M     g )
Nslur)zbezier-offsetzbezier-offset2zbezier-xzbezier-yz	bezier-x2z	bezier-y2ztechnical/hammer-onztechnical/pull-off)	glissandoslider  
continuousr   solid)rO  rh  r$   Slurr   r   r   r   r   r   HammerOnPullOff	Glissando	slideTyperq   r   r&   r   r  )rv   r&  r  r@   r  rq  glisss          r:   rk  $MeasureParser.xmlNotationsToSpannersk  ss    !((0E%%e=De*U)e*##E$(%?& MM%& 1 !(()>?Eu)?)?@ @ !(()=>Eu)>)>? ? 0I$,,Y7**5W5F5FG'&2EO!!%/yy--)w2F%,EN+2EKK( ""50u, 8 0r<   c                z   UR                  S5      nSnUS;   a  Sn [        UR                  R                  5       5      nUSL a8  [        R                  " 5       nXVl        UR                  R                  U5        U$ U R                  X[        R                  5      nXWl        U$ ! [        [
        4 a    Sn Nyf = f)zo
Converts an mxTremolo to either an expression to be added to n.expressions
or to a spanner, returning either.
ru  T)rv  rw  F   )rq   rM   r)   r6   rN   r?   r   TremolonumberOfMarksr   rh  TremoloSpanner)rv   	mxTremolor  tremoloTypeisSinglenumMarksr  tremSpans           r:   rj  MeasureParser.xmlToTremolo  s      mmF+++H	9>>//12H t$$&B'MM  $I)))8R8RSH%-"O N+ 	H	s   #B% %B:9B:Fr  c                  UR                  S5      nU R                  R                  X5S5      nU(       a  USL a  US   nOBU" 5       nXWl        UR                  S5      nUb  Xl        U R                  R                  U5        Ub  UR                  U5        UR                  S5      S:X  a	  SUl        U$ UR                  S5      S:X  a  [        X5        U$ )	z
Some spanner types do not have an id necessarily, we allow duplicates of them
if allowDuplicateIds is True. Wedges are one.

Returns the new spanner created.
r   Fr   r   ru  rw  Trv  )	rq   r"  rc  rd  r   r   r  r[  r  )	rv   r@   r  spannerClassr  rr  rt  sur   s	            r:   rh  MeasureParser.xmlOneSpanner  s     ))H% 99,QVW#u, ABB J		+.I$(%%b) !!&) 99V& $B
 	 YYv')5%	r<   c                   [         R                  " 5       nUR                  S5      nU(       d  g/ nU H?  nUR                  S5      nUb  UR	                  U5        M*  [
        R                  S5        MA     [        U5      S:X  a  US   Ul        O+SU;   a  SU;   a  S	Ul        O[
        R                  S
U/5        UR                  S5      nUb  UR                  S5      nU(       a|  US   n	[        X5        U	R                  S5      n
U
b  U
S:w  a  Xl        U	R                  S5      nUb  Xl        U$ US   R                  S5      nUS:X  a	  SUl        U$ US:X  a  SUl        U$ )a  
Translate a MusicXML <note> with <tie> SubElements
:class:`~music21.tie.Tie` object

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

Create the incomplete part of a Note.

>>> mxNote = ET.fromstring('<note><tie type="start" />'
...            + '<notations>'
...            + '<tied line-type="dotted" placement="below" type="start" />'
...            + '</notations></note>')
>>> m21Tie = MP.xmlToTie(mxNote)
>>> m21Tie.type
'start'
>>> m21Tie.style
'dotted'
>>> m21Tie.placement
'below'

Same thing but with orientation instead of placement, which both get mapped to
placement in Tie objects

>>> mxNote = ET.fromstring('<note><tie type="start" />'
...            + '<notations>'
...            + '<tied line-type="dotted" orientation="over" type="start" />'
...            + '</notations></note>')
>>> tieObj = MP.xmlToTie(mxNote)
>>> tieObj.placement
'above'
r*   Nru  z'found tie element without required typer   r   rw  rv  r  zPfound unexpected arrangement of multiple tie types when importing from musicxml:r  tiedr   wavyr   orientationoverr  underr  )r*   TierO  rq   r   rU  rV  r.  ru  rV   r  r&   r   )rv   r~  tieObjallTies
typesFoundmxTie	foundTyper&  
mxTiedList	firstTiedtieStyler   r  s                r:   r  MeasureParser.xmlToTie  sm   D ..'
E		&)I$!!),''(QR  z?a$Q-FKz!g&;$FK##./9;< kk+."$,,V4J&qM	y1$==5'H,>#+L%MM+6	('0$  #-Q-"3"3M"BK"f,+2(  %/+2(r<   c           	        [         R                  " 5       nUR                  S5      nUc  [        S5      e[        nU" X#SS[
        S9  U" X#SS[
        S9  UR                  S	5      n[        U5      =n(       a  UnO[        UR                  S
5      5      n[        U5      n[        UR                  S5      5      n	UR                  X5        UR                  S5      n
U
c  X R                  S'   UR                  5       nUnS/S-  n[        5       n[        5       nU
Gb  U
R                  S5      nU GHj  nUR                  S
5      nUR                  S5      nUb  [        U5      OSnUS:X  aS  U R                  U   bA  U R                  U   nUU;   a
  Ub  SUl        UR!                  U5        UR!                  U5        M  UR                  S5      nUR                  S5      nUb  Uc  ["        R$                  " U5      nGO[         R                  " 5       nU" UUSS[
        S9  U" UUSS[
        S9  UR                  S5      nUb`  UR&                  =nbQ  UR)                  5       n[        U5      n[        UR                  S5      5      n[         R*                  " UU5      Ul        UR                  S5      nUb`  UR&                  =nbQ  UR)                  5       n[        U5      n[        UR                  S5      5      n[         R*                  " UU5      Ul        [0        R2                  " [0        R4                  S   S-  U5      Ul        UR                  S5      nUb  [6        R8                  " U5      Ul        UR                  S5      nUb  US:X  a  SUl        Uc  SUl        OUb  US:X  a  SUl        UR                  S5      n U b  U S :X  a  UR<                  b  SOS
Ul        O5Ub2  US:X  a,  UR<                  b  SOS
Ul        UR>                  b  SOS
Ul        UR                  S!5      n!U!b  U!S":X  a  S#Ul        [0        R2                  " [0        R4                  S$   UR                  S%5      5      Ul         X-U'   XR                  5       -  nX R                  U'   GMm     [C        S[        U R                  5      5       Hb  n"U R                  U"   n#U#c  M  U#U;   a  M  ["        R$                  " U#5      n$U"U;   a  SU$l        OSU$l        UU$R                  5       -  nU$UU"'   Md     US:w  ah  [D        RF                  " U5      n%[         R                  " U%RH                  U%RJ                  5      n&UR.                  U&l        UR,                  U&l        U&US&'   U H  n'SU R                  U''   M     U Vs/ s H	  o"c  M  UPM     nnU$ s  snf )'aq  
Given an mxNote, based on mxTimeModification
and mxTuplet objects, return a list of Tuplet objects

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxNote = ET.fromstring('<note><type>16th</type>' +
...    '<time-modification><actual-notes>5</actual-notes>' +
...    '<normal-notes>4</normal-notes></time-modification></note>')
>>> tups = MP.xmlToTuplets(mxNote)
>>> tups
[<music21.duration.Tuplet 5/4/16th>]

>>> mxNote = ET.fromstring('<note><type>eighth</type>' +
...    '<time-modification><actual-notes>5</actual-notes>' +
...    '<normal-notes>3</normal-notes>' +
...    '<normal-type>16th</normal-type><normal-dot /><normal-dot />' +
...    '</time-modification></note>')
>>> tup = MP.xmlToTuplets(mxNote)
>>> tup
[<music21.duration.Tuplet 5/3/16th>]
>>> tup[0].durationNormal
DurationTuple(type='16th', dots=2, quarterLength=0.4375)
r+  Nz.Note without time-modification in xmlToTupletszactual-notesnumberNotesActualrR   znormal-notesnumberNotesNormalznormal-typeru  z
normal-dotr  r   r  tupletr   r   rw  	startStopztuplet-actualztuplet-normalztuplet-numberztuplet-typez
tuplet-dot)rv  rw  r'  Fr  zshow-numberr  Fr  z	show-typeactualr   curvedr  )r  r  r   rV  )&r   TupletrV   r.   r^   rM   rB   rJ   r.  rO  setDurationTyper   tupletMultiplierr  rq   ru  r`   r  r  r)   r6   r2  durationActualdurationNormalr  rf  Literalr+   rs   r  tupletActualShowtupletNormalShowr   range	fractionsFractiondenominator	numerator)(rv   r~  r@  r=  r   mxNormalTypenormalTypeTextmusicXMLNormalTypedurationNormalTyper7  r&  !remainingTupletAmountToAccountFor
timeModTupreturnTupletsremoveFromActiveTupletstupletsToStop	mxTupletsmxTupletthis_tuplet_typetupletNumberStrtupletIndexactiveTmxTupletActualmxTupletNormalmxActualTypexmlActualTypedurTyper  mxNormalTypeTextxmlNormalTypebracketMaybe
showNumbershowType	lineShaperh  
thisActivethisActiveCopyremainderFractionremainderTuplettupletIndexToRemoves(                                           r:   r/  MeasureParser.xmlToTuplets   s   6 oo#[[)<=%)*Z[[ (Sn6IUXYSn6IUXY)..}=),77>7!/!-fkk&.A!B/0BC(00>?.8kk+.$'q! -0,@,@,B)
59FQJ"%% "#++H5I%#+<<#7 "*,,x"86E6Qc/2WX#v-))+6B"&"4"4["A"m38K+6GL/33K@%))+6!)!?!)!?!)^-C --
3C"//+Cn(*=Nn(*=N $2#6#6}#EL$02>2C2C!C P(5(;(;(="4]"C"<#7#7#EF-5-O-OPWY]-^*#1#6#6}#EL$05A5F5F!F!1 S(8(>(>(@"4]"C"<#7#7#EF-5-O-OPWY]-^* 66!)),O"PQU"U"24  (||I6+",";";L"ICK%\\-8
)jF.B+/C(#+&++
f0D+3C(#<<4'H,@585I5I5U6[aC(+
f0D585I5I5U6[aC(585I5I5U6[aC($LL6	(Y(-B"(CK !qyy1A'BHLLQ\D] ^-0k*15I5I5KK125"";/U &Z q#d0012A++A.J!]*!]]:6NM!&,#&*#-1P1P1RR--M! 3 -1 ) 2 23T U&oo.?.K.K.?.I.IKO-7-F-FO*-7-F-FO* /M" $;6:D23 $; )6II Js   .W8Wc                    SnU HO  nU R                  U5      nUc  M  UR                  S:X  a  X5l        UR                  R                  U5        US-  nMQ     g)a  
Takes a list of <lyric> elements and update the
note's lyrics from that list.

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxLyric1 = ET.fromstring('<lyric><text>Hi</text><elision/><text>There</text></lyric>')
>>> mxLyric2 = ET.fromstring('<lyric><text>Bye</text></lyric>')
>>> n = note.Note()
>>> MP.updateLyricsFromList(n, [mxLyric1, mxLyric2])
>>> n.lyrics
[<music21.note.Lyric number=1 syllabic=composite text='Hi There'>,
 <music21.note.Lyric number=2 text='Bye'>]
r   Nr   )
xmlToLyricr   lyricsr   )rv   r  	lyricListcurrentLyricNumberr  lyricObjs         r:   r|  "MeasureParser.updateLyricsFromList  sW    "  Gw/H!#"4HHOOH%!# !r<   c                   Uc  [         R                  " 5       nOUnUR                  S5      nUR                  S5      nUR                  S5      nU(       d  Uc  U$ g[        U5      S:X  aK  US   R                  nUb  UR                  5       Ul         US   R                  R                  5       Ul        O/ Ul	        [        U5       H  u  p[         R                  " 5       n
UR                  R                  U
5        U	R                  b  U	R                  R                  5       U
l         XX   nUR                  R                  5       U
l        US:  a   XhS-
     nUR                  nUc  SnXl        M  M     UR                  S5      n [        U5      nXl        UR                  S	5      nUb  Xl        U R'                  XS
S5        U R)                  X5        U R+                  X5        Uc  U$ g! [        [        4 a     Nf = f! [        [        [        4 a     GMV  f = f! ["        [        4 a    SUl        Ub  Xl         Nf = f)a  
Translate a MusicXML <lyric> tag to a
music21 :class:`~music21.note.Lyric` object or return None if no Lyric object
should be created (empty lyric tags, for instance)

If inputM21 is a :class:`~music21.note.Lyric` object, then the values of the
mxLyric are transferred there and nothing returned.

Otherwise, a new `Lyric` object is created and returned.

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxLyric = ET.fromstring('<lyric number="4" color="red">'
...                         + '<syllabic>single</syllabic>'
...                         + '<text>word</text></lyric>')
>>> lyricObj = note.Lyric()
>>> MP.xmlToLyric(mxLyric, lyricObj)
>>> lyricObj
<music21.note.Lyric number=4 syllabic=single text='word'>
>>> lyricObj.style.color
'red'

Non-numeric MusicXML lyric "number"s are converted to identifiers:

>>> mxLyric.set('number', 'part2verse1')
>>> l2 = MP.xmlToLyric(mxLyric)
>>> l2
<music21.note.Lyric number=0 identifier='part2verse1' syllabic=single text='word'>


Multiple texts can be created and result in composite lyrics

>>> mxBianco = ET.fromstring('<lyric>'
...                         + '<syllabic>end</syllabic>'
...                         + '<text>co</text>'
...                         + '<elision>_</elision>'
...                         + '<syllabic>single</syllabic>'
...                         + '<text>e</text>'
...                         + '</lyric>')
>>> bianco = MP.xmlToLyric(mxBianco)
>>> bianco
<music21.note.Lyric number=0 syllabic=composite text='co_e'>
>>> bianco.components
[<music21.note.Lyric number=1 syllabic=end text='co'>,
 <music21.note.Lyric number=1 syllabic=single text='e'>]
Nr)   syllabicelisionr   r   r>   r   r  )r   r   r   )r   r   r   )r    LyricrO  r.  r)   r6   r_  rN   ry  r1  r  r   elisionBeforer?   rq   rM   r   ru   
identifierr   r   r   )rv   r  r   lytext_elementssyllabic_elementselision_elementselement_textrh  mxText	component
mxSyllabic	mxElisionelision_textr   rc  s                   r:   rX  MeasureParser.xmlToLyric  s9   b BB  /#OOJ7"??95	}"(+00L'&,,./277==?
 BM&}5	 JJL	$$Y/;;*%+[[%6%6%8IN "3!5J)3)>)>)@I&Av$4U$;	 (1~~'/+-L2>/  66 X&		'[FI [[(
!&M H M	O 	g"%I o 
+ 8 #J?  :& 	' BI! &	's7   "G/ *AH	H" /HHHH" IIc                    U R                   nU R                  (       d  UR                  U R                  U5        gUR	                  S5      nU R                  U5      nUb  UnUR                  U R                  U5        g)z
Adds an object to a measure or a voice.  Needs a note element (obviously)
but also mxNote to get the voice.  Uses coreInsert and thus leaves insertStream
on the inner voice in an unusable state.
Nrw  )r%   r  rM  r   rV   findM21VoiceFromXmlVoice)rv   	mxElementr  insertStreammxVoice	thisVoices         r:   rZ  $MeasureParser.insertInMeasureOrVoicev  sn     {{~~##D$:$:B?..)
 11':	 $L 6 6;r<   c                ,   U R                   n[        U5      (       a  [        U5      n [        U5      U l        O,U R                  nUc  [
        R                  " S[        5        SnSnX0R                  ;   a  U R                  U   nU$ [        U5      U R                  ;   a  U R                  [        U5         nU$ [        U5      U R                  ;   a  U R                  [        U5         nU$ [
        R                  " SU< S3[        5        [
        R                  " S[        U R                  5       3[        5        [
        R                  " S[        UR                  5       SUR                   3[        5        U$ ! [         a
    X0l         GN,f = f)	z:
Find the stream.Voice object from a <voice> tag or None.
NzmCannot put in an element with a missing voice tag when no previous voice tag was given.  Assuming voice 1... r   zCannot find voice z; putting outside of voices.zCurrent voiceIds: zCurrent voices: z in m. )r%   rB   rM   r2  rN   r]  r^  r/   r+  r  rR  r  r   )rv   rs  r  useVoicert  s        r:   rp  &MeasureParser.findM21VoiceFromXmlVoice  sk    KK  #G,H*!$X ~~H O#% '+	&1I   ]doo-H6I  ]doo-H6I  MM$XL0LM! MM$T$//%:$;<! MM"4>"2'!((D! 9  *!)*s   E? ?FFc                   U R                   nUR                  S5      nUb  U R                  U5      nOU R                  U5      nUR                  S5      nUGb"  U R                  R                  [        R                  5      R                  S5      nU(       d2  [        R                  " U5      nU R                  R                  U5        OUS   nUR                  U5        UR                  S5      S:X  aj  UR                  S5      n Xl        UR                  n	U	bC  Xl        [         R"                  " S
U	5      n
U
(       a  [%        U
R'                  S	5      5      Ul        UR                  S5      S;   a  SUl        UR*                  S:X  a  XBl        gUR*                  S:X  a  XBl        gUR1                  5         UR                  U5        g! [        R                   a
    S	Ul         Nf = f)z]
Handles everything for putting a barline into a Stream
and updating repeat characteristics.
r#   NendingFr   ru  rv  r   r   z
^(\d+)\.?$)rw  r  Tr   r   )r%   rV   xmlToRepeatxmlToBarliner"  rY  r$   r  r\  r   r  rq   r   SpannerExceptionr)   overrideDisplayrematchrM   groupr[  locationleftBarlinerightBarliner^  )rv   	mxBarliner  mxRepeatObjr$  mxEndingObj
rbSpannersrbmxNumberendingNumberTextoverrideNumbers              r:   r  MeasureParser.xmlBarline  s   
 KKnnX."&&y1G''	2G  nnX." ++66%%!!%(  **1-""))"-
  ]%%a(v&'1&??84" (I $/#3#3 #/)9&%'XXm=M%NN%$'(<(<Q(?$@	 v&*AA$(! v%#M($N!!#HHW9 // " !BI"s   G G)(G)c                   Uc  [         R                  " 5       nOUn[        nU" X1SS5        U R                  X5        UR	                  S5      nUb  XSl        OSUl        UR                  S5      nUc  [         R                  " S5      eUR	                  S5      nUc  [        S	5      eUR                  5       S
:X  a  SUl
        O3UR                  5       S:X  a  SUl
        O[         R                  " SU5      eUR	                  S5      b    [        UR	                  S5      5      Ul        Uc  U$ g! [         R                   a     Nf = f)a  
Given an mxBarline (not an mxRepeat object) with repeatObj as a parameter,
file the necessary parameters and return a bar.Repeat() object

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxBarline = ET.fromstring('<barline><bar-style>light-heavy</bar-style>' +
...       '<repeat direction="backward"/></barline>')
>>> r = MP.xmlToRepeat(mxBarline)
>>> r
<music21.bar.Repeat direction=end>

Test that the music21 type for a backwards repeat is called "final"
(because it resembles a final barline) even though the musicxml style
is called light-heavy.

>>> r.type
'final'
>>> r.direction
'end'

Test that a forward repeat with times doesn't raise an exception, and
that the resulting Repeat doesn't have times set.

>>> mxStartBarline = ET.fromstring('<barline><bar-style>light-heavy</bar-style>' +
...       '<repeat direction="forward" times="2"/></barline>')
>>> rs = MP.xmlToRepeat(mxStartBarline)
>>> rs
<music21.bar.Repeat direction=start>
N	bar-styleru  r  r   r#   zPattempting to create a Repeat from an MusicXML bar that does not define a repeatr   z!Repeat sign direction is requiredr!  rv  backwardr  z"cannot handle mx direction format:times)r   Repeatr^   r   rq   r  rV   BarExceptionr.   r  r   rM   r  )rv   r  r   r  r   r  mxRepeatmxDirections           r:   r{  MeasureParser.xmlToRepeat  sF   B 

AA'Q;/)' ==,!J AJ>>(+"" $I J J ll;/)*MNN)+!AK J.AK""#GUU<< ,hll734
 H 	 ## s   
D/ /EEc                    Uc  [         R                  " 5       nOUn[        nU" X1SS5        UR                  S5      nUb  XSl        OSUl        Uc  U$ g)a  
Given an mxBarline, fill the necessary parameters

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxBarline = ET.fromstring(
...    '<barline location="right"><bar-style>light-light</bar-style></barline>')
>>> b = MP.xmlToBarline(mxBarline)
>>> b
<music21.bar.Barline type=double>
>>> b.type  # music21.type is different from musicxml.style
'double'
>>> b.location
'right'
Nr  ru  r  r   )r   Barliner^   rq   r  )rv   r  r   br   r  s         r:   r|  MeasureParser.xmlToBarlineP  s[    $ AA'Q;/==,!J AJH r<   c                    U R                  U5      nU R                  U5      nU R                  U R                  U-   X5        g)zL
Create a ChordSymbol object and insert it to the core and staff reference.
N)xmlToChordSymbolxmlToOffsetrE  r   )rv   	mxHarmonyhchordOffsets       r:   r  MeasureParser.xmlHarmonyr  sB    
 !!),&&y1d44{B'	,r<   c           	        SnSnSnSnSnUR                  S5      n[        U5      =n(       a  UnUR                  S5      n	UR                  S5      n
U
b  U
R                  S5      nUc  [        S5      e[        R                  " UR
                  5      nU
R                  S5      nUb3  UR
                  =nb$  [        R                  " [        U5      5      Ul        UR                  S	5      n[        U5      =n(       a  [        U5      nU(       ai  [        R                  (       a  Uc   eU[        R                  ;   a  [        R                  U   nUR                  S
5      =(       d    SnUS:X  a  US:w  d  UnUR                  S5      nUb  UR                  S5      n[        R                  (       a  Uc   eUR
                  nUS;   a  UR                  S
5      nUbZ  [        R                  " U5      nUR                  S5      nUb0  [        UR
                  5      n[        R                  " U5      Ul        U	b  [        R                   nO'US:X  a  [        R"                  nO[        R$                  nU" UUUUUS9n[&        nUc  U" UUSS5        UR)                  S5      nU Hg  n[        R*                  " 5       nU" UUSS[        S9  UR,                  c  [        S5      eU" UUSS[        S9  U" UUSS5        UR/                  USS9  Mi     U R1                  UU5        U R3                  UU5        U R5                  UU5        U	b   U$ )a  
Convert a <harmony> tag to a harmony.ChordSymbol object:

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> elStr = '<harmony><root><root-step>D</root-step><root-alter>-1</root-alter>'
>>> elStr += '</root><kind>major-seventh</kind></harmony>'
>>> mxHarmony = EL(elStr)

>>> cs = MP.xmlToChordSymbol(mxHarmony)
>>> cs
<music21.harmony.ChordSymbol D-maj7>

>>> cs.figure
'D-maj7'

>>> cs.pitches
(<music21.pitch.Pitch D-3>,
 <music21.pitch.Pitch F3>,
 <music21.pitch.Pitch A-3>,
 <music21.pitch.Pitch C4>)

>>> cs.root()
<music21.pitch.Pitch D-3>

TODO: this is very classically-oriented.  Make more Jazz/Rock like possible/default?.

>>> mxHarmony.find('kind').text = 'major-sixth'
>>> cs = MP.xmlToChordSymbol(mxHarmony)
>>> cs
<music21.harmony.ChordSymbol D-6>

>>> cs.figure
'D-6'

>>> cs.pitches
(<music21.pitch.Pitch D-3>, <music21.pitch.Pitch F3>,
 <music21.pitch.Pitch A-3>, <music21.pitch.Pitch B-3>)

>>> cs.root()
<music21.pitch.Pitch D-3>
Nr>   kindframebassz	bass-stepzbass-step missingz
bass-alter	inversionr)   r  rootz	root-steprU   z
root-alter)r  r  r  r  kindStrfunctionromanNumeraldegreezdegree-valuerR   zdegree-value missingzdegree-alterr   zdegree-typemodTypeT)updatePitches)rV   rB   r.   r"   r  r)   r  rL   r  rM   r  r  r   CHORD_ALIASESrq   r'   ChordWithFretBoardNoChordChordSymbolr^   rO  ChordStepModificationr  addChordStepModificationr   r   r   )rv   r  r  r  r  	chordKindchordKindStrmxKind
mxKindTextmxFramemxBassbassStepmxBassAlterr  mxInversioninversionTextmxRootmxRSrootTextmxRootAlter
alterFloatcs_classcsr   	mxDegreesmxDegreehds                              r:   r  MeasureParser.xmlToChordSymbol|  s   f #""		'%f--:-"I..)$-NN6$:{{;/H-.ABBHMM*A ++l3K&9I9I,II+V$//i0@A  nn[1(55=5 M*I )))G111#11)<	F+1rJ"$f)<) ';;{+D'''yyH:%88F+#KK)$kk,7*!&{'7'7!8J#(#3#3J#?AL
  33H& H**H 
 (>Y
N;%%h/	!H..0BX~x3Gyy -.DEEX~zSIX}i8''$'? " 	)R(9b)Ir*  	r<   c                   U R                  U5      n[        X R                  -   5      nU R                  U5      nSnUR	                  S5       H4  nU H+  nU R                  UUUU5        UR                  S:X  d  M)  SnM-     M6     U(       d?  UR	                  S5       H)  nSUR                  ;  a  M  U R                  UUUU5          g   gg)zz
convert a <direction> tag to one or more expressions, metronome marks, etc.
and add them to the core and staffReference.
Fzdirection-type	metronomeTr#  r(   N)	r  rL   r   r>  rO  setDirectionInDirectionTyper[   r  setSound)	rv   r  offsetDirectionr  r  metronome_added	mxDirTypemxSpecificDirectionTagmxSounds	            r:   r  MeasureParser.xmlDirection'  s     **;7O.D.DDE
 &&{3 %,,-=>I*3&001G1<191<> *--<&*O +4 ? &..w7'..0g)&)+  8 r<   c                   UR                   nUS:X  a  U H  nU R                  XX#U5        M     g US;   aa   U R                  XU5      nU HG  n	U R                  X5        U R                  X5        U R                  X5        U R                  X)5        MI     g US;   aq  US:X  a  [        R                  " 5       n
O[        R                  " 5       n
[        X5        U R                  X5        U R                  XCU
5        U R                  X*5        g US:X  aB  U R!                  U5      n[#        XSS5        U R                  XCU5        U R                  X+5        g US	:X  aG  U R%                  U5      nU R'                  X,S5        U R                  XCU5        U R                  X,5        g US
:X  ay  U R)                  U5      n[#        XSS5        UR+                  5       nUb$  U R                  XCU5        U R                  X.5        g U R                  XCU5        U R                  X-5        g g ! [         a.  n[        R
                  " SU SU 3[        5        / n S nAGNS nAff = f)Nr   )r  r  r  r  r  zCould not import z: )codasegnor  r  r   	rehearsalwords)r[   setDynamicsDirectionr  r.   r]  r^  r/   r   r   r   r   r#   SegnoCodar  rE  xmlToTempoIndicationr   xmlToRehearsalMarkr   xmlToTextExpressiongetRepeatExpression)rv   mxDirr  r  r  r[   mxDynspannerListexceprj  rk  mmrm_gentextExpressionrepeatExpressions                  r:   r  )MeasureParser.setDirectionInDirectionTypeR  s5   ( ii* ))%{[  KK!"==[ "  +!!%,!!%,!!+2	 " %%g~\\^[[]5%U'!!+<k.K**51B%b{KP!!+<k.K,,U3F##KE!!+@k2G^!55e<N &n;P[\-AAC+ %%k=MN!!+@ %%k^L!!+>! G + ! 1#b@/R !s   H# #
I-#IIc                B   UR                   nUS:X  a+  UR                  (       a  UR                  R                  5       n[        R                  " U5      n[        X'5        [        XsSS5        U R                  XTU5        U R                  X5        U R                  X75        g)z>
Add a single dynamic element to the core and staffReference.
zother-dynamicr   N)
r[   r)   r6   r   r  r  r   rE  r   r   )rv   r  r  r  r  r  m21DynamicTextr  s           r:   r  "MeasureParser.setDynamicsDirection  s}     _,"ZZ--/N^,u !!+{KkQ7"+)r<   c                j    [        U5      n[        R                  " U5      nU R                  X5        U$ )a  
Given an `mxWords`, create a :class:`~music21.expression.TextExpression`
and set style attributes, fonts, position, etc.

Calls `setTextFormatting`, which calls `setPrintStyleAlign`.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> m = EL('<words default-y="17" font-family="Courier" ' +
... 'font-style="italic" relative-x="-6">a tempo</words>')
>>> te = MP.xmlToTextExpression(m)
>>> te.content
'a tempo'
>>> te.style.relativeX
-6
>>> te.style.fontFamily
['Courier']
)rB   r   TextExpressionr   )rv   mxWordswordTexttes       r:   r  !MeasureParser.xmlToTextExpression  s1    2  (''1w+	r<   c                j    [        U5      n[        R                  " U5      nU R                  X5        U$ )z/
Return a rehearsal mark from a rehearsal tag.
)rB   r   RehearsalMarkr   )rv   mxRehearsalrehearsalTextrk  s       r:   r   MeasureParser.xmlToRehearsalMark  s1     %[1&&}5{/	r<   c                   / n/ nSnU H  nUR                   nUS:X  a<  [        UR                  5      n[        R                  " US9nUR                  U5        MQ  US:X  a%  Uc  [        S5      eU=R                  S-  sl        M|  US:X  d  M  UR                  n	U	c  M  U	R                  5       S:w  d  M   UR                  [        R                  " [        U	5      5      5        M     [        U5      S:  aD  [        R                  " 5       n
[        U5      S	:  a  [        S
5      eUS   U
l        US   U
l        O;[        R$                  " 5       n
U(       a
  US   U
l        U(       a
  US   U
l        Ub   UR+                  S5      nUb  US:X  a  SU
l        [/        X5        U R1                  X5        U R3                  X5        U
$ ! [         a     GM  f = f)a  
Given an mxMetronome, convert to either a TempoIndication subclass,
either a tempo.MetronomeMark or tempo.MetricModulation.

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> m = EL(r'<metronome><per-minute>125</per-minute>' +
...         '<beat-unit>half</beat-unit></metronome>')
>>> MP.xmlToTempoIndication(m)
<music21.tempo.MetronomeMark Half=125>

Metric modulation:

>>> m = EL(r'<metronome><beat-unit>long</beat-unit><beat-unit>32nd</beat-unit>' +
...         '<beat-unit-dot/></metronome>')
>>> MP.xmlToTempoIndication(m)
<music21.tempo.MetricModulation
 <music21.tempo.MetronomeMark Imperfect Longa=None>=<music21.tempo.MetronomeMark
           Dotted 32nd=None>>
Nz	beat-unit)ru  zbeat-unit-dotz-encountered metronome components out of orderr   z
per-minuter>      zYfound incompletely specified musicxml metric modulation: fewer than two durations definedr   r  r   T)r[   rJ   r)   r   r0  r   r.   r  r6   r
   rt   rL   rN   r.  r(   MetricModulationoldReferentnewReferentMetronomeMarkr   referentrq   r  r  r   r   )rv   mxMetronomer  	durationsnumbersdActiver@   r[   r;  perMinr  parens               r:   r  "MeasureParser.xmlToTempoIndication  s   . 	 E))Ck!1%**="++>  )'?12abb!$ %&,,.B*>v'='=eFm'LM# !, y>A'')B9~!-9: :
 'q\BN&q\BN $$&B#AJ	'l".~!%{'K,)	G & s   5.G
GGc                     [        UR                  S5      R                  R                  5       5      nX R                  -  $ ! [        [
        4 a     gf = f)a  
Finds an <offset> inside the mxObj and returns it as
a music21 offset (in quarterLengths)

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.divisions = 40
>>> off = EL(r'<direction><offset>100</offset></direction>')
>>> MP.xmlToOffset(off)
2.5

Returns a float, not fraction.

>>> MP.divisions = 30
>>> off = EL(r'<direction><offset>10</offset></direction>')
>>> MP.xmlToOffset(off)
0.33333...

rD  rK  )rL   rV   r)   r6   rN   r?   r.  )rv   r@   rD  s      r:   r  MeasureParser.xmlToOffset8  sQ    *	5::h/44::<=F && N+ 		s   2A AAc                   U R                   R                  S5      n[        R                  " U5      (       a4  [        R
                  R                  R                  U R                  l        O3[        R
                  R                  R                  U R                  l        U R                  5         U R                   R                  S5      nUb  [        U5      nX R                  l        gg)z
parses the attributes of the <measure> tag.  Not the
<attributes> tag inside the measure tag.

calls parseMeasureNumbers(), and gets the width from the width tag.

# TODO: non-controlling
# may need to do a format/unit conversion?
implicitwidthN)r  rq   r+   rs   r%   enums
ShowNumberNEVERrN  DEFAULTparseMeasureNumbersrQ   layoutWidth)rv   r  r  s      r:   rJ  $MeasureParser.parseMeasureAttributesS  s     >>%%j1$$X..%+\\%<%<%B%BDKK"%+\\%<%<%D%DDKK"  """7+"5)E&+KK# r<   c                >   SU l         Xl        U H  nUR                  nX0R                  ;   a"  [	        X R                  U   5      nU" U5        M@  US:X  a%  [        [        UR                  5      5      U l        Mk  US:X  a  [        UR                  5      U l
        M  US:X  d  M  U R                  U5      U l        M     U R                  XR                  5        U R                  b7  U R                  U R                  l        U R                  U R                  l        gg)a  
Parses a single attributes tag (mxAttributes) and sets

self.attributesAreInternal to False,
self.activeAttributes to mxAttributes,
self.parent.activeAttributes to mxAttributes
and then runs the appropriate attributeTagsToMethods for
the attribute.

Also sets `self.divisions` for the current divisions
(along with self.parent.lastDivisions)
and `self.transposition` and
to the current transpose.
Fr.  r  r;  N)r-  r(  r[   attributeTagsToMethodsrM  r   rL   r)   r.  rM   r  xmlTransposeToIntervalr  r   r%   rn  r*  )rv   mxAttributesmxSubr[   rP  s        r:   r   MeasureParser.parseAttributesTagi  s     &+" ,!E))C111t%@%@%EFU#!'ejj(9!: !%**o#%)%@%@%G" "& 	,4;;"(,DKK%+/+@+@DKK( #r<   c                &   SnUR                  S5      nUb  [        UR                  5      nSnUR                  S5      nUb  [        UR                  5      nSnUR                  S5      nUb3  [        UR                  5      S-  nUS[        UR                  5      -  -  nUb/  Ub,  US:  a  US-
  nOUS-   n [        R                  " UXF-   5      n	OLUb  [        R                  " XF-   5      n	O0Ub  [        R                  " U5      n	O[        R                  " S	5      n	[        X5        U	$ ! [        R
                   aQ    US:  a  U[        US-  S-  5      -
  S-
  nOU[        US-  S-  5      -
  S-   n[        R                  " UXF-   5      n	 Nqf = f)
a  
Convert a MusicXML Transpose object to a music21 Interval object.

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> t = ET.fromstring('<transpose><diatonic>-1</diatonic>'
...                   + '<chromatic>-2</chromatic></transpose>')
>>> MP.xmlTransposeToInterval(t)
<music21.interval.Interval M-2>

>>> t = ET.fromstring('<transpose><diatonic>-5</diatonic>'
...                   + '<chromatic>-9</chromatic></transpose>')
>>> MP.xmlTransposeToInterval(t)
<music21.interval.Interval M-6>


Not mentioned in MusicXML XSD but supported in (Finale; MuseScore): octave-change
refers to both diatonic and chromatic, so we will deal:

>>> t = ET.fromstring('<transpose id="x"><diatonic>-1</diatonic><chromatic>-2</chromatic>'
...         + '<octave-change>-1</octave-change></transpose>')
>>> inv = MP.xmlTransposeToInterval(t)
>>> inv
<music21.interval.Interval M-9>
>>> inv.id
'x'
Ndiatonic	chromaticr   zoctave-change   r  r   P1)	rV   rM   r)   r   intervalFromGenericAndChromaticIntervalExceptionr  GenericIntervalr  )
rv   mxTransposediatonicStep
mxDiatonicchromaticStepmxChromaticoctaveChangemxOctaveChangediatonicActualr  s
             r:   r  $MeasureParser.xmlTransposeToInterval  s   <  %%j1
!z/L!&&{3" 0 01M$))/:%~223b8LAN$7$7 888L #(A a!-!1!-!1^??@M@\^ &$$]%ABD%++L9D$$T*D{)) -- 	^  !#&2S9IB9N5O&OST%TN&2S9IB9N5O&OST%TN??@M@\^	^s   8D+ +A"FFc                f    U R                  U5      nUb  U R                  U R                  X5        gg)z
Creates a TimeSignature using xmlToTimeSignature and inserts it into
the stream if it is appropriate to do so (now always yes.)
N)xmlToTimeSignaturerE  r   )rv   mxTimer  s      r:   r  !MeasureParser.handleTimeSignature  s4    
 $$V,>!!$"8"8&E r<   c                z   UR                  S5      nUb   [        R                  " UR                  5      $ / n/ nU Hm  nUR                  S:X  a  UR                  [        U5      5        M/  UR                  S:X  a  UR                  [        U5      5        M[  UR                  S:X  d  Mm    O   [        X45       VVs/ s H  u  pgU SU 3PM     nnn[        U5      S:X  a   [        R                  " US   5      n	O5[        R                  " 5       n	U	R                  S	R                  U5      5        U R                  X5        U R                  X5        UR!                  S
5      n
U
c   U	$ U
S;   a  Xl        U	$ U
S:X  a	  SU	l        U	$ U
S:X  a   U	$ s  snnf ! [        R                   a    [        SUS    35      ef = f)a]  
Returns a TimeSignature or SenzaMisuraTimeSignature (for senza-misura)
from a <time> block.

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxTime = ET.fromstring('<time><beats>3</beats><beat-type>8</beat-type></time>')
>>> MP.xmlToTimeSignature(mxTime)
<music21.meter.TimeSignature 3/8>

>>> mxTime = ET.fromstring('<time symbol="common"><beats>4</beats>' +
...                                              '<beat-type>4</beat-type></time>')
>>> MP.xmlToTimeSignature(mxTime).symbol
'common'

Multiple times:

>>> mxTime = ET.fromstring('<time><beats>3</beats><beat-type>8</beat-type>' +
...                              '<beats>4</beats><beat-type>4</beat-type></time>')
>>> MP.xmlToTimeSignature(mxTime)
<music21.meter.TimeSignature 3/8+4/4>

>>> mxTime = ET.fromstring('<time><beats>3+2</beats><beat-type>8</beat-type></time>')
>>> ts32 = MP.xmlToTimeSignature(mxTime)
>>> ts32
<music21.meter.TimeSignature 3/8+2/8>

Senza Misura

>>> mxSenza = ET.fromstring('<time><senza-misura>0</senza-misura></time>')
>>> MP.xmlToTimeSignature(mxSenza)
<music21.meter.SenzaMisuraTimeSignature 0>


Small Duration Time Signatures

>>> mxTime = ET.fromstring('<time><beats>3</beats><beat-type>32</beat-type></time>')
>>> MP.xmlToTimeSignature(mxTime)
<music21.meter.TimeSignature 3/32>

>>> mxTime = ET.fromstring('<time><beats>3</beats><beat-type>64</beat-type></time>')
>>> MP.xmlToTimeSignature(mxTime)
<music21.meter.TimeSignature 3/64>

>>> mxTime = ET.fromstring('<time><beats>3</beats><beat-type>128</beat-type></time>')
>>> MP.xmlToTimeSignature(mxTime)
<music21.meter.TimeSignature 3/128>
zsenza-misurabeatsz	beat-typeinterchangeable/r   r   zCannot process time signature +r  )r
   cutzsingle-numberrW  r    Tzdotted-note)rV   r   SenzaMisuraTimeSignaturer)   r[   r   rB   rp   r.  r  MeterExceptionr.   loadr  r   r   rq   r  symbolizeDenominator)rv   r)  isSenzaMisura
numeratorsdenominators
beatOrTypenumdenommsgr  r  s              r:   r(   MeasureParser.xmlToTimeSignature  s   l N3$11-2D2DEE
 J~~(!!,z":;;.##L$<=#44 ! 36j2OP2OJC#aw2OP s8q=?((Q0
 $$&BGGCHHSM" 	+F'
 H%> 	 CCI 	 v&*B#
 		 }$ 	? Q '' ?-4SVH=? ??s   :F F &F:c                    U R                  U5      nU R                  U R                  X5        U R                  U5      nX R                  U'   g)a  
Handles a clef object, appending it to the core, and
setting self.lastClefs for the staff number.

>>> import xml.etree.ElementTree as ET
>>> mxClef = ET.fromstring('<clef><sign>G</sign><line>2</line></clef>')

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.handleClef(mxClef)
>>> MP.lastClefs
{0: <music21.clef.TrebleClef>}

>>> mxClefBC = ET.fromstring('<clef number="2"><sign>F</sign><line>4</line></clef>')
>>> MP.handleClef(mxClefBC)
>>> MP.lastClefs[2]
<music21.clef.BassClef>
>>> MP.lastClefs[0]
<music21.clef.TrebleClef>
N)	xmlToClefrE  r   r>  r  )rv   mxClefclefObjstaffNumberStrOrNones       r:   r  MeasureParser.handleClefY  sH    * ..(d44fF  $226:/6+,r<   c                   UR                  S5      R                  R                  5       nUR                  5       S;   a  [        R
                  " U5      nOUR                  S5      nUb  UR                  R                  5       nOUS:X  a  SnOSnUR                  S5      nUb   [        UR                  5      nOSn[        R
                  " X%-   U5      nU R                  X5        U R                  X5        U$ ! [         a    Sn NKf = f)	a=  
Returns a music21 Clef object from an mxClef element.

>>> import xml.etree.ElementTree as ET
>>> mxClef = ET.fromstring('<clef><sign>G</sign><line>2</line></clef>')

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.xmlToClef(mxClef)
<music21.clef.TrebleClef>

>>> mxClef = ET.fromstring('<clef><sign>G</sign><line>2</line>'
...                        + '<clef-octave-change>-1</clef-octave-change></clef>')
>>> MP.xmlToClef(mxClef)
<music21.clef.Treble8vbClef>

>>> mxClef = ET.fromstring('<clef><sign>TAB</sign></clef>')
>>> MP.xmlToClef(mxClef)
<music21.clef.TabClef>
r  )tabr!   r  jianpur  G24zclef-octave-changer   )
rV   r)   r6   r  r	   clefFromStringrM   rN   r   r   )rv   r?  r  r@  r  r  r$  r#  s           r:   r>  MeasureParser.xmlToClefu  s    * {{6"''--/::<BB))$/G[[(F!{{((*#[[)=>N)%#&~':':#;L  !))$+|DG 	6+F, " %#$L%s   $C9 9DDc                ^    U R                  U5      nU R                  U R                  X5        g)zG
convert mxKey to a Key or KeySignature and run insertCoreAndRef on it
N)xmlToKeySignaturerE  r   )rv   mxKeykeySigs      r:   r   MeasureParser.handleKeySignature  s*     ''.d44eDr<   c                   UR                  S5      c  U R                  U5      nO`[        R                  " 5       n[        nU" X!SS[
        S9  UR                  S5      nUb$  UR                  nUS;  a   UR                  U5      nU R                  X5        U R                  X5        U R                  X5        U$ ! [        R                   a     NKf = f)a  
Returns either a KeySignature (traditional or non-traditional)
or a Key object based on whether fifths and mode is present.

>>> import xml.etree.ElementTree as ET
>>> mxKey = ET.fromstring('<key><fifths>-4</fifths></key>')

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.xmlToKeySignature(mxKey)
<music21.key.KeySignature of 4 flats>


>>> mxKey = ET.fromstring('<key><fifths>-4</fifths><mode>minor</mode></key>')

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.xmlToKeySignature(mxKey)
<music21.key.Key of f minor>


Invalid modes get ignored and returned as KeySignatures

>>> mxKey = ET.fromstring('<key><fifths>-4</fifths><mode>crazy</mode></key>')

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.xmlToKeySignature(mxKey)
<music21.key.KeySignature of 4 flats>
fifthssharpsrR   moderU   )rV   nonTraditionalKeySignaturer   r  r^   rM   r)   asKeyr   Music21ExceptionmxKeyOctavesr   r   )rv   rM  ksr   	mxKeyMode	modeValues         r:   rL  MeasureParser.xmlToKeySignature  s    > ::h'007B!!#B+DHh#>

6*I$%NN	J.XXi0 	%$5%E&	 (88 s   4B: :CCc                p   UR                  S5      nU(       d  g[        R                  " UR                  5      nU HZ  nUR	                  S5      nUS:X  a  M  UR	                  S5      n U[        U5      S-
     n[        UR                  5      n	Xl	        M\     XBl        g! [        [        4 a     Mx  f = f)aS  
process the <key-octave> tags to potentially change a key signature
to a non-standard key signature.

>>> import xml.etree.ElementTree as ET
>>> mxKey = ET.fromstring('<key><fifths>-4</fifths>'
...   + '<key-octave number="1">3</key-octave>'
...   + '<key-octave number="2">4</key-octave>'
...   + '<key-octave number="4">3</key-octave>'
...   + '</key>')

>>> ks = key.KeySignature(-4)
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.mxKeyOctaves(mxKey, ks)
>>> ks.alteredPitches
[<music21.pitch.Pitch B-3>,
 <music21.pitch.Pitch E-4>,
 <music21.pitch.Pitch A->,
 <music21.pitch.Pitch D-3>]
z
key-octaveNcancelr   r   r   )
rO  r  r  alteredPitchesrq   rM   ry  rN   r)   r  )
rv   rM  rX  
keyOctavesr^  mxKeyOctaver]  
pitchIndexalteredPitchoctaveToSets
             r:   rW  MeasureParser.mxKeyOctaves  s    . ]]<0
r'8'89%K __X.F$2J-c*o.AB k../K"- & + 
+ s   *B!!B54B5c                   [        U5      nSn/ n/ n/ nU H  nUR                  nUS:X  a  US:X  a  UR                  S5        US:X  a  UR                  UR                  5        OLUS:X  a%  UR                  [	        UR                  5      5        O!US:X  a  UR                  UR                  5        UnM     [        U5      [        U5      :  a  UR                  S5        [        U5      [        U5      :w  a  [        S5      e[        R                  " SS9n	/ n
[        XEU5       H  u  pn[        R                  " U5      nUbM  XR                  ;   a  U R                  U   nOUn[        R                  " U5      Ul        XR                  l        O[        R                  " U5      Ul        U
R                  U5        M     Xl        U	$ )a  
Returns a KeySignature object that represents a nonTraditional Key Signature

called by xmlToKeySignature if <fifths> is not present.

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> mxKey = ET.fromstring('<key><key-step>E</key-step><key-alter>-1</key-alter></key>')
>>> MP.nonTraditionalKeySignature(mxKey)
<music21.key.KeySignature of pitches: [E-]>

Should be the same:

>>> MP.xmlToKeySignature(mxKey)
<music21.key.KeySignature of pitches: [E-]>


Works with key-accidental also:

>>> mxKey = ET.fromstring('<key><key-step>G</key-step><key-alter>1</key-alter>'
...                       + '<key-accidental>sharp</key-accidental></key>')
>>> MP.nonTraditionalKeySignature(mxKey)
<music21.key.KeySignature of pitches: [G#]>
Nz	key-alterzkey-stepzkey-accidentalz;For non traditional signatures each step must have an alter)rR  )rR  r[   r   r)   rL   r.  r.   r   r  rp   r"   r  r  r  r  r  r^  )rv   rM  childrenlastTagstepsaltersaccidentalsr   r[   rX  r^  r  r  r  rg  accidentalNames                   r:   rT  (MeasureParser.nonTraditionalKeySignature  s   6 ;A%%C+%#*;""4(j QVV$#eAFFm,((""166*G  {c&k)t$u:V$)MO O T*'*5+'F#DD!A%!;!;;%)%?%?
%KN%/N$//?%*"$//6!!!$ (G +	r<   c                   UR                  S5      nUb  [        U5      nOSnX R                  4nU R                  R                  US5      nU R	                  UUS9nUc+  U R                  U R                  X5        XPR                  U'   gg)a  
StaffDetails (staff-details) handles attributes about
the staff itself -- its size, number of lines, tuning,
frets, etc.

It is different from StaffLayout (staff-layout) which
only handles relationship of one staff to another (the
distance)

Rather than returning a StaffLayout object,
it adds it to self.staffLayoutObjects checking
to see if there is already an incomplete
StaffLayout object for this staff.
r   Nr   )m21staffLayout)rq   rM   r   r   xmlStaffLayoutFromStaffDetailsrE  )rv   	mxDetailsr   layoutObjectKeyexistingStaffLayoutObjectnewStaffLayoutObjects         r:   r   MeasureParser.handleStaffDetailsX  s    &  mmH-"k*KK&(>(>?$($;$;$?$?QU$V!#BB4  C  
 %,!!$"8"8)Z7K##O4 -r<   c                F   [         nU(       d  [        R                  " 5       nOUnUR                  S5      nUb  [	        U5      Ul        UR                  S5      nUS:X  d  USL a  SUl        OUS:X  d  USL a  SUl        U" XAS[        S	9  UR                  S
5      nUb?   UR                  R                  5       n[        R                  R                  U5      Ul        U" XAS[$        S	9  U(       d  U$ g! [         a!    [        R                   " SU 3["        5         N@f = f)a  
Returns a new StaffLayout object from staff-details or sets attributes on an existing one

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> mxDetails = EL('<details number="2" print-object="no">'
...                + '<staff-size>21.2</staff-size><staff-lines>4</staff-lines>'
...                + '</details>')
>>> stl = MP.xmlStaffLayoutFromStaffDetails(mxDetails)
>>> stl.staffSize
21.2
>>> stl.staffLines
4
>>> stl.staffNumber
2
>>> stl.hidden
True

`staffType` defaults to Regular:

>>> stl.staffType
<StaffType.REGULAR: 'regular'>
>>> mxDetails2 = EL(r'<details number="2"><staff-type>cue</staff-type></details>')
>>> MP.xmlStaffLayoutFromStaffDetails(mxDetails2, m21staffLayout=stl)
>>> stl.staffType
<StaffType.CUE: 'cue'>
r   Nr   r   FTr   zstaff-linesrR   z
staff-typez(Got an incorrect staff-type in details: z
staff-size)r^   r   r   rq   rM   r   hiddenrV   r)   r6   r%   r	  	StaffType	staffTyperN   r]  r^  r/   rQ   )	rv   rp  rn  r   rr  r   staffPrintedmxStaffTyper  s	            r:   ro  ,MeasureParser.xmlStaffLayoutFromStaffDetails|  s   B ($$&C C  mmH-"!+.CO }}^44<5#8CJU"ld&:CJ
 	S]c:  nn\2"_*//557 & 6 6w ? 	S\^D J   _>{mLo__s   !>C5 5(D D c                J   UR                  S5      nUb  U R                  b  [        UR                  5      U R                  l        [
        R                  " 5       nUR                  S5      nUS:X  a  SUl        OSUl        X0R                  l	        U R                  X#5        ggg)z
measure + multi-measure repeats, slashed repeats, etc.

But currently only multiMeasure rests are supported.

Each of these applies to the entire measure, so there's
no need to insert into the stream.

Does not support multiple staves yet.
zmultiple-restNzuse-symbolsr   TF)rV   rn  rM   r)   r$  r$   MultiMeasureRestrq   
useSymbolsr%  r   )rv   mxMeasureStylemxMultiRest
mmrSpannerr~  s        r:   r   MeasureParser.handleMeasureStyle  s     %))/:"t{{'>589I9I5JDKK2 113J$7JU"(,
%(-
%8BKK5LL1 (?"r<   c                t   Uc(  U R                   b  U R                   R                  S5      nU R                  nU R                  (       a-  U R                  R                  nU R                  R
                  nOSnSnUc  SnSnO[        R                  " U5      u  pVUS;  a  [        U5      Ul	        US;  a  Xbl
        UbX  UR                  S:X  aH  UR                  US-   :w  a5  UR                  [        UR                  5      -   nUb  XG-   nX2l	        Xrl
        UR                  U l        UR                  U l
        g)ax  
Gets the measure number from the 'number' attribute of the
<measure> tag.  (Or, for testing, from the mNumRaw
argument).  Sets MeasureParser.stream.number and possibly
MeasureParser.stream.numberSuffix

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.parseMeasureNumbers('5')
>>> MP.stream.number
5

Sets not only `stream.number`, but also `MeasureParser.measureNumber` and
`MeasureParser.numberSuffix`

>>> MP.parseMeasureNumbers('44b')
>>> MP.stream.number
44
>>> MP.stream.numberSuffix
'b'
>>> MP.measureNumber
44
>>> MP.numberSuffix
'b'

>>> MP.parseMeasureNumbers('X1')
>>> MP.stream.number
1
>>> MP.stream.numberSuffix
'X'
Nr   r>   rU   Xr   )r  rq   r%   rn  r"  r#  r
   getNumFromStrrM   r   r  r  r  )rv   mNumRawr  lastMNumlastMSuffixmNummSuffix	newSuffixs           r:   r  !MeasureParser.parseMeasureNumbers  s
   > ?t~~9nn((2GKK;;{{44H++66KHK?DG"009MD z!4yAH*$$N ~~$X\)ANNS]:	* + 7I#!*XXNNr<   c                *   U R                   nS H[  nUR                  U5       HC  nUR                  S5      n[        U5      =n(       d  M(  U R                  R                  U5        ME     M]     [        U R                  5      S:  a  [        U R                  5       HR  n[        R                  " 5       nXVl
        U R                  R                  SU5        X`R                  UR                  '   MT     SU l        U R                  R                  5         gg)av  
Finds all the "voice" information in <note> and <forward> tags and updates the set of
`.voiceIndices` to be a set of all the voice texts, and if there is
more than one voice in the measure, sets `.useVoices` to True
and creates a voice for each.

>>> import xml.etree.ElementTree as ET
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.mxMeasure = ET.fromstring('<measure><note><voice>1</voice></note></measure>')
>>> MP.updateVoiceInformation()

Puts a set object in `.voiceIndices`

>>> MP.voiceIndices
{'1'}
>>> MP.useVoices
False

>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.mxMeasure = ET.fromstring('<measure><note><voice>1</voice></note>'
...                                     + '<note><voice>2</voice></note></measure>')
>>> MP.updateVoiceInformation()
>>> sorted(list(MP.voiceIndices))
['1', '2']
>>> MP.useVoices
True
>>> len(MP.stream)
2
>>> list(MP.stream.getElementsByClass(stream.Voice))
[<music21.stream.Voice 1>, <music21.stream.Voice 2>]
>>> MP = musicxml.xmlToM21.MeasureParser()
>>> MP.mxMeasure = ET.fromstring('<measure><note><voice>1</voice></note>'
...                                     + '<forward><voice>2</voice></forward></measure>')
>>> MP.updateVoiceInformation()
>>> sorted(list(MP.voiceIndices))
['1', '2']
>>> MP.useVoices
True
>>> len(MP.stream)
2
>>> list(MP.stream.getElementsByClass(stream.Voice))
[<music21.stream.Voice 1>, <music21.stream.Voice 2>]
)r    r!  rw  r   rK  TN)r  rO  rV   rB   r,  r`   r.  r  r%   VoicerJ  rM  r+  r  r^  )rv   mxmrq  mxnrw  r  rQ  s          r:   rK  $MeasureParser.updateVoiceInformation'  s    Z nn,I{{9-))%0060%%))&1 . - t  !A% !2!23LLN&&sA.()%	 4
 "DNKK++- &r<   )r(  r   r-  r.  r  r  r  r2  r  r0  r  r*  r/  r1  r  r   rn  r4  r7  r3  r"  r   r  r  r%   r  r  r,  r+  r	  )r  r
  rn  zPartParser | None)r  rM   )r@   r
  )r   r
  )r~  r
  r  r  )r/  zlist[ET.Element]r  zchord.ChordBase)T)r  znote.Note | note.Unpitchedrh   )r  r
  )r  r
  r   znote.Unpitched | Noner  znote.Unpitched)r  r
  r   zpitch.Accidental | Noner  zpitch.Accidental)r&  r
  r  znote.GeneralNote)r\  zexpressions.Ornament | None)r@   r
  r  z
int | Noner  zOffsetQL | None)r~  r
  r  zlist[duration.Tuplet])r  znote.Lyric | None)rs  r
  r  zstream.Voice | None)r  r
  r  zDharmony.ChordSymbol | harmony.NoChord | tablature.ChordWithFretBoard)r  r
  r  r
  r  rM   r  rL   )
r  r
  r  r
  r  r
  r  rM   r  rL   )r)  r
  r  z4meter.TimeSignature | meter.SenzaMisuraTimeSignature)rn  layout.StaffLayout | Noner  r  )Lr  r  r	  r
  r  r  rL  r  r  r>  rA  rE  r7  r  r  rI  r  r}  rz  r  r  r  r  r  r  r{  r  r  r  r   r^  r  r  r  r_  rf  r  rk  rj  rh  r  r/  r|  rX  rZ  rp  r  r{  r|  r  r  r  r  r  r  r  r  r  rJ  r  r  r  r(  r  r>  r  rL  rW  rT  r  ro  r  r  rK  r  r  r  s   @r:   r  r   	  sk   , &#-- #*" /3+/KY+KY(KY KYZ J% J%\&3P2((@F:-4:,~_2BXtRUlJX8"CHPj )-&& && 
	&V +/F F (F 
	FPt:lIxDL2v4pIV:#x ( (BO3r 9=	W 6	Wx "%)	aa a #	aF	#-J6 OT #JN`ob$6HT<. $() ) 
)VIVM^ D,ii 
JiV'VS?S?  S? 	S?
 S?j** *  	*
 * *0<Pd'6,,(ATUnFdd 
<dL782hE2h*+XFP!LN 37G 0G 
!	GR2<B+H>. >.r<   r  __main__)r8   
str | Noner  r  )r@   r
  r  r  )rI   r  r  r  rh   )ra   r  )c
__future__r   r  r3  r?  r5  mathr   r  typingr  r]  xml.etree.ElementTreer:  ElementTreer6  music21r   r   r   r   r	   r
   r   r   r   music21.common.enumsr   music21.common.numberToolsr   r   r   r   r   r   r   r   r   r   r   r   r   music21.midi.percussionr   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   music21.musicxmlr+   r,   music21.musicxml.xmlSoundParserr-   music21.musicxml.xmlObjectsr.   r/   synchronizeIdsToM21r  setM21AttributeFromAttributer   r  r0   music21.common.typesr1   dictrM   rR  Music21Objectr  EnvironmentrU  r  
propertiesALL_NAMESPACE_NAMESALL_UNIQUE_NAMESALL_MUSIC21_WORK_IDSr2   __annotations__r;   rB   rJ   rQ   r^   rc   re   r  r  ro  r  r  mainTestr  r<   r:   <module>r     s   #   	   	   " " !         . >             M            ' $ 9 P,,#@@ ??- c4(:(:#;;<&&':;    $++**+../  9 "L<25)QU 5)n	#M M`. .2r
} r
lx6 x6xEA.M= EA.VB z r<   