
    rhA             	         % S r SSKJr  SSK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	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  SSK	Jr  SSK	Jr  SSK	Jr  \R:                  " S5      rSrSr  " S S\RB                  5      r" " S S\RF                  5      r$ " S S\RJ                  5      r&S r'    S;S jr(S  r)0 r*S!\+S"'    " S# S$5      r,S<S% jr-S&S'S(S)S*S+S,S-S..r. S<   S=S/ jjr/S0 r0S1 r1S2 r2S<S3 jr3 " S4 S5\Rh                  5      r5 " S6 S7\Rh                  5      r6/ r7S8\+S9'   \8S::X  a  SSK	r	\	Rr                  " \65        gg)>a  
Translation routines for roman numeral analysis text files, as defined
and demonstrated by Dmitri Tymoczko.  Also used for the ClercqTemperley
format which is similar but a little different.

This module is really only needed for people extending the parser,
for others it's simple to get Harmony, RomanNumeral, Key (or KeySignature)
and other objects out of an rntxt file by running this:


>>> monteverdi = corpus.parse('monteverdi/madrigal.3.1.rntxt')
>>> monteverdi.show('text')
{0.0} <music21.metadata.Metadata object at 0x...>
{0.0} <music21.stream.Part ...>
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.key.KeySignature of 1 flat>
        {0.0} <music21.meter.TimeSignature 4/4>
        {0.0} <music21.roman.RomanNumeral vi in F major>
        {3.0} <music21.roman.RomanNumeral V[no3] in F major>
    {4.0} <music21.stream.Measure 2 offset=4.0>
        {0.0} <music21.roman.RomanNumeral I in F major>
        {3.0} <music21.roman.RomanNumeral IV in F major>
    ...

Then the stream can be analyzed with something like this, storing
the data to make a histogram of scale degree usage within a key:

>>> degreeDictionary = {}
>>> for el in monteverdi.recurse():
...    if isinstance(el, roman.RomanNumeral):
...         print(f'{el.figure} {el.key}')
...         for p in el.pitches:
...              degree, accidental = el.key.getScaleDegreeAndAccidentalFromPitch(p)
...              if accidental is None:
...                   degreeString = str(degree)
...              else:
...                   degreeString = str(degree) + str(accidental.modifier)
...              if degreeString not in degreeDictionary:
...                   degreeDictionary[degreeString] = 1
...              else:
...                   degreeDictionary[degreeString] += 1
...              degTuple = (str(p), degreeString)
...              print(degTuple)
    vi F major
    ('D5', '6')
    ('F5', '1')
    ('A5', '3')
    V[no3] F major
    ('C5', '5')
    ('G5', '2')
    I F major
    ('F4', '1')
    ('A4', '3')
    ('C5', '5')
    ...
    V6 g minor
    ('F#5', '7#')
    ('A5', '2')
    ('D6', '5')
    i g minor
    ('G4', '1')
    ('B-4', '3')
    ('D5', '5')
    ...

Now if we'd like we can get a Histogram of the data.
It's a little complex, but worth seeing in full:

>>> import operator
>>> histogram = graph.primitives.GraphHistogram()
>>> i = 0
>>> data = []
>>> xLabels = []
>>> values = []
>>> ddList = list(degreeDictionary.items())
>>> for deg,value in sorted(ddList, key=operator.itemgetter(1), reverse=True):
...    data.append((i, degreeDictionary[deg]), )
...    xLabels.append((i+.5, deg), )
...    values.append(degreeDictionary[deg])
...    i += 1
>>> histogram.data = data


These commands give nice labels for the data; optional:

>>> histogram.setIntegerTicksFromData(values, 'y')
>>> histogram.setTicks('x', xLabels)
>>> histogram.setAxisLabel('x', 'ScaleDegree')

Now generate the histogram:

>>> #_DOCS_HIDE histogram.process()

.. image:: images/romanTranslatePitchDistribution.*
    :width: 600


OMIT_FROM_DOCS

>>> x = converter.parse('romantext: m1 a: VI')
>>> [str(p) for p in x[roman.RomanNumeral].first().pitches]
['F5', 'A5', 'C6']

>>> x = converter.parse('romantext: m1 a: vi')
>>> [str(p) for p in x[roman.RomanNumeral].first().pitches]
['F#5', 'A5', 'C#6']

>>> [str(p) for p in
...  converter.parse('romantext: m1 a: vio'
...                  )[roman.RomanNumeral].first().pitches]
['F#5', 'A5', 'C6']
    )annotationsN)bar)base)common)OffsetQL)environment)exceptions21)harmony)key)metadata)meter)note)repeat)roman)	rtObjects)spanner)stream)tiezromanText.translate      ?Fc                      \ rS rSrSrg)RomanTextTranslateException    N__name__
