
    3j             	         U d Z ddlmZ ddlZddlZddlZddlZddlZddl	m
Z
 ddl	mZ ddl	mZ ddlmZ ddl	mZ dd	l	mZ dd
l	mZ ddl	mZ ddl	mZ ddl	mZ ddl	mZ ddl	mZ ddl	mZ ddlmZ ddl	mZ ddl	mZ ddl	mZ  ej:                  d      ZdZdZ  G d dejB                        Z" G d dejF                        Z$ G d dejJ                        Z&d Z'	 	 	 	 d;dZ(d  Z)i Z*d!e+d"<    G d# d$      Z,d<d%Z-d&d'd(d)d*d+d,d-d.Z.	 d<	 	 	 d=d/Z/d0 Z0d1 Z1d2 Z2d<d3Z3 G d4 d5ejh                        Z5 G d6 d7ejh                        Z6g Z7d8e+d9<   e8d:k(  rddl	Z	 e	jr                  e6       yy)>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                      e Zd Zy)RomanTextTranslateExceptionN__name__
__module____qualname__     H/DATA/.local/lib/python3.12/site-packages/music21/romanText/translate.pyr   r          r   r   c                      e Zd Zy)RomanTextUnprocessedTokenNr   r   r   r   r!   r!      r   r   r!   c                  (     e Zd Zd fd	ZddZ xZS )RomanTextUnprocessedMetadatac                @    t        |   di | || _        || _        y )Nr   )super__init__tagdata)selfr'   r(   keywords	__class__s       r   r&   z%RomanTextUnprocessedMetadata.__init__   s!    $8$	r   c                8    | j                    d| j                   S )N: )r'   r(   )r)   s    r   _reprInternalz*RomanTextUnprocessedMetadata._reprInternal   s    ((2dii[))r   ) r/   )returnstr)r   r   r   r&   r.   __classcell__)r+   s   @r   r#   r#      s    
*r   r#   c                   d}| j                         \  }}t        |      dkD  rt        d      |d   }|j                  t        j
                        D ]U  }|j                  |k(  s	 t        j                  |      }| j                  d   |_        |j                  t        j                        D ]  }	|t        d	      |	j                  r|	j                  }n*|	j                  |	j                  j                  }n||	_        |	j                  `t        j                  |	j                   t        j                  |            }
d
|
_        t        j                  |	j$                        |
_        t        j                  |	j&                        |
_        |j)                  |	|
         ||fS  ||fS # t        $ r%}t        d|j                   ddz   dz         |d}~ww xY w)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   Failed to copy measure :zD did you perhaps parse an RTOpus object with romanTextToStreamScore z!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ternPastnewRNs              r   _copySingleMeasurerT      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!)FJ//;!..t}}X'>E *.E&%)]]6??%CEN#'==#?ELIIfe,% C( h;C 6B h;;  1-ell^1=\]9: 	s   (F00	G9 GGc                   | j                         \  }}t        |      dk(  rt        d      |d   }|d   }| j                  d   | j                  d   z
  ||z
  k7  rt        d      | j                  d   |k  rt        d      g }|j	                  t
        j                        D ]  }|j                  t        ||dz         v rk	 t        j                  |      }	| j                  d   |j                  z   |z
  |	_        |j                  |	       t        |	j	                  t        j                              }|D ]  }|t        d      |j                  r|j                   }n*|j"                  |j"                  j                   }n||_        |j$                  `t        j                  |j&                  t        j                  |            }d|_        t        j                  |j*                        |_        t        j                  |j,                        |_        |	j/                  ||        |j                  |k(  s ||fS  ||fS # t        $ r%}
t        d|j                   d| d| d	      |
d
}
~
ww xY w)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
    r4   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 sectionr5   z to measure range -zf: did you perhaps parse an RTOpus object with romanTextToStreamScore instead of romanTextToStreamOpus?Nr7   T)r8   r9   r   r<   r:   r   r;   ranger=   r>   r?   appendlistr   r@   rA   r   rB   rC   rD   rE   rF   rG   rH   )	rtMeasurerJ   rK   targetNumbersrN   targetStart	targetEndmeasuresrP   rL   rQ   allRNsrR   rS   s                 r   _copyMultipleMeasuresr`      sp    *3)@)@)B&M&
=Q)*abb"Ka IY--a00I4KK)_a 	aY&)LN 	N H%%fnn5<<5i!m<<MM%( !''*U\\9KGAHOOA!..u/A/ABCF #5\^ ^**%zzH&&2%0044H!)FJ//;!..t}}X'>E *.E&%)]]6??%CEN#'==#?ELIIfe,% !( <<9$XK 6J XC  1-ell^;M"m1YK 0--
 s   I	I9 I44I9c                   t        | t              r+t        j                  |       } t        j                  |       }n| j                         }|j                  j                  }|j                  dk(  r|j                         }|dz   }||fS )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--: ')
    minorr-   )

isinstancer1   r   "convertKeyStringToMusic21KeyStringKeygetKeytonicnamemodelower)rtKeyOrStringk	tonicNameprefixs       r   _getKeyAndPrefixro   ,  ss    ( -%>>}MGGM"  "IvvOO%	Ff9r   z)dict[tuple[str, str], roman.RomanNumeral]_rnKeyCachec                      e Zd ZdZddZd ZddZddZddZddZ	dd	Z
dd
Zd Zdd	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 ddZd Zy)PartTranslatora  
    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                P   |t        j                         }|| _        t        j                         | _        t        | _        t        j                  d      | _
        | j                  | _        d| _        d | _        d| _        d | _        d | _        d| _        d| _        t'        d      \  | _        }d| _        t,        j.                  j0                  | _        t,        j.                  j0                  | _        i | _        d | _        d | _        d| _        d| _        d| _         d| _!        y )Nz4/4Fr   TCr/           )"r   Metadatamdr   PartrJ   ROMANTEXT_VERSIONromanTextVersionr   TimeSignature	tsCurrenttsAtTimeOfLastChordtsSetlastMeasureTokenlastMeasureNumber
previousRnkeySigCurrentsetKeySigFromFirstKeyTokenfoundAKeySignatureSoFarro   rK   prefixLyricr   Minor67Default
CAUTIONARY
sixthMinorseventhMinorrepeatEndingscurrentMeasureTokenpreviousChordInMeasurepivotChordPossiblenumberOfAtomsInCurrentMeasuresetKeyChangeTokencurrentOffsetInMeasure)r)   rw   unused_prefixLyrics      r   r&   zPartTranslator.__init__X  s   :""$B 1 ,,U3#'>> 
 $!"!*.'',$,<S,A))..99!00;; $( &*#"'-.*!&&)#r   c           
        |D ]  }	 | j                  |        | j                  }|j                          t        |       |j                  d       |j                  d       t        || j                         |S # t        $ r8}t        j                         }t	        d|j
                   d| d|       |d }~ww xY w)NzAt line z for token z, an exception was raised: 
T)inPlace)translateOneLineToken	Exception	traceback
format_excr   
lineNumberrJ   coreElementsChangedfixPickupMeasure	makeBeamsmakeAccidentals_addRepeatsFromRepeatEndingsr   )r)   tokenstokenexctracebackMessagerJ   s         r   translateTokenszPartTranslator.translateTokensz  s    EO**51  FF		D!	$'$Q(:(:;  O#,#7#7#9 1u//0E7 C22B1CEFKNOOs   A==	B>3B99B>c                x   | j                   }|j                         r>t        j                  rt	        |t
        j                        sJ | j                  |       y
|j                         r|j                  d|j                         y
|j                         r|j                  d|j                         y
|j                         r|j                  d|j                         y
|j                         r|j                  d|j                         y
|j                         r|j                  d|j                         y
|j                         r|j                  d|j                         y
|j!                         r|j                  d|j                         y
|j#                         r-	 t%        j&                  |j                        | _        d| _        y
|j5                         r| j7                  |       y
|j9                         s|j;                         r| j=                  |       y
|j?                         r	 tA        |j                        | _!        y
t	        |t
        jF                        r<tI        |jJ                  |j                        }| jL                  jO                  |       y
tQ        |      }| jL                  jO                  |       y
# t,        j.                  $ r% t0        j3                  d|j                         Y y
w xY w# tD        $ r% t0        j3                  d	|j                         Y y
w xY w)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))rw   	isMeasuretTYPE_CHECKINGrc   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floatrz   
ValueErrorRTTaggedr#   r'   rJ   rX   r!   )r)   	lineTokenrw   otherMetadataunprocesseds        r   r   z$PartTranslator.translateOneLineToken  sa    WW  !)Y-@-@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""9-  "X(-inn(=% 	9#5#568	WMFFMM-( 4I>KFFMM+&/  00 \!!$G	GY"Z[\  X!!$CINNCU"VWXs$   '+K 8L 5LL+L98L9c                &   |j                   j                         }|dk(  rt        j                  j                  }n|dk(  rt        j                  j
                  }n|dk(  rt        j                  j                  }nx|dv rt        j                  j                  }nY|dk(  rF|j                         rt        j                  j                  }n)t        j                  j
                  }nt        d|      |j                         r|| _
        y|| _        y)aO  
        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(   rj   r   r   FLATSHARPQUALITYr   r   r   r   r   )r)   rI   tDatatEnums       r   r   z PartTranslator.setMinorRootParse  s    P ##%F?((--Eg((..Ei((00E00((33Ej $$&,,11,,22-:5)DF F   "#DO %Dr   c                   | j                   }|j                  d   | j                  dz   kD  xr | j                  du}t	        |j                        dk(  xr |j
                  }t	        |j                        dkD  }|j                  y|j                  y|r| j                  |       |r|j                          t        ||| j                        \  }| _        |j                  |       |j                  | _        || _        |j                  t        j                         }|r|d   | _        yy|r|j                          t#        ||| j                        \  }| _        |j%                  |       |d   j                  | _        || _        |d   j                  t        j                         }|r|d   | _        yy| j'                  |      }|j(                  j*                  dk(  r| j-                  |       |j                  |       y)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   r4   N)rJ   r<   r   r   r9   isCopyDefinitionvariantNumbervariantLetterfillToMeasureTokenr   rT   rK   
coreAppendr   r:   r   r@   r`   rX   translateSingleMeasurerF   quarterLengthfillMeasureFromPreviousRn)	r)   measureLineTokenrJ   skipsPriorMeasuresisSingleMeasureCopyisMultipleMeasureCopyrL   romansr^   s	            r   r   z(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 !!#12BAt}}UAt}LLO%&XXD"$4D!))%*<*<=F"(*  #!!#&;<LaQUQ^Q^&_#HdmHHX%-b\%8%8D"$4D!b\44U5G5GHF"(*  ++,<=Azz''1,..q1LLOr   c                l   | j                   }t        | j                  dz   |j                  d         D ]a  }t	        j
                         }||_        | j                  |       t        | j                  || j                  |       |j                  |       c |j                  d   dz
  | _        || _        y)z
        Create a series of measures which extend the previous RN until the measure number
        implied by `measureToken`.
        r4   r   N)rJ   rW   r   r<   r   r;   r    appendMeasureToRepeatEndingsDictr   r   r   )r)   measureTokenrJ   imFills        r   r   z!PartTranslator.fillToMeasureTokenK  s    
 FFt--1<3F3Fq3IJANN$EEL**51,T-B-B-2-1-?-?D LL K ".!4!4Q!7!!; ,r   c                   | j                   t        j                  | j                         }d|_        t        j                  | j                  j
                        |_        | j                   j                  %t        j                  d      | j                   _        nd| j                   j                  _	        t        j                  d      |_        || _         |j                  |       y y )Nr/   startcontinuestop)r   r=   r>   lyricr}   barDurationrF   r   TietyperX   )r)   r   newRns      r   r   z(PartTranslator.fillMeasureFromPreviousRn\  s    ??&MM$//2EEK!]]4+C+C+O+OPEN""*&)ggg&6#+5##(EI#DOLL 'r   c                D   |j                   }|dk(  rt        j                  d      | _        nF|dk(  rt        j                  d      | _        n&	 t	        |      }t        j                  |      | _        d| _        d| _        y# t
        $ r}t        d|      |d}~ww xY w)	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'
        r/   r   Bbr   zCannot parse key signature: NFT)	r(   r   KeySignaturer   intr   r   r   r   )r)   rI   r(   dataValves        r   r   z#PartTranslator.parseKeySignatureTagk  s    B }}2:!$!1!1!!4DT\!$!1!1"!5Dcd)%(%5%5g%>" +0''+$	  c14PQUPX2YZ`bbcs   %B 	BBBc                (   || _         t        j                         }|j                  d   |_        t	        ||| j
                         |j                  d   | _        || _        | j                  s| j                  |_
        d| _        | j                  s/| j                  #|j                  d| j                         d| _        d| _        d| _        d| _        t#        |j$                        | _        d| _        t+        |j$                        D ]+  \  }}|| j&                  dz
  k(  }| j-                  |||       - | j                  <| j                  j.                  j0                  | j                  z
  | j2                  _        |j5                          |S )zp
        Given a measureToken, return a `stream.Measure` object with
        the appropriate atoms set.
        r   TNru   Fr4   isLastAtomInMeasure)r   r   r;   r<   r   r   r   r   r~   r|   timeSignaturer   r   insertr   r   r   r9   atomsr   r   	enumeratetranslateSingleMeasureAtomr   r   r   r   )r)   r   rL   r   ar   s         r   r   z%PartTranslator.translateSingleMeasure  s`   
 $0 NN&&q)(q$:L:LM!-!4!4Q!7 ,zz"nnAODJ..43E3E3QHHQ**+.2D+&)#&*#"'-01C1C-D*!&l001DAq#$(J(JQ(N#N++AqFY+Z 2
 >>%-1^^-G-G-U-U262M2M.NDOO)	r   Fr   c          	        t        |t        j                        s(| j                  du rt        |t        j                        rr| j                  |       |j                  dk  r$|j                  d| j                         d| _        y|j                  | j                  | j                         d| _        yt        |t        j                        r^	 |j                         }|j                  dk  r|j                  d|       d| _        y|j                  | j                  |       d| _        yt        |t        j                        r| j                  |       yt        |t        j$                        r	 |j'                  | j(                        }| j*                  | j,                  |dkD  rt/        j0                  | j,                        }||_        d
|_        | j,                  j6                  %t7        j8                  d      | j,                  _        nd| j,                  j6                  _        t7        j8                  d      |_        || _        || _        |j                  d|       d| _        || _	        yt        |t        j>                        r| j(                  | _         tC        jD                         }|j                  | j                  |       tG        jH                         }	| j<                  du r| j*                  nb| j*                  jK                  |      }
| j                  |
z
  }|dk  r"t        d| j"                  j                          || j*                  _        d
| _&        |j                  | j                  |	       |	| _        |	| _        d| _        yyt        |t        jN                        r| jQ                  ||| j                         yt        |t        jR                        rt        |t        jT                        re|rctW        jX                  d      |_-        | j(                  g|j]                  |jZ                  | j(                  j^                  j2                         y| j                  dk(  r^t        |t        j`                        rtW        jX                  d      |_1        yte        |      }|j                  | j                  |       y| j(                  | j(                  j^                  j2                  | j                  k(  r^t        |t        jT                        rtW        jX                  d      |_-        yte        |      }|j                  | j                  |       yte        |      }|j                  | j                  |       yyte        |      }|j                  | j                  |       y# t        j                  t        f$ r5}t        d|j                    d| j"                  j                          |d}~ww xY w# t        $ rB}t        d|j                    d	| j(                   d| j"                  j                          |d}~ww xY w)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.
        Fr4   r   Tzcannot get key from 	 in line Nz-cannot properly get an offset from beat data z under timeSignature r/   r   r   r    too many notes in this measure: end	direction)3rc   r   RTKeyr   RTAnalyticKeysetAnalyticKeyr<   