__module____qualname____firstlineno____static_attributes__r       U/home/james-whalen/.local/lib/python3.13/site-packages/music21/romanText/translate.pyr   r          r    r   c                      \ rS rSrSrg)RomanTextUnprocessedToken   r   Nr   r   r    r!   r$   r$      r"   r    r$   c                  6   ^  \ rS rSrSU 4S jjrSS jrSrU =r$ )RomanTextUnprocessedMetadata   c                >   > [         TU ]  " S0 UD6  Xl        X l        g )Nr   )super__init__tagdata)selfr,   r-   keywords	__class__s       r!   r+   %RomanTextUnprocessedMetadata.__init__   s    $8$	r    c                8    U R                    SU R                   3$ )N: )r,   r-   )r.   s    r!   _reprInternal*RomanTextUnprocessedMetadata._reprInternal   s    ((2dii[))r    )r-   r,   ) r6   )returnstr)r   r   r   r   r+   r4   r   __classcell__)r0   s   @r!   r'   r'      s    
* *r    r'   c                   SnU R                  5       u  pE[        U5      S:  a  [        S5      eUS   nUR                  [        R
                  5       GHf  nUR                  U:X  d  M   [        R                  " U5      nU R                  S   Ul        UR                  [        R                  5       GH   nUc  [        S	5      eUR                  (       a  UR                  nO*UR                  b  UR                  R                  nOX(l        UR                  c  Mi  [        R                  " UR                   [        R                  " U5      5      n	S
U	l        [        R                  " UR$                  5      U	l        [        R                  " UR&                  5      U	l        UR)                  X5        GM       X24$    X24$ ! [         a     [        SUR                   S3S-   S-   5      ef = f)z
Given a RomanText token, a Part used as the current container,
and the current Key, return a Measure copied from the past of the Part.

This is used in cases of definitions such as:
m23=m21
N   zEa single measure cannot define a copy operation for multiple measuresr   zFailed to copy measure :zD did you perhaps parse an RTOpus object with romanTextToStreamScore !instead of romanTextToStreamOpus?Battempting to copy a measure but no past key definitions are foundT)getCopyTargetlenr   getElementsByClassr   Measurenumbercopydeepcopy	TypeErrorr   RomanNumeralfollowsKeyChanger   
pivotChordsecondaryRomanNumeralfigurewriteAsChorddurationlyricsreplace)
rtTaggedpkCurrentmtargetNumberunused_targetRepeattargetmPastrnPastnewRNs
             r!   _copySingleMeasurerZ      s    	A )1(>(>(@%L
<1)SU 	U !_F%%fnn5<<6!;MM%(  q)AH..u/A/AB#5\^ ^**%zzH&&2%0044H!)J//;!..t}}X'>E *.E&%)]]6??%CEN#'==#?ELIIf,% C( ;A 6@ ;9  ;1-ell^1=\]9:; ;;s   *G*G+c           	     .   U R                  5       u  p4[        U5      S:X  a  [        S5      eUS   nUS   nU R                  S   U R                  S   -
  Xe-
  :w  a  [        S5      eU R                  S   U:  a  [        S5      e/ nUR	                  [
        R                  5       GH  nUR                  [        XVS-   5      ;   Ga{   [        R                  " U5      n	U R                  S   UR                  -   U-
  U	l        UR                  U	5        [        U	R	                  [        R                  5      5      n
U
 GH   nUc  [        S	5      eUR                   (       a  UR"                  nO*UR$                  b  UR$                  R"                  nOX+l        UR&                  c  Mi  [        R                  " UR(                  [        R                  " U5      5      nS
Ul        [        R                  " UR,                  5      Ul        [        R                  " UR.                  5      Ul        U	R1                  X5        GM     UR                  U:X  d  GM    Xr4$    Xr4$ ! [         a,    [        SR                  UR                  XV5      S-   S-   5      ef = f)z
Given a RomanText token for a RTMeasure, a
Part used as the current container, and the current Key,
return a Measure range copied from the past of the Part.

This is used for cases such as:
m23-25 = m20-22
r;   z5a multiple measure range cannot copy a single measurer   zQboth the source and destination sections need to have the same number of measuresz>the source section cannot overlap with the destination sectionz5Failed to copy measure {0} to measure range {1}-{2}: zCdid you perhaps parse an RTOpus object with romanTextToStreamScore r=   r>   T)r?   r@   r   rC   rA   r   rB   rangerD   rE   rF   formatappendlistr   rG   rH   r   rI   rJ   rK   rL   rM   rN   rO   )	rtMeasurerQ   rR   targetNumbersrU   targetStart	targetEndmeasuresrW   rS   allRNsrX   rY   s                r!   _copyMultipleMeasuresrf      sb    *3)@)@)B&M
=Q)*abb"Ka IY--a00I4KK)_a 	aY&)LN 	N H%%fnn5<<5!m<<;MM%( !''*U\\9KGAHOOA!..u/A/ABCF #5\^ ^**%zzH&&2%0044H!)J//;!..t}}X'>E *.E&%)]]6??%CEN#'==#?ELIIf,% !( <<9$K 6J C  ;1KRRk>[\ ::; ;;s   I6Jc                "   [        U [        5      (       a-  [        R                  " U 5      n [        R                  " U 5      nOU R                  5       nUR                  R                  nUR                  S:X  a  UR                  5       nUS-   nX4$ )a  
Given an RTKey specification, return the Key and a string prefix based
on the tonic:

>>> romanText.translate._getKeyAndPrefix('c')
(<music21.key.Key of c minor>, 'c: ')
>>> romanText.translate._getKeyAndPrefix('F#')
(<music21.key.Key of F# major>, 'F#: ')
>>> romanText.translate._getKeyAndPrefix('Eb')
(<music21.key.Key of E- major>, 'E-: ')
>>> romanText.translate._getKeyAndPrefix('Bb')
(<music21.key.Key of B- major>, 'B-: ')
>>> romanText.translate._getKeyAndPrefix('bb')
(<music21.key.Key of b- minor>, 'b-: ')
>>> romanText.translate._getKeyAndPrefix('b#')
(<music21.key.Key of b# minor>, 'b#: ')
>>> romanText.translate._getKeyAndPrefix('Bbb')
(<music21.key.Key of B-- major>, 'B--: ')
minorr3   )

isinstancer8   r   "convertKeyStringToMusic21KeyStringKeygetKeytonicnamemodelower)rtKeyOrStringk	tonicNameprefixs       r!   _getKeyAndPrefixru   /  st    ( -%%>>}MGGM"  "IvvOO%	F9r    z)dict[tuple[str, str], roman.RomanNumeral]_rnKeyCachec                      \ rS rSrSrSS j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 rSS.       SS jjr        SS jrS rSrg)PartTranslatoriS  z
A refactoring of the previously massive romanTextToStreamScore function
to allow for more fine-grained testing (eventually), and to
get past the absurdly high number of nested blocks (the previous translator
was written under severe time constraints).
Nc                V   Uc  [         R                  " 5       nXl        [        R                  " 5       U l        [        U l        [        R                  " S5      U l
        U R                  U l        SU l        S U l        SU l        S U l        S U l        SU l        SU l        ['        S5      u  U l        nSU l        [,        R.                  R0                  U l        [,        R.                  R0                  U l        0 U l        S U l        S U l        SU l        SU l        SU l         SU l!        g )Nz4/4Fr   TCr6           )"r   Metadatamdr   PartrQ   ROMANTEXT_VERSIONromanTextVersionr   TimeSignature	tsCurrenttsAtTimeOfLastChordtsSetlastMeasureTokenlastMeasureNumber
previousRnkeySigCurrentsetKeySigFromFirstKeyTokenfoundAKeySignatureSoFarru   rR   prefixLyricr   Minor67Default
CAUTIONARY
sixthMinorseventhMinorrepeatEndingscurrentMeasureTokenpreviousChordInMeasurepivotChordPossiblenumberOfAtomsInCurrentMeasuresetKeyChangeTokencurrentOffsetInMeasure)r.   r}   unused_prefixLyrics      r!   r+   PartTranslator.__init__[  s    :""$B 1 ,,U3#'>> 
 $!"!*.'',$,<S,A))..99!00;; $( &*#"'-.*!&&)#r    c           	     z   U H  n U R                  U5        M     U R                  nUR                  5         [        U5        UR                  SS9  UR                  SS9  [        X@R                  5        U$ ! [         a8    [        R                  " 5       n[	        SUR
                   SU S3SU 3-   5      ef = f)NzAt line z for token z, zan exception was raised: 
T)inPlace)translateOneLineToken	Exception	traceback
format_excr   
lineNumberrQ   coreElementsChangedfixPickupMeasure	makeBeamsmakeAccidentals_addRepeatsFromRepeatEndingsr   )r.   tokenstokentracebackMessagerQ   s        r!   translateTokensPartTranslator.translateTokens}  s    EH**51  FF		D!	$'$Q(:(:;  H#,#7#7#9 1u//0E7"E34D3EFGH HHs   A88AB:c                "   U R                   nUR                  5       (       aH  [        R                  (       a!  [	        U[
        R                  5      (       d   eU R                  U5        g
UR                  5       (       a  UR                  SUR                  5        g
UR                  5       (       a  UR                  SUR                  5        g
UR                  5       (       a  UR                  SUR                  5        g
UR                  5       (       a  UR                  SUR                  5        g
UR                  5       (       a  UR                  SUR                  5        g
UR                  5       (       a  UR                  SUR                  5        g
UR!                  5       (       a  UR                  SUR                  5        g
UR#                  5       (       a.   [$        R&                  " UR                  5      U l        SU l        g
UR5                  5       (       a  U R7                  U5        g
UR9                  5       (       d  UR;                  5       (       a  U R=                  U5        g
UR?                  5       (       a   [A        UR                  5      U l!        g
[	        U[
        RF                  5      (       a<  [I        URJ                  UR                  5      nU RL                  RO                  U5        g
[Q        U5      nU RL                  RO                  U5        g
! [,        R.                   a&    [0        R3                  SUR                  < 35         g
f = f! [D         a&    [0        R3                  S	UR                  < 35         g
f = f)z
Translates one line token and set the current settings.

A token in this case consists of an entire line's worth.
It might be a token such as 'Title: Neko Funjatta' or
a composite token such as 'm23 b4 IV6'
titlealternativeTitlecomposermovementNumberanalystproofreaderFz#Could not parse TimeSignature tag: zCould not parse RTVersion tag: N))r}   	isMeasuretTYPE_CHECKINGri   r   	RTMeasuretranslateMeasureLineTokenisTitleaddr-   isWorkisPiece
isComposer
isMovement	isAnalystisProofreaderisTimeSignaturer   r   r   r   r	   Music21ExceptionenvironLocalwarnisKeySignatureparseKeySignatureTagisSixthMinorisSeventhMinorsetMinorRootParse	isVersionfloatr   
ValueErrorRTTaggedr'   r,   rQ   r^   r$   )r.   	lineTokenr}   otherMetadataunprocesseds        r!   r   $PartTranslator.translateOneLineToken  s    WW   !)Y-@-@AAAA**95  FF7INN+FF%y~~6  FF%y~~6!!##FF:y~~.!!##FF#Y^^4  ""FF9inn-$$&&FF=)..1&&((\!&!4!4Y^^!D"
 %%''%%i0##%%)A)A)C)C""9-  ""X(-inn(=% 	9#5#5668	WMFFMM-( 4I>KFFMM+&/  00 \!!$G	GY"Z[\  X!!$CINNCU"VWXs$   ,L! M !7MM-NNc                D   UR                   R                  5       nUS:X  a  [        R                  R                  nOUS:X  a  [        R                  R
                  nOUS:X  a  [        R                  R                  nOUS;   a  [        R                  R                  nO`US:X  aK  UR                  5       (       a  [        R                  R                  nO*[        R                  R
                  nO[        SU< 35      eUR                  5       (       a  X0l
        gX0l        g)aX  
Set Roman Numeral parsing standards from a token.

>>> pt = romanText.translate.PartTranslator()
>>> pt.sixthMinor
<Minor67Default.CAUTIONARY: 2>

>>> tag = romanText.rtObjects.RTTagged('SixthMinor: Flat')
>>> tag.isSixthMinor()
True
>>> pt.setMinorRootParse(tag)
>>> pt.sixthMinor
<Minor67Default.FLAT: 4>

Harmonic sets to FLAT for sixth and SHARP for seventh

>>> for config in 'flat sharp quality cautionary harmonic'.split():
...     tag = romanText.rtObjects.RTTagged('Seventh Minor: ' + config)
...     pt.setMinorRootParse(tag)
...     print(pt.seventhMinor)
Minor67Default.FLAT
Minor67Default.SHARP
Minor67Default.QUALITY
Minor67Default.CAUTIONARY
Minor67Default.SHARP

>>> tag = romanText.rtObjects.RTTagged('Sixth Minor: harmonic')
>>> pt.setMinorRootParse(tag)
>>> print(pt.sixthMinor)
Minor67Default.FLAT


Unknown settings raise a `RomanTextTranslateException`

>>> tag = romanText.rtObjects.RTTagged('Seventh Minor: asdf')
>>> pt.setMinorRootParse(tag)
Traceback (most recent call last):
music21.romanText.translate.RomanTextTranslateException:
    Cannot parse setting vi or vii parsing: 'asdf'
flatsharpquality)courtesy
cautionaryharmonicz(Cannot parse setting vi or vii parsing: N)r-   rp   r   r   FLATSHARPQUALITYr   r   r   r   r   )r.   rP   tDatatEnums       r!   r    PartTranslator.setMinorRootParse  s    R ##%F?((--Eg((..Ei((00E00((33Ej $$&&,,11,,22-:5)DF F   ""#O %r    c                P   U R                   nUR                  S   U R                  S-   :  =(       a    U R                  SLn[	        UR                  5      S:H  =(       a    UR
                  n[	        UR                  5      S:  nUR                  b  gUR                  b  gU(       a  U R                  U5        U(       a  UR                  5         [        XU R                  5      u  o`l        UR                  U5        UR                  U l        Xl        UR                  [        R                   5      nU(       a  US   U l        ggU(       a  UR                  5         [#        XU R                  5      u  ol        UR%                  U5        US   R                  U l        Xl        US   R                  [        R                   5      nU(       a  US   U l        ggU R'                  U5      nUR(                  R*                  S:X  a  U R-                  U5        UR                  U5        g)z
Translate a measure token consisting of a single line such as::

    m21 b3 V b4 C: IV

Or it might be a variant measure, or a copy instruction.
r   r;   N)rQ   rC   r   r   r@   isCopyDefinitionvariantNumbervariantLetterfillToMeasureTokenr   rZ   rR   
coreAppendr   rA   r   rG   rf   r^   translateSingleMeasurerM   quarterLengthfillMeasureFromPreviousRn)	r.   measureLineTokenrQ   skipsPriorMeasuresisSingleMeasureCopyisMultipleMeasureCopyrS   romansrd   s	            r!   r   (PartTranslator.translateMeasureLineToken  s    FF/66q9D<R<RUV<VV A$(OO4$? 	"#3#:#:;q@  E#3#D#D 	!$%5%<%<!=!A
 ))5 ))5 
 ##$45 !!#12Bt}}UA}LLO%&XXD"$4!))%*<*<=F"(*  #!!#&;<LQUQ^Q^&_#HmHHX%-b\%8%8D"$4!b\44U5G5GHF"(*  ++,<=Azz''1,..q1LLOr    c                n   U R                   n[        U R                  S-   UR                  S   5       Hb  n[        R
                  " 5       nX4l        U R                  U5        [        U R                  UU R                  U5        UR                  U5        Md     UR                  S   S-
  U l        Xl        g)zn
Create a series of measures which extend the previous RN until the measure number
implied by `measureToken`.
r;   r   N)rQ   r\   r   rC   r   rB   r    appendMeasureToRepeatEndingsDictr   r   r   )r.   measureTokenrQ   imFills        r!   r   !PartTranslator.fillToMeasureTokenO  s    
 FFt--1<3F3Fq3IJANN$EL**51,T-B-B-2-1-?-?D LL K ".!4!4Q!7!!; ,r    c                   U R                   b  [        R                  " U R                   5      nSUl        [        R                  " U R                  R
                  5      Ul        U R                   R                  c&  [        R                  " S5      U R                   l        OSU R                   R                  l	        [        R                  " S5      Ul        X l         UR                  U5        g g )Nr6   startcontinuestop)r   rD   rE   lyricr   barDurationrM   r   Tietyper^   )r.   r   newRns      r!   r   (PartTranslator.fillMeasureFromPreviousRn`  s    ??&MM$//2EEK!]]4+C+C+O+OPEN""*&)ggg&6#+5##(EI#OLL 'r    c                H   UR                   nUS:X  a  [        R                  " S5      U l        OIUS:X  a  [        R                  " S5      U l        O' [	        U5      n[        R                  " U5      U l        SU l        SU l        g! [
         a    [        SU< 35      ef = f)	a  
Parse a key signature tag which has already been determined to
be a key signature.

>>> tag = romanText.rtObjects.RTTagged('KeySignature: -4')
>>> tag.isKeySignature()
True
>>> tag.data
'-4'

>>> pt = romanText.translate.PartTranslator()
>>> pt.keySigCurrent is None
True
>>> pt.setKeySigFromFirstKeyToken
True
>>> pt.foundAKeySignatureSoFar
False

>>> pt.parseKeySignatureTag(tag)
>>> pt.keySigCurrent
<music21.key.KeySignature of 4 flats>
>>> pt.setKeySigFromFirstKeyToken
False
>>> pt.foundAKeySignatureSoFar
True

>>> tag = romanText.rtObjects.RTTagged('KeySignature: xyz')
>>> pt.parseKeySignatureTag(tag)
Traceback (most recent call last):
music21.romanText.translate.RomanTextTranslateException:
    Cannot parse key signature: 'xyz'
r6   r   Bbr   zCannot parse key signature: FTN)	r-   r   KeySignaturer   intr   r   r   r   )r.   rP   r-   dataVals       r!   r   #PartTranslator.parseKeySignatureTago  s    B }}2:!$!1!1!!4DT\!$!1!1"!5D[d)%(%5%5g%>" +0''+$	  [14PQUPX2YZZ[s   &B B!c                4   Xl         [        R                  " 5       nUR                  S   Ul        [	        XU R
                  5        UR                  S   U l        Xl        U R                  (       d  U R                  Ul
        SU l        U R                  (       d0  U R                  b#  UR                  SU R                  5        SU l        SU l        SU l        SU l        [#        UR$                  5      U l        SU l        [+        UR$                  5       H&  u  p4X0R&                  S-
  :H  nU R-                  XBUS9  M(     U R                  b<  U R                  R.                  R0                  U R                  -
  U R2                  l        UR5                  5         U$ )zX
Given a measureToken, return a `stream.Measure` object with
the appropriate atoms set.
r   TNr{   Fr;   isLastAtomInMeasure)r   r   rB   rC   r   r   r   r   r   r   timeSignaturer   r   insertr   r   r   r@   atomsr   r   	enumeratetranslateSingleMeasureAtomr   r   r   r   )r.   r   rS   r   ar  s         r!   r   %PartTranslator.translateSingleMeasure  sT   
 $0 NN&&q)($:L:LM!-!4!4Q!7 ,zz"nnAODJ..43E3E3QHHQ**+.2D+&)#&*#"'-01C1C-D*!&l001DA#$(J(JQ(N#N++AFY+Z 2
 >>%-1^^-G-G-U-U262M2M.NDOO)	r    Fr  c               @   [        U[        R                  5      (       d.  U R                  SL a  [        U[        R                  5      (       al  U R                  U5        UR                  S::  a  UR                  SU R                  5        O&UR                  U R                  U R                  5        SU l        g
[        U[        R                  5      (       aX   UR                  5       nUR                  S::  a  UR                  SU5        OUR                  U R                  U5        SU l        g
[        U[        R                  5      (       a  U R                  U5        g
[        U[        R$                  5      (       Ga   UR'                  U R(                  5      nU R,                  c  U R.                  b  US:  a  [0        R2                  " U R.                  5      nXVl        SUl        U R.                  R8                  c&  [8        R:                  " S5      U R.                  l        OSU R.                  R8                  l        [8        R:                  " S5      Ul        X`l        X`l        UR                  SU5        SU l        XPl	        g
[        U[        R@                  5      (       Ga  U R(                  U l!        [D        RF                  " 5       nUR                  U R                  U5        [H        RJ                  " 5       nU R>                  SL a  U R,                  c  ObU R,                  RM                  U5      n	U R                  U	-
  n
U
S::  a"  [        SU R"                  R                    35      eXR,                  l        SU l'        UR                  U R                  U5        Xl        Xl        SU l        g
g
[        U[        RP                  5      (       a  U RS                  XU R                  5        g
[        U[        RT                  5      (       Ga  [        U[        RV                  5      (       ai  U(       ab  [X        RZ                  " SS9Ul.        U R(                  b;  UR_                  UR\                  U R(                  R`                  R4                  5        g
g
U R                  S:X  aa  [        U[        Rb                  5      (       a  [X        RZ                  " SS9Ul2        g
[g        U5      nUR                  U R                  U5        g
U R(                  b  U R(                  R`                  R4                  U R                  :X  aa  [        U[        RV                  5      (       a  [X        RZ                  " SS9Ul.        g
[g        U5      nUR                  U R                  U5        g
[g        U5      nUR                  U R                  U5        g
[g        U5      nUR                  U R                  U5        g
! [        R                  [        4 a0    [        SUR                    SU R"                  R                    35      ef = f! [         aM    [        SSUR                    3-   S	R+                  U R(                  U R"                  R                   5      -   5      ef = f)z
Translate a single atom in a measure token.

`a` is the Atom
`m` is a `stream.Measure` object.

Uses coreInsert and coreAppend methods, so must have `m.coreElementsChanged()`
called afterward.
Fr;   r   Tzcannot get key from 	 in line z#cannot properly get an offset from z
beat data z#under timeSignature {0} in line {1}Nr6   r   r   r    too many notes in this measure: end	direction)4ri   r   RTKeyr   RTAnalyticKeysetAnalyticKeyrC   
coreInsertrR   r   RTKeySignaturegetKeySignaturer	   r   r   r   srcr   RTBeat	getOffsetr   r]   r   r   rD   rE   r   r   r   r   r   r   	RTNoChordr   r
   NoChordr   RestgetOffsetBySiter   RTChordprocessRTChordRTRepeatRTRepeatStopr   RepeatrightBarlinesetElementOffsetr   RTRepeatStartleftBarliner$   )r.   r
  rS   r  thisSig	newOffset
firstChordcsrn	oPreviousnewQLrtts               r!   r	  )PartTranslator.translateSingleMeasureAtom  s     q)//**00E9"1i&=&=>>" xx1}Q.T88$--H+/D(93344[++- xx1}Q(T88'B+/D(92233"9++,,7KK7	 ++33!A!]]4??;
+4(#%
 ??&&.*-'''*:DOO'/9DOO'',!$
",.8+Q
+&+D#*3'9..//'+~~D$"BLL44b9B&&%/..6 $ ; ; K KA NI 77)CEz9>t?W?W?[?[>\]_ _@E//=#% T88"=.0+"$*/' 0" 9,,--d&A&AB9--..!Y33449L "%e!<>>-&&(B(B(P(P . ,,1a!8!899$'JJ$AAM3A6CLL!<!<cB..,22@@DD_D__a!7!788%(ZZ%%@AN3A6CLL!<!<cB/2T88#> ,A.CLL44c:I !11:> [1*155'4;S;S;W;W:XY[ [[$  719"155'*+;BB0044667 77s   W9 Y 9A
YAZc                p   U R                   U l         UR                  nX@R                  R                  4n[
        (       a(  U[        ;   a  [        R                  " [        U   5      nOY[        R                  " U[        R                  " U R                  5      U R                  U R                  S9nSUl        U[        U'   U R                  SL a  SUl        SU l        OSUl         U R"                  SL a  U R$                  c  OWU R$                  R'                  U5      nX7-
  nUS::  a"  [)        SU R*                  R                   35      eXR$                  l        UR/                  U R0                  UR                  -   5        SU l        UR3                  X65        X`l        X`l        SU l        gU R$                  =R6                  SU R0                  -   UR                  -   -  sl        X`R$                  l        SU l        SU l        g! [        R                    a    [        R                  " 5       n GNLf = f)	z 
Process a single RTChord atom.
)r   r   TFNr   r  r6   z//)r   r   r  rR   tonicPitchNameWithCaseUSE_RN_CACHErv   rD   rE   r   rG   r   r   rL   r   rH   RomanNumeralExceptionr   r   r  r   r   r   addLyricr   r  r   r   rI   )	r.   r
  rS   currentOffsetaSrc
cacheTupler,  r-  r.  s	            r!   r   PartTranslator.processRTChordI  s    $(>> 2	&55D
  D DEJ|
k 9 ]];z#:; ''(,dmm(D37??595F5F*
 #'*,J'. %%-&*#).&&+#
 ""e+**2 77GGJ	%1A:5:4;S;S;W;W:XY[ [<A++9KK((15501!DLL+*,' O&*D#''--8H8H1H1551PP-57''2!D&+D#5 ** 	&##%B	&s   CH  H )H54H5c                     [        U5      u  U l        nU =R                  U-  sl        SU l        g!   [        SUR                   SU R
                  R                   35      e= f)zb
Indicates a change in the analyzed key, not a change in anything
else, such as the keySignature.
zcannot get analytic key from r  TN)ru   rR   r   r   r  r   r   )r.   r
  pls      r!   r  PartTranslator.setAnalyticKey  sl    
	` 0 3DM2" "&	`-/wi@X@X@\@\?]^` `s	   (2 1A#)r   r   r   rR   r   r   r   r}   r   rQ   r   r   r   r   r   r   r   r   r   r   r   r   r   N)r   rtObjects.RTTagged)rP   r>  )r   rtObjects.RTMeasure)r   r?  )r   stream.Measurer7   None)r
  zrtObjects.RTAtomrS   r@  r  boolr7   rA  )r
  zrtObjects.RTChordrS   r@  r6  r   r7   rA  )r   r   r   r   __doc__r+   r   r   r   r   r   r   r   r   r	  r   r  r   r   r    r!   rx   rx   S  s     *D$B'H>&@:x-" .,`"R %*C;C; C;
 "C; 
C;LU,U, U,  	U,
 
U,n&r    rx   c                v   [        U [        5      (       a'  [        R                  " 5       nUR	                  U 5      nOU nUc  [
        R                  " 5       nOUn[        R                  " 5       nUR                  SU5        [        U5      nUR                  UR                  5      nUR                  SU5        U$ )z
The main processing module for single-movement RomanText works.

Given a romanText handler or string, return or fill a Score Stream.
r   )ri   r8   r   RTFilereadstrr   Scorer   r|   r  rx   r   r   )	rtHandlerinputM21rtftokenedRtHandlersr}   	partTransrQ   s           r!   romanTextToStreamScorerN    s     )S!! ;;y1$ LLN 
			BHHQOr"I!!"2"9"9:AHHQNHr    r;                        )r
  bcdefghc                6   U R                   (       d  gU R                   S   Ul        U R                    Hc  nUb  US:X  a  M  U[        ;  a  [        SU 35      e[        U   nXR;  a  / X%'   Uc  U R                  S   U4nOX14nX%   R                  U5        Me     g)a@  
Takes an RTMeasure object (which might represent one or more
measures; but currently only one) and a music21 stream.Measure object and
store it as a tuple in the repeatEndings dictionary to mark where the
translator should later mark for adding endings.

If the optional measureNumber is specified, we use that rather than the
token number to add to the dict.

This does not yet work for skipped measures.

>>> rtm = romanText.rtObjects.RTMeasure('m15a V6 b1.5 V6/5 b2 I b3 viio6')
>>> rtm.repeatLetter
['a']
>>> rtm2 = romanText.rtObjects.RTMeasure('m15b V6 b1.5 V6/5 b2 I')
>>> rtm2.repeatLetter
['b']
>>> repeatEndings = {}
>>> m1 = stream.Measure()
>>> m2 = stream.Measure()
>>> romanText.translate.appendMeasureToRepeatEndingsDict(rtm, m1, repeatEndings)
>>> repeatEndings
{1: [(15, <music21.stream.Measure 0a offset=0.0>)]}
>>> romanText.translate.appendMeasureToRepeatEndingsDict(rtm2, m2, repeatEndings)
>>> repeatEndings[1], repeatEndings[2]
([(15, <music21.stream.Measure 0a offset=0.0>)],
 [(15, <music21.stream.Measure 0b offset=0.0>)])
>>> repeatEndings[2][0][1] is m2
True
Nr   r6   zImproper repeat letter: )repeatLetternumberSuffixletterToNumDictr   rC   r^   )rtMeasureObjrS   r   measureNumberrlrepeatNumbermeasureTuples          r!   r   r     s    F $$!..q1AN'':r_$-0H.MNN&r*,*,M' (//2A6L)-L#**<8 (r    c                   / nU  H  nSnSn/ nX    HW  u  pgUc  UnUnUR                  U5        M  XdS-   :  a  XR4nUR                  U5        UnUnU/nMD  UR                  U5        UnMY     Uc  Mm  XR4nUR                  U5        M     U$ )a  
take repeatEndings, which is a dict of integers (repeat ending numbers) each
holding a list of tuples of measure numbers and measure objects that get this ending,
and return a list where contiguous endings should appear.  Each element of the list is a
two-element tuple, where the first element is a list of measure objects that should have
a bracket and the second element is the repeat number.

Assumes that the list of measure numbers in each repeatEndings array is sorted.

For the sake of demo and testing, we will use strings instead of measure objects.

>>> repeatEndings = {1: [(5, 'm5a'), (6, 'm6a'), (17, 'm17'), (18, 'm18'),
...                      (19, 'm19'), (23, 'm23a')],
...                  2: [(5, 'm5b'), (6, 'm6b'), (20, 'm20'), (21, 'm21'), (23, 'm23b')],
...                  3: [(23, 'm23c')]}
>>> print(romanText.translate._consolidateRepeatEndings(repeatEndings))
[(['m5a', 'm6a'], 1), (['m17', 'm18', 'm19'], 1), (['m23a'], 1),
 (['m5b', 'm6b'], 2), (['m20', 'm21'], 2), (['m23b'], 2), (['m23c'], 3)]
Nr;   )r^   )	r   
returnListendingNumberstartMeasureNumberr   measureListmeasureNumberUnderEndingmeasureObjectmyTuples	            r!   _consolidateRepeatEndingsrn    s    * J%! 7D7R3$!)%="$<!""=1),AA&5!!'*%="$<!,o""=1$<! 8S )"1Gg&) &, r    c                   [        U5      nU H{  nUS   US   pT[        R                  " XES9nUS   R                  U 5      nU R	                  Xv5        US:X  d  MM  US   R
                  b  M_  [        R                  " SS9US   l        M}     g)zG
Given a Stream and the repeatEndings dict, add repeats to the stream.
r   r;   )rC   r   Nr  r  )rn  r   RepeatBracketr  r  r$  r   r#  )rL  r   consolidatedRepeatsrepeatEndingTuplerj  rh  rbrbOffsets           r!   r   r   7  s     4MB0$5a$8:KA:N\"";Dq>11!4 	
12++3/2zzE/JB, 1r    c                d   U R                  S5      nUc  gUR                  [        R                  [        R
                  /5      nU(       d  gUS   R                  S:X  a  gUS   R                  nU H)  nUR                  U:  a  M  UR                  U-
  Ul        M+     X1l        U  H*  nUR                  S:  d  M  U=R                  U-  sl        M,     U R                  [        R                  5      R                  5       nXQL a  gUR                  [        R                  [        R
                  /5      R                  5       nU(       a  UR                  R                  U:  a  UR                  R                  nUR                  =R                  Xs-
  -  sl        Xs-
  Ul        [        R                  R!                  U SS5         [#        U 5      nSn	X   ULa;  X   R%                  U X   R                  UR                  -
  5        U	S-  n	X   ULa  M;  SSS5        ggg! , (       d  f       g= f)a>  
Fix a pickup measure if any.

We determine a pickup measure by being measure 0 and not having an RN
object at the beginning.  Will also pad the last measure right and
cut the duration of the final chord to match.

Demonstration: an otherwise incorrect part

>>> p = stream.Part()
>>> m0 = stream.Measure()
>>> m0.number = 0
>>> k0 = key.Key('G')
>>> m0.insert(0, k0)
>>> m0.insert(0, meter.TimeSignature('4/4'))
>>> m0.insert(3, roman.RomanNumeral('I', k0, quarterLength=1.0))
>>> m1 = stream.Measure()
>>> m1.number = 1
>>> m1.append(roman.RomanNumeral('V', k0, quarterLength=4.0))
>>> m2 = stream.Measure()
>>> m2.number = 2
>>> m2.append(roman.RomanNumeral('I', k0, quarterLength=4.0))
>>> p.insert(0, m0)
>>> p.insert(4, m1)
>>> p.insert(8, m2)

After running fixPickupMeasure()

>>> romanText.translate.fixPickupMeasure(p)
>>> p.show('text')
{0.0} <music21.stream.Measure 0 offset=0.0>
    {0.0} <music21.key.Key of G major>
    {0.0} <music21.meter.TimeSignature 4/4>
    {0.0} <music21.roman.RomanNumeral I in G major>
{1.0} <music21.stream.Measure 1 offset=1.0>
    {0.0} <music21.roman.RomanNumeral V in G major>
{5.0} <music21.stream.Measure 2 offset=5.0>
    {0.0} <music21.roman.RomanNumeral I in G major>

>>> m0.paddingLeft
3.0
>>> m2.paddingRight
1.0
>>> m2[roman.RomanNumeral].last().duration
<music21.duration.Duration 3.0>
r   NautoSortFr   r;   )measurerA   r   rG   r
   r  offsetpaddingLeftr   rB   lastrM   r   paddingRightr   
classToolstempAttributer_   setOffsetBySite)

partObjectm0	rnObjectsleftPaddingelmLastlastRNcurLastLengthpartElementsr   s
             r!   r   r   I  s   ` 
		A	B	z%%u'9'97??&KLI|aA,%%K99{"		K/BI	 
 !N99q=II$I  ))&..9>>@E{%%u'9'97??&KLQQSF&////+=44%%)DD%*8,,ZUK
+LA/.//
0<0F0FI[I[0[]Q	 /.	 LK >v
 LKs   AH!!
H/c                R   [        U [        5      (       a&  [        R                  " 5       nUR	                  U 5      n U R                  5       (       aO  Uc  [        R                  " 5       nOUnU R                  SS9nU H  nUR                  [        U5      5        M     U$ [        XS9$ )aq  
The main processing routine for RomanText objects that may or may not
be multi movement.

Takes in a romanText.rtObjects.RTFile() object, or a string as rtHandler.

Runs `romanTextToStreamScore()` as its main work.

If inputM21 is None then it will create a Score or Opus object.

Return either a Score object, or, if a multi-movement work is defined, an
Opus object.
T)duplicateHeader)rI  )ri   r8   r   rE  rF  definesMovementsr   OpussplitByMovementr^   rN  )rH  rI  rJ  rL  handlerBundlesr\  s         r!   romanTextToStreamOpusr    s     )S!! KK	*	!!##AA"2242HA HH+A./   %iCCr    c                  6    \ rS rSrSrS rS rS rS rS r	Sr
g	)
TestSlowi  z7
These tests are currently too slow to run every time.
c                    SSK Jn  UR                   HD  n[        R                  " 5       nUR                  U5      n[        U5      nUR                  5         MF     g Nr   	testFiles)music21.romanTextr  ALLr   rE  rF  rN  showr.   r  tfrJ  rthrL  s         r!   testExternalATestSlow.testExternalA  sA    /--B""$C++b/C&s+AFFH	  r    c                   SSK Jn  UR                   HD  n[        R                  " 5       nUR                  U5      n[        U5      nUR                  5         MF     [        UR                  5      nU R                  UR                  R                  S5        U R                  UR                  R                  S5        [        UR                  5      nU R                  UR                  R                  S5        U R                  UR                  R                  S5        [        UR                  5      nU R                  UR                  R                  S5        g )Nr   r  zHeinrich Schutzz4Warum toben die Heiden, Psalmen Davids no. 2, SWV 23z
J. S. BachzAus meines Herzens GrundezClaudio Monteverdi)r  r  r  r   rE  rF  r  r  rN  swv23assertEqualr   r   r   riemenschneider001monteverdi_3_13r  s         r!   
testBasicATestSlow.testBasicA  s    /--B""$C++b/C%c*AFFH   #9??3,,.?@ 	))+ab"9#?#?@,,l;))+FG"9#<#<=,,.BCr    c                   SSK Jn  [        UR                  5      nUR                  S   R                  [        R                  5      nUS   R                  [        R                  5      R                  5       nU R                  UR                   Vs/ s H  n[        U5      PM     sn/ SQ5        U R                  [        UR                  5      S5        US   R                  [        R                  5      S   nU R                  [        UR                  5      S5        US   R                  [        R                  5      S   nU R                  [        UR                  5      S5        US   R                  [        R                  5      S   nU R                  [        UR                  5      S5        US   R                  [        R                  5      S   nU R                  [        UR                  5      S5        US   R                  [        R                  5      S   nU R                  [        UR                  5      S5        [        UR                  5      nUR                  S   R                  [        R                  5      nS nS nS n	S n
S nS nU H{  nUR                   S	:X  a  UnM  UR                   S
:X  a  UnM+  UR                   S:X  a  Un	M?  UR                   S:X  a  Un
MS  UR                   S:X  a  UnMg  UR                   S:X  d  My  UnM}     UR                  [        R                  5      S   nU R                  [        UR                  5      S5        UR                  [        R                  5      S   nU R                  [        UR                  5      S5        U
R                  [        R                  5      S   nU R                  [        UR                  5      S5        U
R                  [        R                  5      S   nU R                  [        UR                  5      S5        UR                  [        R                  5      S   nU R                  [        UR                  5      S5        UR                  [        R                  5      S   nU R                  [        UR                  5      S5        UR                  [        R                  5      S   nU R                  [        UR                  5      S5        UR                  [        R                  5      S   nU R                  [        UR                  5      S5        U	R                  [        R                  5      R                  5       nU R                  [        UR                  5      S5        UR                  [        R                  5      R                  5       nU R                  [        UR                  5      S5        g s  snf )Nr   r  r;   )D5zF#5A5Vr   rO  rP  )   *   +   1   2   3   IVIiizV/ii)r  r  rN  r  partsrA   r   rB   r   rG   firstr  pitchesr8   rK   r  rC   )r.   r  rL  mStreamrn1xrn2m1am2am3am1bm2bm3brS   r,  s                  r!   testMeasureCopyingATestSlow.testMeasureCopyingA  sk   /"9??3''!*//?aj++E,>,>?EEG#++6+Q#a&+68KLSZZ#.aj++E,>,>?BSZZ#. aj++E,>,>?BSZZ#.aj++E,>,>?BSZZ#.aj++E,>,>?BSZZ#.aj++E,>,>?BSZZ#. #9#<#<=''!*//?Axx2~RRRRR  ##E$6$67:RYY.##E$6$67:RYY-##E$6$67:RYY.##E$6$67:RYY-##E$6$67:RYY-##E$6$67:RYY.##E$6$67:RYY-##E$6$67:RYY.##E$6$67==?RYY0##E$6$67==?RYY0A 7s   W2c                \   SSK Jn  SSKJn  UR	                  UR
                  5      nUR                  S5      nUR                  5       R                  [        R                  5      nU R                  US   R                  S5        U R                  [        US   R                  5      S5        g )Nr   	converterr     r;   IIIzd minor)music21r  r  r  parser  rw  flattenrA   r   rG   r  rK   r8   r   )r.   r  r  rL  m25r,  s         r!   testMeasureCopyingBTestSlow.testMeasureCopyingB4  sy    %/OOI556iim[[]--e.@.@AAu-RUYY3r    c                   SSK Jn  [        UR                  5      nU R	                  UR
                  S   R                  R                  S5        U R	                  UR
                  S   R                  R                  S5        U R	                  UR
                  S   R                  R                  S5        U R	                  UR
                  S   R                  R                  S5        U R	                  UR
                  S   R                  R                  S5        U R	                  UR
                  S   R                  R                  S5        SS	K	J
n  UR                  UR                  5      nU R                  S
UR                  ;   5        U R	                  [        UR
                  5      S5        UR                  UR                  5      nU R                  [!        U["        R$                  5      5        g )Nr   r  1Mozartr;   2rO  3r  r  rP  )r  r  r  
mozartK279r  scoresr   r   r   r  r  r  
assertTrueclassesr@   r  ri   r   rG  )r.   r  or  rL  s        r!   testOpusTestSlow.testOpusC  s`   /!)"6"67!--<<cB!--66A!--<<cB!--66A!--<<cB!--66A 	&OOI001!))+,QXX* OOI889
1fll34r    r   N)r   r   r   r   rC  r  r  r  r  r  r   r   r    r!   r  r    s#    D.G1R45r    r  c                      \ rS rSrS rS rS rS rS rS 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rg)TestiY  c                   ^ ^ SSK Jn  [        UR                  5      n[	        U[
        R                     5      mUU 4S jnU" SS5        U" SS5        U" SS5        U" S	S
5        U" SS5        U" SS5        g )Nr   r  c                x   > TU    nUR                   nTR                  SR                  S U 5       5      U5        g )N c              3  8   #    U  H  oR                   v   M     g 7fr=  )rn   ).0rQ   s     r!   	<genexpr>:Test.testMinor67set.<locals>.pitchEqual.<locals>.<genexpr>b  s     %@iffis   )r  r  join)indexpitchStrch	chPitcheschordsr.   s       r!   
pitchEqual'Test.testMinor67set.<locals>.pitchEqual_  s4    B

ISXX%@i%@@(Kr    zC E- Gr;   zB D FrP  zG B DrQ  zA- C E-rT  zB- D F
   zA C E)r  r  rN  testSetMinorRootParser_   r   rG   )r.   r  rL  r  r  s   `   @r!   testMinor67setTest.testMinor67setZ  so    /"9#B#BCa**+,	L
 	1h1g1g1i 1h2wr    c                   SSK Jn  SnUR                  USS9nUR                  S5      R	                  5       nU R                  UR                  [        R                  5      R                  5       R                  R                  S5        UR                  S5      R	                  5       nU R                  UR                  [        R                  5      R                  5       R                  R                  S5        g )	Nr   r  z6
m1 G: I
m2 I
m3 V D: I
m4 V
m5 G: I
m6-7 = m3-4
m8 I
	romanTextr]   rT  D majorrU  r  r  r  rw  r  r  rA   r   rG   r  r   rn   r.   r  testCaserL  rS   s        r!   testPivotInCopyMultipleTest.testPivotInCopyMultiplek  s    % OOH[O9IIaL  "--e.@.@AGGIMMRRT]^IIaL  "--e.@.@AGGIMMRRT]^r    c                   SSK Jn  SnUR                  USS9nUR                  S5      R	                  5       nU R                  UR                  [        R                  5      R                  5       R                  R                  S5        g)	zN
test whether a chord in a pivot situation outside of copying affects copying
r   r  z7
m1 G: I
m2 V D: I
m3 G: IV
m4 V
m5 I
m6-7 = m4-5
m8 I
r  r  rR  zG majorNr  r  s        r!   testPivotInCopyMultiple2Test.testPivotInCopyMultiple2|  so    
 	& OOH[O9IIaL  "--e.@.@AGGIMMRRT]^r    c                   SSK Jn  SnUR                  USS9nUR                  S5      R	                  5       nU R                  UR                  [        R                  5      R                  5       R                  R                  S5        g )Nr   r  z-
m1 G: I
m2 I
m3 V D: I
m4 G: I
m5 = m3
m6 I
r  r  rS  r  r  r  s        r!   testPivotInCopySingleTest.testPivotInCopySingle  sm    % OOH[O9IIaL  "--e.@.@AGGIMMRRT]^r    c                   Sn[        U5      nUR                  S5      R                  5       nU R                  UR	                  [
        R                  5      R                  5       R                  S5        UR                  S5      R                  5       nU R                  UR	                  [
        R                  5      R                  5       R                  S5        g)z%
test secondary dominants after copy
zG
Time Signature: 4/4
m1 g: i
m2 i6
m3 V7/v
m4 d: i
m5-6 = m2-3
m7 = m3
rS  zE-dominant seventh chordrT  N)	rN  rw  r  r  rA   r   rG   r  pitchedCommonName)r.   testSecondaryInCopyrL  rS   s       r!   testSecondaryInCopyMultiple Test.testSecondaryInCopyMultiple  s    
 ##67IIaL  "--e.@.@AGGI[[3	5IIaL  "--e.@.@AGGI[[3	5r    c                :    SSK Jn  [        UR                  5      ng r  )r  r  rN  r  )r.   r  unused_ss      r!   
testBasicBTest.testBasicB  s    /))*F*FGr    c                l   SSK Jn  UR                  SSS9nUR                  5       R	                  [
        R                  5      R                  5       nU R                  US   R                  S5        U R                  US   R                  S5        U R                  US	   R                  S5        U R                  US
   R                  S5        U R                  US   R                  S5        U R                  US   R                  S5        U R                  US   R                  S5        U R                  US   R                  S5        UR                  5       R	                  [        R                  5      nU R                  US   R                  S5        U R                  US   R                  S5        g )Nr   r  zDm1 KS1 I 
 m2 V6/5 
 m3 I b3 V7 
m4 KS-3 vi 
 m5 a: i b3 V4/2 
 m6 I	romantextr  r  r;   zV6/5rO  rP  V7rQ  virR  r   rS  zV4/2rT  )r  r  r  r  rA   r   rG   r   r  rK   r   r   sharps)r.   r  rL  rnStreamrnStreamKeys        r!   testRomanTextStringTest.testRomanTextString  sh   %OO F#.  0 99;11%2D2DELLN!++S1!++V4!++S1!++T2!++T2!++S1!++V4!++S1iik44S5E5EFQ..2Q..3r    c                b   SSK Jn  SSK Jn  SnUR                  USS9nUR	                  5       R                  [        R                  5      nS GHS  nU R                  XVS-      R                  S	5        U R                  [        XVS-      R                   Vs/ s H  n[        U5      PM     sn5      S
5        XVS-      R                  S   R                  nUc  UR                  S5      nU R                  UR                  S5        U R                  XVS-      R                  S5        U R                  [        XVS-      R                   Vs/ s H  n[        U5      PM     sn5      S5        U R                  XVS-      R                  S   R                  R                   5        GMV     g s  snf s  snf )Nr   r  )pitchz`m1 G: IV || b3 d: III b4 ii
m2 v b2 III6 b3 iv6 b4 ii/o6/5
m3 i6/4 b3 V
m4-5 = m2-3
m6-7 = m4-5
r  r  )r   rS     rQ  III6z['A4', 'C5', 'F5']rO  naturalrR  iv6z['B-4', 'D5', 'G5'])r  r  r  r  r  rA   r   rG   r  rK   r8   r  
accidental
Accidentalalterr  displayStatus)	r.   r  r  r  rL  r
  elementNumberrQ   r  s	            r!   r  Test.testMeasureCopyingB  sz   %! OOCO499;11%2D2DE'MXa&78??HS(1;L2M2U2U!V2UQ#a&2U!VW13 *+33A6AAAy$$Y/QWWa(Xa&78??GS(1;L2M2U2U!V2UQ#a&2U!VW24 OOHQ%67??BMM[[\ (!V "Ws   F'	F,c                   SSK Jn  SSKJn  SnUR	                  USS9nUR
                  S   nUR                  [        R                  5      R                  5       nUR                  S   nU R                  SUR                  5        U R                  UR                  S	5        UR                  [        R                   5      R#                  5       nU R%                  X5        UR                  [        R                  5      S
   n	U	R                  S   n
U R                  SU
R                  5        U R                  UR                  S	5        U	R                  S
   nU R                  [&        R(                  UR*                  5        g )Nr   r  )r  zGm1 G: IV || b3 d: III b4 NC
m2 b2 III6 b3 iv6 b4 ii/o6/5
m3 NC b3 G: V
r  r  r   r  r   r;   )r  r  music21.harmonyr  r  r  rA   r   rB   r  notesAndRestsassertInr  r  r   r
   Harmonyrz  assertIsInstancer   rG   classSet)r.   r  r  r  rL  rQ   m1r1
noChordObjm2r2r  s               r!   testNoChordTest.testNoChord  s)   %+ OOCO4GGAJ!!&..1779b!fbjj)))3/**7??;@@B
j2!!&..1!4a fbjj)))3/q!e((#,,7r    c                   SSK Jn  SSKJn  SnUR	                  USS9nUR
                  S   nXRR                     nU R                  [        U5      S5        Uu  pxn	U R                  UR                  S5        U R                  U	R                  S5        U R                  UR                  S	5        U R                  U	R                  S
5        U R                  UR                  5        U R                  SUR                  5        g )Nr   r  	translatez9Note: Hello
m1 G: IV || b3 d: III b4 NC
varM1 I
Note: Hi
r  r  rP  NoteHelloHiz I)r  r  r  r*  r  r  r'   r  r@   r,   r-   assertFalser  )
r.   r  r*  r  rL  rQ   unprocessedElementsnote1var1note2s
             r!   testUnprocessedTest.testUnprocessed  s    %/
 OOCO4GGAJ F FG01150UF+F+W-T*"dDII&r    c                (   SSK Jn  SnUR                  U5      nUR                  S   nU R	                  [        U5      S5        U R                  US   [        R                  5        U R	                  US   R                  S5        U R                  US   UR                  5        U R	                  US   R                  S5        U R	                  US   R                  S5        U R                  US	   [        R                  5        U R	                  US	   R                  S
5        U R                  US	   S   [        R                  5        U R	                  US	   R                  S
5        U R	                  US	   R                   R"                  S5        g )Nr   r)  zx
        Time Signature: 4/4
        m0 b4 f: i
        Note: Internal Note field after anacrusis.
        m1 V
        rP        @r;   r{   z$Internal Note field after anacrusis.rO  r   )r  r*  rN  r  r  r@   r  r   rB   ry  r'   rx  r-   r   rG   r{  rM   r   )r.   r*  r  rL  rQ   s        r!   testUnprocessedWithAnacrusis!Test.testUnprocessedWithAnacrusis  sB   / ,,S1GGAJQ#adFNN31))3/adI$J$JK1c*1$JKadFNN31c*ad1gu'9'9:1**C0144c:r    c                    SSK Jn  SnUR                  USS9nUR                  S   nUR	                  5       R
                  S   nU R                  UR                  5       R                  S5        g )Nr   r  zSixthMinor: flat
m1 c: vi
r  r  zA-)	r  r  r  r  recursenotesr  rootrn   )r.   r  r  rL  rQ   ch0s         r!   testSixthMinorParseTest.testSixthMinorParse2  s]    % OOCO4GGAJiik"$/r    c                    Sn[         R                  " 5       nUR                  U5      n[        5       nUR	                  UR
                  5        U R                  UR                  S5        g )NzRTVersion: 2.5
m1 C: I      @)r   rE  rF  rx   r   r   r  r   )r.   r  rJ  rH  pts        r!   testSetRTVersionTest.testSetRTVersion=  sW     KK$	
9++,,,c2r    c                |   SSK Jn  SnUR                  USS9nUR                  S   nUR	                  [
        R                  5      R                  5       nUR	                  [        R                  5      nUS   nUS   nU R                  UR                  R                  R                  S5        U R                  UR                  S5        UR                  n	U R                  U	R                  R                  R                  S	5        U R                  U	R                  S
5        U R!                  UR                  5        g )Nr   r  zm1 G: I b3 v d: i b4 Vr  r  r;   GvDr   )r  r  r  r  rA   r   rB   r  r   rG   r  r   rm   steprK   rI   assertIsNone)
r.   r  r  rL  rQ   r!  re   	notPChordpChordpivots
             r!   testPivotChordTest.testPivotChordO  s    %*OOCO4GGAJ!!&..1779&&u'9'9:1I	))..4,!!--s3s+)../r    c                   SSK Jn  SnUR                  USS9nUR                  S   nUR	                  [
        R                  5      S   nU R                  UR                  U5      S5        UR	                  [
        R                  5      S   nU R                  UR                  U5      S	5        UR	                  [
        R                  5      S
   nU R                  UR                  U5      S5        UR	                  [
        R                  5      S   nU R                  UR                  U5      S5        UR	                  [
        R                  5      S   n	U R                  U	R                  U5      S5        UR	                  [
        R                  5      S   n
U R                  U
R                  U5      S5        UR	                  [
        R                  5      S   nU R                  UR                  U5      S5        UR	                  [
        R                  5      S   nU R                  UR                  U5      S5        UR	                  [
        R                  5      S   nU R                  UR                  U5      S5        g )Nr   r  zTime Signature: 4/4
        m1 C: I
        Time Signature: 2/4
        m10 V
        Time Signature: 4/4
        m12 I
        m14-25 = m1-12
        r  r  rO  g       @	   g      B@r  g      C@   g      D@r  g      F@   g      L@   g      U@   g     U@   g      V@)	r  r  r  r  rA   r   rB   r  r  )r.   r  r  rL  rQ   m3m10m11m12m13m16m23m24r  s                 r!   testTimeSigChangesTest.testTimeSigChangesb  s   % OOCO4GGAJ!!&..1!4++A.4""6>>215,,Q/6""6>>226,,Q/6""6>>226,,Q/6""6>>226,,Q/6""6>>226,,Q/6""6>>226,,Q/6""6>>226,,Q/6""6>>226,,Q/6r    c                ,   SSK Jn  UR                  SSS9nUR                  5       R                  S   nUR                  5       R                  S   nU R                  UR                  R                  [        R                  " S5      5        U R                  UR                  [        R                  " S5      5        U R                  UR                  R                  [        R                  " S5      5        UR                  S	SS9nUR                  5       R                  S   nUR                  5       R                  S   nU R                  UR                  R                  S
5        U R                  UR                  S
5        U R                  UR                  R                  S5        UR                  SSS9nUR                  5       R                  S   nUR                  5       R                  S   nU R                  UR                  R                  [        R                  " S5      5        U R                  UR                  [        R                  " S5      5        U R                  UR                  R                  [        R                  " S5      5        g )Nr   r  zm1 C: I b2.66 Vr  r  r;   g?g@z"TimeSignature: 6/8
m1 C: I b2.66 VrA  g      ?zm1 C: I b2.66.5 VgUUUUUU?gUUUUUU@)r  r  r  r  r;  r  rM   r   r   opFracrx  )r.   r  rW  n1n2s        r!   testTupletsTest.testTuplets  s   %OO-kOBYY[q!YY[q!22FMM%4HIFMM%$8922FMM%4HIOOA+OVYY[q!YY[q!22E:E*22E:OO/ODYY[q!YY[q!22FMM&4IJFMM&$9:22FMM&4IJr    c                    SSK Jn  [        R                  " S5      nUR	                  USS9nUR
                  R                  S:X  d   eg )Nr   r  zx'
            Time Signature: 2/4
            m1 I
            m2 V
            m3 = m1
            m4-5 = m1-2
        r  r  r  )r  r  textwrapdedentr  rM   r   )r.   r  empty_measures_with_copyrL  s       r!   testCopyEmptyMeasuresTest.testCopyEmptyMeasures  sF    %#+?? 4 $  OO4[OIzz''2---r    c                  ^  SSK Jn            S!U 4S jjnS"U 4S jjn      S#U 4S jjn[        R                  " S5      nUR	                  USS9nU[
        R                     nT R                  [        U5      S	5        Uu  pU" US
SS5        U" U	SSS	5        U" US5        [        R                  " S5      n
UR	                  U
SS9nU[
        R                     nT R                  [        U5      S	5        Uu  pU" US
SS5        U" U	SSS5        U" US5        [        R                  " S5      nUR	                  USS9nU[
        R                     nT R                  [        U5      S5        Uu  ppU" US
SS	5        U" USSS5        U" US
SS5        U" USSS5        U[        R                      H[  nU[        R                     nT R                  [        U5      S5        T R                  UR                  5       R                  S5        M]     U" US5        [        R                  " S5      nUR	                  USS9nU[
        R                     nT R                  [        U5      S5        Uu  pnU" US
SS5        U" USSS	5        U" USSS	5        U[        R                      nT R                  [        U5      S5        Uu  nnnU" US/5        U" US/5        U" US/5        U" US5        [        R                  " S5      nUR	                  USS9nU[
        R                     nT R                  [        U5      S5        U[
        R                     u  pnU" US
SS5        U" USSS5        U" USSS	5        U[        R                      nT R                  [        U5      S5        Uu  nnnU" USS/5        U" US/5        U" USS/5        U" US 5        g )$Nr   r  c                   > TR                  U R                  U5        TR                  U R                  U5        TR                  U R                  R                  U5        g r=  )r  r  rx  
activeSiterC   )
repeat_barr  rx  mNumberr.   s       r!   _repeat_tester(Test.testRepeats.<locals>._repeat_tester  sM     Z119=Z..7Z22997Cr    c                   > [        U [        R                     5      n[        R                  " U5      nTR                  UR                  5       5        UR                  5       nTR                  UR                  U5        g r=  )
nextr   r~   r   Expanderr  repeatBarsAreCoherentprocessr  r   )rL  r   rQ   rY  p2r.   s        r!   _test_expanded(Test.testRepeats.<locals>._test_expanded  s[     Qv{{^$A"AOOA3356BR--}=r    c                   > U [         R                      Vs/ s H  o"R                  5       PM     nnTR                  X15        g s  snf r=  )r   rB   measureNumberWithSuffixr  )rs  expectedMeasuresrS   measure_nosr.   s       r!   _test_ending_contents/Test.testRepeats.<locals>._test_ending_contents  sA     AC6>>@RS@R1446@RKS[; Ts   AzS
            Time Signature: 3/4
            m1 ||: V
            m2 I :||
        r  r  rO  r   r{   r;   r  r6  g      (@zB
            Time Signature: 2/4
            m1 ||: I :||
        g       @g      @zw
            Time Signature: 2/4
            m1 I
            m2 ||:
            m3 :||
            m4 ||: :||
        rQ  rP  r  g      ,@z}
            Time Signature: 3/4
            m1 ||: I
            m2a IV :||
            m2b V :||
            m2c I
        2a2b2cg      2@z
            TimeSignature: 3/4
            m1 ||: I
            m2a IV
            m3a V :||
            m2b V :||
            m2c IV
            m3c V
            m4 I
        3a3cg      ;@)
rp  z
bar.Repeatr  r8   rx  r   rq  r   r7   rA  )rL  zstream.Streamr   r   r7   rA  )rs  zspanner.RepeatBracketr~  z	list[str]r7   rA  )r  r  rh  ri  r  r   r#  r  r@   r   rB   r   rG   r  rK   r   rp  )r.   r  rr  rz  r  simple_repeatsrL  br_iterstart_repeat
end_repeatsingle_bar_repeatsempty_bars_with_repeatsstart_repeat1end_repeat1start_repeat2end_repeat2rw  rn_iterthree_endingsrb_iterfirst_endingsecond_endingthird_endingmore_complex_examples   `                       r!   testRepeatsTest.testRepeats  s   %	D"	D/2	D<A	DLO	D	D	>	<%	<9B	<	< " * 
 OON;O?CJJ-Wq)#* |Wc15z5#q1q$%__ .  OO.{OCCJJ-Wq)#* |Wc15z5#q1q#"*// 3 # OO3KOHCJJ-Wq)AH>M}gsA6{E32}gsA6{E32(Ge001GS\1-
 W]]_33S9 ) 	q$  )  OOM+O>CJJ-Wq)18.;|Wc15{E32{E32G))*Wq)4;1m\lTF3mdV4lTF3q$' 	0 	  OO0OECJJ-Wq)123::.;|Wc15{E32{E32G))*Wq)4;1m\lT4L9mdV4lT4L9q$r    r   N)r7   rA  )r   r   r   r   r  r  r  r  r  r  r  r  r&  r3  r7  r>  rC  rN  r_  re  rk  r  r   r   r    r!   r  r  Y  sd     "_"_&_50H4,]:82'(;.	03$0&7FK.
.z r    r  z
list[type]
_DOC_ORDER__main__)r`   r?  rQ   zstream.PartrR   zkey.Key | Noner=  )ra  r?  rS   r@  r   dict):rC  
__future__r   rD   rh  r   typingr   unittestr  r   r   r   music21.common.typesr   r   r	   r
   r   r   r   r   r   r   r  r   r   r   r   Environmentr   r   r3  r   r   ElementWrapperr$   Music21Objectr'   rZ   rf   ru   rv   __annotations__rx   rN  r`  r   rn  r   r   r  TestCaser  r  r  r   mainTestr   r    r!   <module>r     s  o` #         )           '   &&'<=  	,"?"? 		 3 3 	*4#5#5 *2jC(C$0CLB :<6 ;X	& X	&v> PQR 4849(6494849n-`K$Tn DLP5x   P5fI 8 I ^ 
J  zT r    