coreInsertrK   r   RTKeySignaturegetKeySignaturer	   r   r   r   srcr   RTBeat	getOffsetr|   r   r   r=   r>   r   r   r   r   r   r   	RTNoChordr}   r
   NoChordr   RestgetOffsetBySiter   RTChordprocessRTChordRTRepeatRTRepeatStopr   RepeatrightBarlinesetElementOffsetr   RTRepeatStartleftBarliner!   )r)   r   rL   r   thisSigr   	newOffset
firstChordcsrn	oPreviousnewQLrtts                r   r   z)PartTranslator.translateSingleMeasureAtom  s     q)//*00E9"1i&=&=>" xx1}Q. ,0D( T88$--H+/D(9334++- xx1}Q( ,0D( T88'B+/D(9223"9++,KK7	 ++33!A!]]4??;
+4
(#%
 ??&&.*-'''*:DOO'/9DOO'',!$
",.8+Q
+&+D#*3D'9../'+~~D$"BLL44b9B&&%/..6 $ ; ; K KA NI 77)CEz9>t?W?W?[?[>\]_ _@ED//=#% T88"=.0+"$*/' 0" 9,,-1d&A&AB9--.!Y3349L "%e!<>>-&&(B(B(P(P ,,1a!8!89$'JJ$AAM3A6CLL!<!<cB..,22@@DD_D__a!7!7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&  1CAEE7 K++/>>*: ;#77;;<> 	s0   W 5X X 0XX	Y#!=YY#c                b   | j                   | _        	 |j                  }|| j                  j                  f}t
        r%|t        v rt        j                  t        |         }nZt        j                  |t        j                  | j                        | j                  | j                        }d|_        |t        |<   | j                  du rd|_        d| _        nd|_        | j"                  du r| j$                  nX| j$                  j'                  |      }||z
  }|dk  r"t)        d| j*                  j                         || j$                  _        |j/                  | j0                  |j                  z          d| _        |j3                  ||       || _        || _        d| _        y| j$                  xj6                  d| j0                  z   |j                  z   z  c_        || j$                  _        d| _        d| _        y# t        j                   $ r t        j                         }Y Mw xY w)	z0
        Process a single RTChord atom.
        )r   r   TFNr   r  r/   z//)r|   r}   r  rK   tonicPitchNameWithCaseUSE_RN_CACHErp   r=   r>   r   r@   r   r   rE   r   rA   RomanNumeralExceptionr   r   r  r   r   r   addLyricr   r  r   r   rB   )	r)   r   rL   currentOffsetaSrc
cacheTupler  r   r!  s	            r   r  zPartTranslator.processRTChordE  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+*,D' DO&*D#''--8H8H1H1551PP-57D''2!D&+D#5 ** 	&##%B	&s   CH 'H.-H.c                   	 t        |      \  | _        }| xj                  |z  c_        d| _	        y# t        t        j
                  f$ r5}t        d|j                   d| j                  j                         |d}~ww xY w)zz
        Indicates a change in the analyzed key, not a change in anything
        else, such as the keySignature.
        zcannot get analytic key from r   NT)
ro   rK   r   r   r	   r   r   r  r   r   )r)   r   plr   s       r   r  zPartTranslator.setAnalyticKey  s    
	 0 3DM2"
 "&	 L99: 	-/wi@X@X@\@\?]^	s   (2 B 0A;;B N)r   rtObjects.RTTagged)rI   r.  )r   rtObjects.RTMeasure)r   r/  )r   stream.Measurer0   None)r   zrtObjects.RTAtomrL   r0  r   boolr0   r1  )r   zrtObjects.RTChordrL   r0  r(  r   r0   r1  )r   r   r   __doc__r&   r   r   r   r   r   r   r   r   r   r  r  r   r   r   rr   rr   P  s     *D$B'H=&~:x-" .,`"R %*C;C; C;
 "C; 
C;LU,U, U,  	U,
 
U,n&r   rr   c                d   t        | t              r&t        j                         }|j	                  |       }n| }|t        j                         }n|}t        j                         }|j                  d|       t        |      }|j                  |j                        }|j                  d|       |S )z
    The main processing module for single-movement RomanText works.

    Given a romanText handler or string, return or fill a Score Stream.
    r   )rc   r1   r   RTFilereadstrr   Scorer   rv   r   rr   r   r   )	rtHandlerinputM21rtftokenedRtHandlersrw   	partTransrJ   s           r   romanTextToStreamScorer>    s     )S! ;;y1$ LLN 
			BHHQOr"I!!"2"9"9:AHHQNHr   r4                        )r   bcdefghc                    | j                   sy| j                   d   |_        | j                   D ]^  }||dk(  r|t        vrt        d|       t        |   }||vrg ||<   || j                  d   |f}n||f}||   j                  |       ` y)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   r/   zImproper repeat letter: )repeatLetternumberSuffixletterToNumDictr   r<   rX   )rtMeasureObjrL   r   measureNumberrlrepeatNumbermeasureTuples          r   r   r     s    F $$!..q1AN'':r_$-0H.MNN&r*},*,M,' (//2A6L)1-Ll#**<8 (r   c                   g }| D ]}  }d}d}g }| |   D ]U  \  }}||}|}|j                  |       ||dz   kD  r||f}|j                  |       |}|}|g}C|j                  |       |}W |i||f}|j                  |        |S )aB  
    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)]
    Nr4   )rX   )	r   
returnListendingNumberstartMeasureNumberr   measureListmeasureNumberUnderEndingmeasureObjectmyTuples	            r   _consolidateRepeatEndingsr^    s    * J%! 7D\7R3$m!)%="$<!""=1),=,AA&5!!'*%="$<!,o""=1$<! 8S )"L1Gg&) &, r   c                   t        |      }|D ]}  }|d   |d   }}t        j                  ||      }|d   j                  |       }| j	                  ||       |dk(  sP|d   j
                  `t        j                  d      |d   _         y)zO
    Given a Stream and the repeatEndings dict, add repeats to the stream.
    r   r4   )r<   r   Nr  r  )r^  r   RepeatBracketr  r   r  r   r  )r<  r   consolidatedRepeatsrepeatEndingTuplerZ  rX  rbrbOffsets           r   r   r   4  s     4MB0$5a$8:KA:N\"";|Dq>11!4 	
212++3/2zzE/JB, 1r   c                8   | j                  d      }|y|j                  t        j                  t        j
                  g      }|sy|d   j                  dk(  ry|d   j                  }|D ]&  }|j                  |k  r|j                  |z
  |_        ( ||_        | D ]'  }|j                  dkD  s|xj                  |z  c_        ) | j                  t        j                        j                         }||u ry|j                  t        j                  t        j
                  g      j                         }|r|j                  j                  |kD  r|j                  j                  }|j                  xj                  ||z
  z  c_        ||z
  |_        t        j                  j!                  | dd      5  t#        |       }d}	||	   |ur<||	   j%                  | ||	   j                  |j                  z
         |	dz  }	||	   |ur<ddd       yyy# 1 sw Y   yxY w)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   r4   )measurer:   r   r@   r
   r  offsetpaddingLeftr   r;   lastrF   r   paddingRightr   
classToolstempAttributerY   setOffsetBySite)

partObjectm0	rnObjectsleftPaddingelmLastlastRNcurLastLengthpartElementsr   s
             r   r   r   F  s   ` 
		A	B	z%%u'9'97??&KLI|aA,%%K99{"		K/BI	 
 !BN99q=II$I  ))&..9>>@E{%%u'9'97??&KLQQSF&////+=44%%)DD%*[8,,ZUK
+LAq/.Q//
0<Q0F0FI[I[0[]Q	 q/.	 LK >v
 LKs   4AHHc                B   t        | t              r%t        j                         }|j	                  |       } | j                         rN|t        j                         }n|}| j                  d      }|D ]  }|j                  t        |              |S t        | |      S )a  
    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)r9  )rc   r1   r   r5  r6  definesMovementsr   OpussplitByMovementrX   r>  )r8  r9  r:  r<  handlerBundlesrL  s         r   romanTextToStreamOpusr~    s     )S! KK	*	!!#AA"2242HA HH+A./   %i(CCr   c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)TestSlowz?
    These tests are currently too slow to run every time.
    c                    ddl m} |j                  D ]B  }t        j                         }|j                  |      }t        |      }|j                          D y Nr   	testFiles)music21.romanTextr  ALLr   r5  r6  r>  showr)   r  tfr:  rthr<  s         r   testExternalAzTestSlow.testExternalA  sA    /--B""$C++b/C&s+AFFH	  r   c                   ddl m} |j                  D ]B  }t        j                         }|j                  |      }t        |      }|j                          D t        |j                        }| j                  |j                  j                  d       | j                  |j                  j                  d       t        |j                        }| j                  |j                  j                  d       | j                  |j                  j                  d       t        |j                        }| j                  |j                  j                  d       y )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   r5  r6  r~  r  r>  swv23assertEqualr   r   r   riemenschneider001monteverdi_3_13r  s         r   
testBasicAzTestSlow.testBasicA  s    /--B""$C++b/C%c*AFFH   #9??3,,.?@ 	))+ab"9#?#?@,,l;))+FG"9#<#<=,,.BCr   c                   ddl m} t        |j                        }|j                  d   j                  t        j                        }|d   j                  t        j                        j                         }| j                  |j                  D cg c]  }t        |       c}g d       | j                  t        |j                        d       |d   j                  t        j                        d   }| j                  t        |j                        d       |d   j                  t        j                        d   }| j                  t        |j                        d       |d   j                  t        j                        d   }| j                  t        |j                        d       |d   j                  t        j                        d   }| j                  t        |j                        d       |d   j                  t        j                        d   }| j                  t        |j                        d       t        |j                        }|j                  d   j                  t        j                        }d }d }d }	d }
d }d }|D ]n  }|j                   d	k(  r|}|j                   d
k(  r|}'|j                   dk(  r|}	9|j                   dk(  r|}
K|j                   dk(  r|}]|j                   dk(  sm|}p |j                  t        j                        d   }| j                  t        |j                        d       |j                  t        j                        d   }| j                  t        |j                        d       |
j                  t        j                        d   }| j                  t        |j                        d       |
j                  t        j                        d   }| j                  t        |j                        d       |j                  t        j                        d   }| j                  t        |j                        d       |j                  t        j                        d   }| j                  t        |j                        d       |j                  t        j                        d   }| j                  t        |j                        d       |j                  t        j                        d   }| j                  t        |j                        d       |	j                  t        j                        j                         }| j                  t        |j                        d       |j                  t        j                        j                         }| j                  t        |j                        d       y c c}w )Nr   r  r4   )D5zF#5A5Vr   r?  r@  )   *   +   1   2   3   IVIiizV/ii)r  r  r>  r  partsr:   r   r;   r   r@   firstr  pitchesr1   rD   r  r<   )r)   r  r<  mStreamrn1xrn2m1am2am3am1bm2bm3brL   r  s                  r   testMeasureCopyingAz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   W!c                \   ddl m} ddlm} |j	                  |j
                        }|j                  d      }|j                         j                  t        j                        }| j                  |d   j                  d       | j                  t        |d   j                        d       y )Nr   	converterr     r4   IIIzd minor)music21r  r  r  parser  rg  flattenr:   r   r@   r  rD   r1   r   )r)   r  r  r<  m25r  s         r   testMeasureCopyingBzTestSlow.testMeasureCopyingB1  sy    %/OOI556iim[[]--e.@.@AAu-RUYY3r   c                   ddl m} t        |j                        }| j	                  |j
                  d   j                  j                  d       | j	                  |j
                  d   j                  j                  d       | j	                  |j
                  d   j                  j                  d       | j	                  |j
                  d   j                  j                  d       | j	                  |j
                  d   j                  j                  d       | j	                  |j
                  d   j                  j                  d       dd	l	m
} |j                  |j                        }| j                  d
|j                  v        | j	                  t        |j
                        d       |j                  |j                        }| j                  t!        |t"        j$                               y )Nr   r  1Mozartr4   2r?  3r  r{  r@  )r  r  r~  
mozartK279r  scoresr   r   r   r  r  r  
assertTrueclassesr9   r  rc   r   r7  )r)   r  or  r<  s        r   testOpuszTestSlow.testOpus@  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   N)	r   r   r   r3  r  r  r  r  r  r   r   r   r  r    s#    D.G1R45r   r  c                  |    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd ZddZddZy)Testc                     ddl m} t        |j                        }t	        |t
        j                            fd} |dd        |dd        |dd        |d	d
        |dd        |dd       y )Nr   r  c                x    |    }|j                   }j                  dj                  d |D              |       y )N c              3  4   K   | ]  }|j                     y wr-  )rh   ).0rJ   s     r   	<genexpr>z:Test.testMinor67set.<locals>.pitchEqual.<locals>.<genexpr>_  s     %@iaffis   )r  r  join)indexpitchStrch	chPitcheschordsr)   s       r   
pitchEqualz'Test.testMinor67set.<locals>.pitchEqual\  s4    B

ISXX%@i%@@(Kr   zC E- Gr4   zB D Fr@  zG B DrA  zA- C E-rD  zB- D F
   zA C E)r  r  r>  testSetMinorRootParserY   r   r@   )r)   r  r<  r  r  s   `   @r   testMinor67setzTest.testMinor67setW  so    /"9#B#BCa**+,	L
 	1h1g1g1i 1h2wr   c                   ddl m} d}|j                  |d      }|j                  d      j	                         }| j                  |j                  t        j                        j                         j                  j                  d       |j                  d      j	                         }| j                  |j                  t        j                        j                         j                  j                  d       y )	Nr   r  z6
m1 G: I
m2 I
m3 V D: I
m4 V
m5 G: I
m6-7 = m3-4
m8 I
	romanTextformatrD  D majorrE  r  r  r  rg  r  r  r:   r   r@   r  r   rh   r)   r  testCaser<  rL   s        r   testPivotInCopyMultiplezTest.testPivotInCopyMultipleh  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                   ddl m} d}|j                  |d      }|j                  d      j	                         }| j                  |j                  t        j                        j                         j                  j                  d       y)	z^
        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  rB  zG majorNr  r  s        r   testPivotInCopyMultiple2zTest.testPivotInCopyMultiple2y  so    
 	& OOH[O9IIaL  "--e.@.@AGGIMMRRT]^r   c                   ddl m} d}|j                  |d      }|j                  d      j	                         }| j                  |j                  t        j                        j                         j                  j                  d       y )Nr   r  z-
m1 G: I
m2 I
m3 V D: I
m4 G: I
m5 = m3
m6 I
r  r  rC  r  r  r  s        r   testPivotInCopySinglezTest.testPivotInCopySingle  sm    % OOH[O9IIaL  "--e.@.@AGGIMMRRT]^r   c                   d}t        |      }|j                  d      j                         }| j                  |j	                  t
        j                        j                         j                  d       |j                  d      j                         }| j                  |j	                  t
        j                        j                         j                  d       y)z5
        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
rC  zE-dominant seventh chordrD  N)	r>  rg  r  r  r:   r   r@   r  pitchedCommonName)r)   testSecondaryInCopyr<  rL   s       r   testSecondaryInCopyMultiplez Test.testSecondaryInCopyMultiple  s    
 ##67IIaL  "--e.@.@AGGI[[3	5IIaL  "--e.@.@AGGI[[3	5r   c                :    ddl m} t        |j                        }y r  )r  r  r>  r  )r)   r  unused_ss      r   
testBasicBzTest.testBasicB  s    /))*F*FGr   c                r   ddl m} |j                  dd      }|j                         j	                  t
        j                        j                         }| j                  |d   j                  d       | j                  |d   j                  d       | j                  |d	   j                  d       | j                  |d
   j                  d       | j                  |d   j                  d       | j                  |d   j                  d       | j                  |d   j                  d       | j                  |d   j                  d       |j                         j	                  t        j                        }| j                  |d   j                  d       | j                  |d   j                  d       y )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  r4   zV6/5r?  r@  V7rA  virB  r   rC  zV4/2rD  )r  r  r  r  r:   r   r@   r   r  rD   r   r   sharps)r)   r  r<  rnStreamrnStreamKeys        r   testRomanTextStringz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   ddl m} ddl m} d}|j                  |d      }|j	                         j                  t        j                        }dD ]Q  }| j                  ||dz      j                  d	       | j                  t        ||dz      j                  D cg c]  }t        |       c}      d
       ||dz      j                  d   j                  }||j                  d      }| j                  |j                  d       | j                  ||dz      j                  d       | j                  t        ||dz      j                  D cg c]  }t        |       c}      d       | j                  ||dz      j                  d   j                  j                          T y c c}w c c}w )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   rC     rA  III6z['A4', 'C5', 'F5']r?  naturalrB  iv6z['B-4', 'D5', 'G5'])r  r  r  r  r  r:   r   r@   r  rD   r1   r  
accidental
Accidentalalterr  displayStatus)	r)   r  r  r  r<  r  elementNumberrJ   r  s	            r   r  zTest.testMeasureCopyingB  s   %! OOCO499;11%2D2DE'MXma&78??HS(=1;L2M2U2U!V2UQ#a&2U!VW13 *+33A6AAAy$$Y/QWWa(Xma&78??GS(=1;L2M2U2U!V2UQ#a&2U!VW24 OOH]Q%67??BMM[[\ (!V "Ws   F'F,c                   ddl m} ddlm} d}|j	                  |d      }|j
                  d   }|j                  t        j                        j                         }|j                  d   }| j                  d|j                         | j                  |j                  d	       |j                  t        j                         j#                         }| j%                  ||       |j                  t        j                        d
   }	|	j                  d   }
| j                  d|
j                         | j                  |j                  d	       |	j                  d
   }| j                  t&        j(                  |j*                         y )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   r4   )r  r  music21.harmonyr  r  r  r:   r   r;   r  notesAndRestsassertInr  r  r   r
   Harmonyrj  assertIsInstancer   r@   classSet)r)   r  r  r  r<  rJ   m1r1
noChordObjm2r2r  s               r   testNoChordz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                   ddl m} ddlm} d}|j	                  |d      }|j
                  d   }||j                     }| j                  t        |      d       |\  }}}	| j                  |j                  d       | j                  |	j                  d       | j                  |j                  d	       | j                  |	j                  d
       | j                  |j                         | j                  d|j                         y )Nr   r  	translatez9Note: Hello
m1 G: IV || b3 d: III b4 NC
varM1 I
Note: Hi
r  r  r@  NoteHelloHiz I)r  r  r  r  r  r  r#   r  r9   r'   r(   assertFalser  )
r)   r  r  r  r<  rJ   unprocessedElementsnote1var1note2s
             r   testUnprocessedzTest.testUnprocessed  s    %/
 OOCO4GGAJ	 F FG01150tUF+F+W-T*"dDII&r   c                (   ddl m} d}|j                  |      }|j                  d   }| j	                  t        |      d       | j                  |d   t        j                         | j	                  |d   j                  d       | j                  |d   |j                         | j	                  |d   j                  d       | j	                  |d   j                  d       | j                  |d	   t        j                         | j	                  |d	   j                  d
       | j                  |d	   d   t        j                         | j	                  |d	   j                  d
       | j	                  |d	   j                   j"                  d       y )Nr   r
  zx
        Time Signature: 4/4
        m0 b4 f: i
        Note: Internal Note field after anacrusis.
        m1 V
        r@        @r4   ru   z$Internal Note field after anacrusis.r?  r   )r  r  r>  r  r  r9   r  r   r;   ri  r#   rh  r(   r   r@   rk  rF   r   )r)   r  r  r<  rJ   s        r   testUnprocessedWithAnacrusisz!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                    ddl m} d}|j                  |d      }|j                  d   }|j	                         j
                  d   }| j                  |j                         j                  d       y )Nr   r  zSixthMinor: flat
m1 c: vi
r  r  zA-)	r  r  r  r  recursenotesr  rootrh   )r)   r  r  r<  rJ   ch0s         r   testSixthMinorParsezTest.testSixthMinorParse/  s]    % OOCO4GGAJiik"$/r   c                    d}t        j                         }|j                  |      }t               }|j	                  |j
                         | j                  |j                  d       y )NzRTVersion: 2.5
m1 C: I      @)r   r5  r6  rr   r   r   r  rz   )r)   r  r:  r8  pts        r   testSetRTVersionzTest.testSetRTVersion:  sW     KK$	
9++,,,c2r   c                   ddl m} d}|j                  |d      }|j                  d   }|j	                  t
        j                        j                         }|j	                  t        j                        }|d   }|d   }| j                  |j                  j                  j                  d       | j                  |j                  d       |j                  }	| j                  |	j                  j                  j                  d	       | j                  |	j                  d
       | j!                  |j                         y )Nr   r  zm1 G: I b3 v d: i b4 Vr  r  r4   GvDr   )r  r  r  r  r:   r   r;   r  r   r@   r  r   rg   steprD   rB   assertIsNone)
r)   r  r  r<  rJ   r  r_   	notPChordpChordpivots
             r   testPivotChordzTest.testPivotChordL  s    %*OOCO4GGAJ!!&..1779&&u'9'9:1I	))..4,!!--s3s+)../r   c                   ddl m} d}|j                  |d      }|j                  d   }|j	                  t
        j                        d   }| j                  |j                  |      d       |j	                  t
        j                        d   }| j                  |j                  |      d	       |j	                  t
        j                        d
   }| j                  |j                  |      d       |j	                  t
        j                        d   }| j                  |j                  |      d       |j	                  t
        j                        d   }	| j                  |	j                  |      d       |j	                  t
        j                        d   }
| j                  |
j                  |      d       |j	                  t
        j                        d   }| j                  |j                  |      d       |j	                  t
        j                        d   }| j                  |j                  |      d       |j	                  t
        j                        d   }| j                  |j                  |      d       y )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  r?  g       @	   g      B@r  g      C@   g      D@r  g      F@   g      L@   g      U@   g     U@   g      V@)	r  r  r  r  r:   r   r;   r  r  )r)   r  r  r<  rJ   m3m10m11m12m13m16m23m24r  s                 r   testTimeSigChangeszTest.testTimeSigChanges_  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                2   ddl m} |j                  dd      }|j                         j                  d   }|j                         j                  d   }| j                  |j                  j                  t        j                  d             | j                  |j                  t        j                  d             | j                  |j                  j                  t        j                  d             |j                  d	d      }|j                         j                  d   }|j                         j                  d   }| j                  |j                  j                  d
       | j                  |j                  d
       | j                  |j                  j                  d       |j                  dd      }|j                         j                  d   }|j                         j                  d   }| j                  |j                  j                  t        j                  d             | j                  |j                  t        j                  d             | j                  |j                  j                  t        j                  d             y )Nr   r  zm1 C: I b2.66 Vr  r  r4   g?g@z"TimeSignature: 6/8
m1 C: I b2.66 Vr  g      ?zm1 C: I b2.66.5 VgUUUUUU?gUUUUUU@)r  r  r  r  r  r  rF   r   r   opFracrh  )r)   r  rG  n1n2s        r   testTupletsz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                    ddl m} t        j                  d      }|j	                  |d      }|j
                  j                  dk(  sJ y )Nr   r  zx'
            Time Signature: 2/4
            m1 I
            m2 V
            m3 = m1
            m4-5 = m1-2
        r  r  r  )r  r  textwrapdedentr  rF   r   )r)   r  empty_measures_with_copyr<  s       r   testCopyEmptyMeasureszTest.testCopyEmptyMeasures  sF    %#+?? 4 $  OO4[OIzz''2---r   c                    ddl m} 	 	 	 	 	 	 	 	 	 	 d! fd}d" fd}	 	 	 	 	 	 d# fd}t        j                  d      }|j	                  |d      }|t
        j                     } j                  t        |      d	       |\  }}	 ||d
dd        ||	ddd	        ||d       t        j                  d      }
|j	                  |
d      }|t
        j                     } j                  t        |      d	       |\  }}	 ||d
dd        ||	ddd        ||d       t        j                  d      }|j	                  |d      }|t
        j                     } j                  t        |      d       |\  }}}} ||d
dd	        ||ddd        ||d
dd        ||ddd       |t        j                     D ]Z  }|t        j                     } j                  t        |      d        j                  |j                         j                  d       \  ||d       t        j                  d      }|j	                  |d      }|t
        j                     } j                  t        |      d       |\  }}} ||d
dd        ||ddd	        ||ddd	       |t        j                      } j                  t        |      d       |\  }}} ||dg        ||dg        ||dg        ||d       t        j                  d      }|j	                  |d      }|t
        j                     } j                  t        |      d       |t
        j                     \  }}} ||d
dd        ||ddd        ||ddd	       |t        j                      } j                  t        |      d       |\  }}} ||ddg        ||dg        ||ddg        ||d        y )$Nr   r  c                    j                  | j                  |       j                  | j                  |       j                  | j                  j                  |       y r-  )r  r  rh  
activeSiter<   )
repeat_barr  rh  mNumberr)   s       r   _repeat_testerz(Test.testRepeats.<locals>._repeat_tester  sM     Z119=Z..7Z22997Cr   c                    t        | t        j                           }t        j                  |      }j                  |j                                |j                         }j                  |j                  |       y r-  )
nextr   rx   r   Expanderr  repeatBarsAreCoherentprocessr  r   )r<  r   rJ   rI  p2r)   s        r   _test_expandedz(Test.testRepeats.<locals>._test_expanded  s[     Qv{{^$A"AOOA3356BR--}=r   c                    | t         j                     D cg c]  }|j                          }}j                  ||       y c c}w r-  )r   r;   measureNumberWithSuffixr  )rc  expectedMeasuresrL   measure_nosr)   s       r   _test_ending_contentsz/Test.testRepeats.<locals>._test_ending_contents  sF     AC6>>@RS@R11446@RKS[*:; Ts   AzS
            Time Signature: 3/4
            m1 ||: V
            m2 I :||
        r  r  r?  r   ru   r4   r  r  g      (@zB
            Time Signature: 2/4
            m1 ||: I :||
        g       @g      @zw
            Time Signature: 2/4
            m1 I
            m2 ||:
            m3 :||
            m4 ||: :||
        rA  r@  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      ;@)
rI  z
bar.Repeatr  r1   rh  r   rJ  r   r0   r1  )r<  zstream.Streamr   r   r0   r1  )rc  zspanner.RepeatBracketrU  z	list[str]r0   r1  )r  r  rB  rC  r  r   r  r  r9   r   r;   r   r@   r  rD   r   r`  )r)   r  rK  rR  rW  simple_repeatsr<  br_iterstart_repeat
end_repeatsingle_bar_repeatsempty_bars_with_repeatsstart_repeat1end_repeat1start_repeat2end_repeat2rg  rn_iterthree_endingsrb_iterfirst_endingsecond_endingthird_endingmore_complex_examples   `                       r   testRepeatszTest.testRepeats  s   %	D"	D/2	D<A	DLO	D	D	>	<%	<9B	<	< " * 
 OON;O?CJJ-Wq)#* j|Wc15z5#q1q$%__ .  OO.{OCCJJ-Wq)#* j|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.k;|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::.k;|Wc15{E32{E32G))*Wq)4;1m\lT4L9mdV4lT4L9q$r   N)r0   r1  )r   r   r   r  r  r  r  r  r  r  r  r  r  r  r  r!  r+  r;  r@  rE  rn  r   r   r   r  r  V  sd     "_"_&_50H4,]:82'(;.	03$0&7FK.
.z r   r  z
list[type]
_DOC_ORDER__main__)rZ   r/  rJ   zstream.PartrK   zkey.Key | Noner-  )rQ  r/  rL   r0  r   dict):r3  
__future__r   r=   rB  r   typingr   unittestr  r   r   r   music21.common.typesr   r   r	   r
   r   r   r   r   r   r   r  r   r   r   r   Environmentr   ry   r%  r   r   ElementWrapperr!   Music21Objectr#   rT   r`   ro   rp   __annotations__rr   r>  rP  r   r^  r   r   r~  TestCaser  r  ro  r   mainTestr   r   r   <module>r|     s  lZ #         )           '   &{&&'<=  	,"?"? 		 3 3 	*4#5#5 *3l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GT r   