
    rh0                      % S r SSKJr  / SQ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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&                  (       a4  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  \	R:                  " S5      r\R>                  " S5      r / SQr!\! V s0 s H  o S   U S   _M     sn r"0 r#S\$S'   \RJ                  " S5      r&\RJ                  " S5      r'\RJ                  " S5      r(\RJ                  " S5      r)\RJ                  " S5      r*\RJ                  " S5      r+ " S  S!\RX                  5      r- " S" S#\RX                  5      r. " S$ S%\RX                  5      r/ " S& S'\R`                  \Rb                  Rd                  5      r3 " S( S)\35      r4 " S* S+\35      r5 " S, S-\35      r6 " S. S/\35      r7 " S0 S1\35      r8 " S2 S3\35      r9 " S4 S5\35      r: " S6 S7\35      r; " S8 S9\35      r< " S: S;\35      r= " S< S=\35      r> " S> S?\35      r? " S@ SA\35      r@ " SB SC\35      rA " SD SE\35      rB " SF SG\35      rC " SH SI\35      rD " SJ SK\35      rE " SL SM\E5      rF " SN SO5      rG " SP SQ\G5      rHSXSR jrI " SS ST\R`                  5      rJ " SU SV\
R                  5      rL\J\G\H/rM\NSW:X  a  SSKr\R                  " \L5        ggs  sn f )Ya  
ABC is a music format that, while being able to encode all sorts of scores, is especially
strong at representing monophonic music, and folk music in particular.

Modules in the `music21.abcFormat` package deal with importing ABC into music21.  Most people
working with ABC data won't need to use this package.  To convert ABC from a file or URL
to a :class:`~music21.stream.Stream` use the :func:`~music21.converter.parse` function of
the `converter` module:

>>> #_DOCS_SHOW from music21 import *
>>> #_DOCS_SHOW abcScore = converter.parse('/users/ariza/myScore.abc')

For users who will be editing ABC extensively or need a way to have music21 output ABC
(which it doesn't do natively), we suggest using the open source EasyABC package:
https://easyabc.sourceforge.net .  You can set it up as a MusicXML reader through:

>>> #_DOCS_SHOW us = environment.UserSettings()
>>> #_DOCS_SHOW us['musicxmlPath'] = '/Applications/EasyABC.app'

or wherever you have downloaded EasyABC to
(PC users might need: 'c:/program files (x86)/easyabc/easyabc.exe')
(Thanks to Norman Schmidt for the heads-up)

There is a two-step process in converting ABC files to music21 Streams.  First this module
reads in the text-based .abc file and converts all the information into ABCToken objects.  Then
the function :func:`music21.abcFormat.translate.abcToStreamScore` of
the :ref:`moduleAbcFormatTranslate` module
translates those Tokens into music21 objects.

Music21 implements the entire v1.6 ABC standard (January 1997) found at
https://abcnotation.com/standard/abc_v1.6.txt .  The system aims to support the
v2.1 ABC standard (December 2011) found at
https://abcnotation.com/wiki/abc:standard:v2.1 but some parts (e.g. 4.10 Variant Endings) are not
implemented.  No support is yet given for the draft 2.2 standard.
    )annotations)	translate	testFilesABCTokenExceptionABCHandlerExceptionABCFileExceptionABCTokenABCMetadataABCBar	ABCTupletABCTieABCSlurStartABCParenStopABCCrescStartABCDimStartABCStaccatoABCUpbow
ABCDownbow	ABCAccentABCStraccent	ABCTenutoABCGraceStartABCGraceStopABCBrokenRhythmMarkerABCNoteABCChord
ABCHandlerABCHandlerBarmergeLeadingMetaDataABCFile)SequenceN)common)defaults)environment)exceptions21)prebase)r   barclefdurationdynamicskeymetertempospanner_T	abcFormat)):|1zlight-heavy-repeat-end-first):|2zlight-heavy-repeat-end-second)|]zlight-heavy)||zlight-light)z[|zheavy-light)[1regular-first)[2regular-second)|1r>   )|2r@   ):|zlight-heavy-repeat-end)|:zheavy-light-repeat-start)::z heavy-heavy-repeat-bidirectional)|regular):dotted   z3dict[tuple[str, str, str], tuple[str, bool | None]]_pitchTranslationCachez[A-Zw]:z	[a-gA-Gz]z"[^"]*"z[.*?]z%abc-(\d+)\.(\d+)\.?(\d+)?z^%%([a-z\-]+)\s+(\S+)(.*)c                      \ rS rSrSrg)r       N__name__
__module____qualname____firstlineno____static_attributes__rN       T/home/james-whalen/.local/lib/python3.13/site-packages/music21/abcFormat/__init__.pyr   r          rU   r   c                      \ rS rSrSrg)r      rN   NrO   rN   rU   rV   r   r      rW   rU   r   c                      \ rS rSrSrg)r      rN   NrO   rN   rU   rV   r   r      rW   rU   r   c                  P    \ rS rSrSrSrS
SS jjrS r\SS j5       r	S r
S rSrg	)r	      a  
ABC processing works with a multi-pass procedure. The first pass
breaks the data stream into a list of ABCToken objects. ABCToken
objects are specialized in subclasses.

The multi-pass procedure is conducted by an ABCHandler object.
The ABCHandler.tokenize() method breaks the data stream into
ABCToken objects. The :meth:`~music21.abcFormat.ABCHandler.tokenProcess` method first
calls the :meth:`~music21.abcFormat.ABCToken.preParse` method on each token,
then does contextual
adjustments to all tokens, then calls :meth:`~music21.abcFormat.ABCToken.parse` on all tokens.

The source ABC string itself is stored in self.src.

Because of how copying ABCTokens works, all tokens must have default parameters in their
initializers
srcc                    Xl         g Nr^   )selfr_   s     rV   __init__ABCToken.__init__   s    rU   c                ,    [        U R                  5      $ ra   )reprr_   rb   s    rV   _reprInternalABCToken._reprInternal   s    DHH~rU   c                :    SU ;   a  U R                  S5      S   $ U $ )a  
removes ABC-style comments from a string:

>>> ao = abcFormat.ABCToken()
>>> ao.stripComment('asdf')
'asdf'
>>> ao.stripComment('asdf%234')
'asdf'
>>> ao.stripComment('asdf  %     234')
'asdf  '
>>> ao.stripComment('[ceg]% this chord appears 50% more often than other chords do')
'[ceg]'

This is a static method, so it can also be called on the class itself:

>>> abcFormat.ABCToken.stripComment('b1 % a b-flat actually')
'b1 '

* Changed in v6.2: made a staticmethod
%r   )split)strSrcs    rV   stripCommentABCToken.stripComment   s$    , &=<<$Q''rU   c                    g)ze
Dummy method that is called before contextual adjustments.
Designed to be subclassed or overridden.
NrN   rg   s    rV   preParseABCToken.preParse   s    
 	rU   c                    g)z
Dummy method that reads self.src and loads attributes.
It is called after contextual adjustments.

It is designed to be subclassed or overridden.
NrN   rg   s    rV   parseABCToken.parse   s     	rU   N r_   str)rm   ry   returnry   )rP   rQ   rR   rS   __doc__	__slots__rc   rh   staticmethodrn   rq   rt   rT   rN   rU   rV   r	   r	      s6    " I  2rU   r	   c                     ^  \ rS rSrSrSrSSU 4S jjj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S jrSS jrSS jrSS jrSS jrSS jrSS jrS S jrS!S jrS"S jrS#S jrSrU =r$ )$r
      a?  
Defines a token of metadata in ABC.

>>> md = abcFormat.ABCMetadata('I:linebreak')
>>> md.src
'I:linebreak'

Has two attributes, `tag` and `data` which are strings.
Initially both are set to '':

>>> md.tag
''

After calling `preParse()`, these are separated:

>>> md.preParse()
>>> md.tag
'I'
>>> md.data
'linebreak'
)tagdatac                @   > [         TU ]  U5        SU l        SU l        g Nrw   )superrc   r   r   rb   r_   	__class__s     rV   rc   ABCMetadata.__init__   s    	rU   c                    [         R                  U R                  5      =n(       aP  UR                  5       nU R	                  U R                  5      nUSUS-
   U l        X2S R                  5       U l        gg)z
Called before contextual adjustments and needs
to have access to data.  Divides a token into
.tag (a single capital letter or w) and .data representations.

>>> x = abcFormat.ABCMetadata('T:tagData')
>>> x.preParse()
>>> x.tag
'T'
>>> x.data
'tagData'
NrJ   )reMetadataTagmatchr_   endrn   r   stripr   )rb   r   divrm   s       rV   rq   ABCMetadata.preParse   sh     "''1151))+C&&txx0FhsQw'DHt**,DI	 2rU   c                    g ra   rN   rg   s    rV   rt   ABCMetadata.parse
  s    rU   c                &    U R                   S:X  a  gg)z2
Returns True if the tag is "L", False otherwise.
LTFr   rg   s    rV   isDefaultNoteLengthABCMetadata.isDefaultNoteLength       88s?rU   c                &    U R                   S:X  a  gg)z
Returns True if the tag is "X", False otherwise.

>>> x = abcFormat.ABCMetadata('X:5')
>>> x.preParse()
>>> x.tag
'X'
>>> x.isReferenceNumber()
True
XTFr   rg   s    rV   isReferenceNumberABCMetadata.isReferenceNumber  s     88s?rU   c                f    U R                   S:X  a!  U R                  R                  S5      (       a  gg)aE  
Returns True if the tag is "I" for "Information" and
the data is "abc-version", False otherwise.

>>> x = abcFormat.ABCMetadata('I:abc-version 2.1')
>>> x.preParse()
>>> x.tag
'I'
>>> x.isVersion()
True

>>> deer = abcFormat.ABCMetadata('I:abc-venison yummy')
>>> deer.preParse()
>>> deer.tag
'I'
>>> deer.isVersion()
False
Izabc-version TF)r   r   
startswithrg   s    rV   	isVersionABCMetadata.isVersion$  s)    & 88s?tyy33NCCrU   c                &    U R                   S:X  a  gg)z<
Returns True if the tag is "M" for meter, False otherwise.
MTFr   rg   s    rV   isMeterABCMetadata.isMeter;  r   rU   c                &    U R                   S:X  a  gg)z<
Returns True if the tag is "T" for title, False otherwise.
TTFr   rg   s    rV   isTitleABCMetadata.isTitleC  r   rU   c                &    U R                   S:X  a  gg)z?
Returns True if the tag is "C" for composer, False otherwise.
CTFr   rg   s    rV   
isComposerABCMetadata.isComposerK  r   rU   c                &    U R                   S:X  a  gg)z~
Returns True if the tag is "O" for origin, False otherwise.
This value is set in the Metadata `localOfComposition` of field.
OTFr   rg   s    rV   isOriginABCMetadata.isOriginS  s    
 88s?rU   c                &    U R                   S:X  a  gg)z2
Returns True if the tag is "V", False otherwise.
VTFr   rg   s    rV   isVoiceABCMetadata.isVoice\  r   rU   c                &    U R                   S:X  a  gg)z
Returns True if the tag is "K", False otherwise.
Note that in some cases a Key will encode clef information.

(example from corpus: josquin/laDeplorationDeLaMorteDeJohannesOckeghem.abc)
KTFr   rg   s    rV   isKeyABCMetadata.isKeyd  s     88s?rU   c                &    U R                   S:X  a  gg)z<
Returns True if the tag is "Q" for tempo, False otherwise.
QTFr   rg   s    rV   isTempoABCMetadata.isTempoo  r   rU   c                   U R                  5       (       d  [        S5      eU R                  R                  5       S:X  a  gU R                  S:X  a  Su  pSnOU R                  S:X  a  Su  pS	nOU R                  R	                  S
5      u  pE[        [        R                  " UR                  5       5      S   5      n[        [        R                  " UR                  5       5      S   5      nSnXU4$ )a  
If there is a time signature representation available,
get a numerator, denominator and an abbreviation symbol.
To get a music21 :class:`~music21.meter.TimeSignature` object, use
the :meth:`~music21.abcFormat.ABCMetadata.getTimeSignatureObject` method.

>>> am = abcFormat.ABCMetadata('M:2/2')
>>> am.preParse()
>>> am.isMeter()
True
>>> am.getTimeSignatureParameters()
(2, 2, 'normal')

>>> am = abcFormat.ABCMetadata('M:C|')
>>> am.preParse()
>>> am.getTimeSignatureParameters()
(2, 2, 'cut')

>>> am = abcFormat.ABCMetadata('M: none')
>>> am.preParse()
>>> am.getTimeSignatureParameters() is None
True

>>> am = abcFormat.ABCMetadata('M: FREI4/4')
>>> am.preParse()
>>> am.getTimeSignatureParameters()
(4, 4, 'normal')
z/no time signature associated with this metadatanoneNr   )   r   r"   C|)   r   cut/r   normal)	r   r   r   lowerrl   intr"   getNumFromStrr   )rb   ndsymbolnStrdStrs         rV   getTimeSignatureParameters&ABCMetadata.getTimeSignatureParametersw  s    : ||~~#$UVV
 99??&YY#DAFYY$DAF-JD F((6q9:AF((6q9:AFV|rU   c                    U R                  5       (       d  [        S5      eSSKJn  U R	                  5       nUc  gUu  p4nUR
                  " U SU 35      $ )aU  
Return a music21 :class:`~music21.meter.TimeSignature`
object for this metadata tag, if isMeter is True, otherwise raise exception.

>>> am = abcFormat.ABCMetadata('M:2/2')
>>> am.preParse()
>>> ts = am.getTimeSignatureObject()
>>> ts
<music21.meter.TimeSignature 2/2>

>>> am = abcFormat.ABCMetadata('Q:40')
>>> am.getTimeSignatureObject()
Traceback (most recent call last):
music21.abcFormat.ABCTokenException: no time signature associated with
    this non-metrical metadata.

>>> am = abcFormat.ABCMetadata('M:none')
>>> am.preParse()
>>> ts = am.getTimeSignatureObject()
>>> ts is None
True
z=no time signature associated with this non-metrical metadata.r   r1   Nr   )r   r   music21r2   r   TimeSignature)rb   r2   
parameters	numeratordenominatorunused_symbols         rV   getTimeSignatureObject"ABCMetadata.getTimeSignatureObject  sa    . ||~~#OQ Q!446
4>1IM&&)Ak]'CDDrU   c                r   SSK Jn  U R                  5       (       d  [        S5      e/ SQnSnSn[	        U[
        SS9 H^  nXPR                  S	[        U5       R                  5       :X  d  M.  U R                  S	[        U5       nU R                  [        U5      S	 n  O   [        U5      S
:  a  US
   S:X  a  US   S-   nS	nUR                  5       nUS:X  a  SnO5UR                  5       nS H  u  pUR                  U5      (       d  M  U	n  O   US:X  a  SnS	nO
US:X  a  SnS	nUR                  " X65      U4$ )a  
Extract key signature parameters,
returning the number of sharps and the mode.

>>> am = abcFormat.ABCMetadata('K:Eb Lydian')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(-2, 'lydian')

>>> am = abcFormat.ABCMetadata('K:APhry')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(-1, 'phrygian')

>>> am = abcFormat.ABCMetadata('K:G Mixolydian')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(0, 'mixolydian')

>>> am = abcFormat.ABCMetadata('K: Edor')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(2, 'dorian')

>>> am = abcFormat.ABCMetadata('K: F')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(-1, 'major')

>>> am = abcFormat.ABCMetadata('K:G')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(1, 'major')

>>> am = abcFormat.ABCMetadata('K:Gm')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(-2, 'minor')

>>> am = abcFormat.ABCMetadata('K:Hp')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(2, None)

>>> am = abcFormat.ABCMetadata('K:G ionian')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(1, 'ionian')

>>> am = abcFormat.ABCMetadata('K:G aeol')
>>> am.preParse()
>>> am.getKeySignatureParameters()
(-2, 'aeolian')
r   r/   z/no key signature associated with this metadata.)cgr   aebzf#zg#za#fbbebzd#abze#dbzc#gbcbhpr   rw   T)r0   reverseNrJ   r   -major))dordorian)phrphrygian)lydlydian)mix
mixolydian)majr   )ionionian)aeoaeolian)mminorHPHpD)r   r0   r   r   sortedlenr   r   r   r   pitchToSharps)
rb   r0   keyNameMatchstandardKeyStrstringRemaintargetmodemodeCandidater   modeStrs
             rV   getKeySignatureParameters%ABCMetadata.getKeySignatureParameters  sP   r 	 zz||#$UVV \sDAF<CK06688!%<CK!8#yyV6 B ~"~a'8C'?+A.4N#))+2D )..0M	# !++E22"D	#  T! NDt# ND
   6<<rU   c                    U R                  5       (       d  [        S5      eSSKJn  U R	                  5       u  p#UR
                  " U5      nUS;   a  U$ UR                  U5      $ )a  
Return a music21 :class:`~music21.key.KeySignature` or :class:`~music21.key.Key`
object for this metadata tag.


>>> am = abcFormat.ABCMetadata('K:G')
>>> am.preParse()
>>> ks = am.getKeySignatureObject()
>>> ks
<music21.key.Key of G major>

>>> am = abcFormat.ABCMetadata('K:Gmin')
>>> am.preParse()
>>> ks = am.getKeySignatureObject()
>>> ks
<music21.key.Key of g minor>
>>> ks.sharps
-2

Note that capitalization does not matter
(http://abcnotation.com/wiki/abc:standard:v2.1#kkey)
so this should still be minor.

>>> am = abcFormat.ABCMetadata('K:GM')
>>> am.preParse()
>>> ks = am.getKeySignatureObject()
>>> ks
<music21.key.Key of g minor>
z.no key signature associated with this metadatar   r/   r   )r   r   r   r0   r  KeySignatureasKey)rb   r0   sharpsr  kss        rV   getKeySignatureObject!ABCMetadata.getKeySignatureObjectD  s\    B zz||#$TUU 557f%:I88D>!rU   c                &   U R                  5       (       d  [        S5      eSSKJn  SnSnSU R                  R                  5       ;   a  UR                  " 5       nSnX#4$ SU R                  R                  5       ;   a  UR                  " 5       nSnX#4$ )	af  
Extract any clef parameters stored in the key metadata token.
Assume that a clef definition suggests a transposition.
Return both the Clef and the transposition.

Returns a two-element tuple of clefObj and transposition in semitones

>>> am = abcFormat.ABCMetadata('K:Eb Lydian bass')
>>> am.preParse()
>>> am.getClefObject()
(<music21.clef.BassClef>, -24)
zNno key signature associated with this metadata; needed for getting Clef Objectr   r)   Nz-8vaibassi)r   r   r   r*   r   r   Treble8vbClefBassClef)rb   r*   clefObjtransposeSemitoness       rV   getClefObjectABCMetadata.getClefObjectq  s     zz||#`b b 	!"&!TYY__&&((*G!$ ** tyy((mmoG!$ **rU   c                   U R                  5       (       d  [        S5      eSnSSKJn  SnSU R                  ;   a  / n/ nSnU R                   HP  nUS:X  a  U(       d  SnM  US:X  a  U(       a  SnM%  U(       a  UR                  U5        M?  UR                  U5        MR     SR                  U5      R                  5       nSR                  U5      R                  5       nOU R                  R                  5       nS	n	Sn
U(       a  S
U;   a  UR                  S
5      u  p[        U5      n	Sn
UR                  S5       HU  nSU;   a  UR                  S5      u  pO[        R                  SU/5        Su  pU
[        U5      [        U5      -  S-  -  n
MW     O[        U5      n	U(       d  U	b#  UR                  " U=(       d    SU	S	:w  a  U	OSU
S9nU$ )aI  
Extract any tempo parameters stored in a tempo metadata token.

>>> am = abcFormat.ABCMetadata('Q: "Allegro" 1/4=120')
>>> am.preParse()
>>> am.getMetronomeMarkObject()
<music21.tempo.MetronomeMark Allegro Quarter=120>

>>> am = abcFormat.ABCMetadata('Q: 3/8=50 "Slowly"')
>>> am.preParse()
>>> am.getMetronomeMarkObject()
<music21.tempo.MetronomeMark Slowly Dotted Quarter=50>

>>> am = abcFormat.ABCMetadata('Q:1/2=120')
>>> am.preParse()
>>> am.getMetronomeMarkObject()
<music21.tempo.MetronomeMark animato Half=120>

>>> am = abcFormat.ABCMetadata('Q:1/4 3/8 1/4 3/8=40')
>>> am.preParse()
>>> am.getMetronomeMarkObject()
<music21.tempo.MetronomeMark grave Whole tied to Quarter (5 total QL)=40>

>>> am = abcFormat.ABCMetadata('Q:90')
>>> am.preParse()
>>> am.getMetronomeMarkObject()
<music21.tempo.MetronomeMark maestoso Quarter=90>
z&no tempo associated with this metadataNr   r3   "FTrw   =         r   *incorrectly encoded / unparsable duration:)1r  r   )textnumberreferent)r   r   r   r4   r   appendjoinr   rl   floatenvironLocal
printDebugMetronomeMark)rb   mmObjr4   tempoStrtempoStrListnonTextListisOpencharnonTextr  r  durs	numberStrdurr   r   s                   rV   getMetronomeMarkObject"ABCMetadata.getMetronomeMarkObject  s   : ||~~#$LMM!$))LKF		3;v!F3;6"F ''-&&t, " ww|,224Hggk*002Giioo'G #g~")--"4y)::c?Ccz"yy~1$//1]_b0cd'qE!H!4 99H + wv)''X-=9?2v419;E rU   c                   U R                  5       (       ap  SU R                  ;   a`  U R                  R                  S5      u  p[        UR	                  5       5      nUS:X  a  SnO[        UR	                  5       5      nUS-  U-  $ U R                  5       (       a#  U R                  5       nUc  gUu  p4nX4-  S:  a  gg[        SU R                   35      e)a  
If there is a quarter length representation available, return it as a floating point value

>>> am = abcFormat.ABCMetadata('L:1/2')
>>> am.preParse()
>>> am.getDefaultQuarterLength()
2.0

>>> am = abcFormat.ABCMetadata('L:1/8')
>>> am.preParse()
>>> am.getDefaultQuarterLength()
0.5

>>> am = abcFormat.ABCMetadata('M:C|')
>>> am.preParse()
>>> am.getDefaultQuarterLength()
0.5


If taking from meter, find the "fraction" and if < 0.75 use sixteenth notes.
If >= 0.75 use eighth notes.

>>> am = abcFormat.ABCMetadata('M:2/4')
>>> am.preParse()
>>> am.getDefaultQuarterLength()
0.25

>>> am = abcFormat.ABCMetadata('M:3/4')
>>> am.preParse()
>>> am.getDefaultQuarterLength()
0.5


>>> am = abcFormat.ABCMetadata('M:6/8')
>>> am.preParse()
>>> am.getDefaultQuarterLength()
0.5


Meter is only used for default length if there is no L:

>>> x = 'L:1/4\nM:3/4\n\nf'
>>> sc = converter.parse(x, format='abc')
>>> sc.recurse().notes.first().duration.type
'quarter'
r   Gr         ?g      ?      ?z1no quarter length associated with this metadata: )r   r   rl   r   r   r   r   r   )rb   r   r   r   r   r   r   s          rV   getDefaultQuarterLength#ABCMetadata.getDefaultQuarterLength  s    ` ##%%#*:-JDDJJL!A s{

%q519\\^^88:J!",A-ut|#CDII;OQ QrU   )r   r   rv   rx   rz   Nonerz   bool)rz   ztuple[int, int, str] | None)rz   meter.TimeSignature | None)rz   ztuple[int, str | None])rz   z(t.Union[key.Key, key.KeySignature, None])rz   z#tuple[clef.Clef | None, int | None])rz   ztempo.MetronomeMark | None)rz   r"  )rP   rQ   rR   rS   r{   r|   rc   rq   rt   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r0  r6  rT   __classcell__r   s   @rV   r
   r
      s    *  I 
-&.	2h EDu=n+"Z+@PdIQ IQrU   r
   c                  b   ^  \ rS rSrSrSrU 4S jrSS jrSS jrSS jr	SS jr
SS	 jrS
rU =r$ )r   i/  za
An ABCBar token represents a barline, possibly with repeat information.

Currently 4.10 Variant
)barTypebarStyle
repeatFormc                N   > [         TU ]  U5        SU l        SU l        SU l        g r   )r   rc   r@  rA  rB  r   s     rV   rc   ABCBar.__init__9  s%    rU   c                   U R                   R                  5       nU[        ;  a  g[        U   nUR                  S5      nSU;   a  SU l        OSU;   d  SU;   a  SU l        OSU l        [        U5      S:X  a  US   U l        OL[        U5      S	:  a=  SU;   a  S
U l        SU l        O(SU;   a  S
U l        SU l        OUS   S-   US   -   U l        [        U5      S	:  a  US   U l        gg)a  
Assign the bar-type based on the source string.

>>> ab = abcFormat.ABCBar('|')
>>> ab.parse()
>>> ab
<music21.abcFormat.ABCBar '|'>

>>> ab.barType
'barline'
>>> ab.barStyle
'regular'

>>> ab = abcFormat.ABCBar('||')
>>> ab.parse()
>>> ab.barType
'barline'
>>> ab.barStyle
'light-light'

>>> ab = abcFormat.ABCBar('|:')
>>> ab.parse()
>>> ab.barType
'repeat'
>>> ab.barStyle
'heavy-light'
>>> ab.repeatForm
'start'
Nr   repeatfirstsecondbarlinerJ   r   r   rG      )r_   r   ABC_BARS_DICTrl   r@  r   rA  rB  )rb   	src_stripbarTypeStringbarTypeComponentss       rV   rt   ABCBar.parse?  s   < )	M)%i0 *//4((#DL**..$DL %DL  !Q&-a0DM "#q( ++ )").. )"* 1! 4s :=Nq=Q Q  !A%/2DO &rU   c                &    U R                   S:X  a  gg)NrF  TF)r@  rg   s    rV   isRepeatABCBar.isRepeat  s    <<8#rU   c                F    U R                   S:w  a  U R                  S:X  a  gg)z
Return True if this is a regular, single, light bar line.

>>> ab = abcFormat.ABCBar('|')
>>> ab.parse()
>>> ab.isRegular()
True
rF  rG   TF)r@  rA  rg   s    rV   	isRegularABCBar.isRegular  s!     <<8#(BrU   c                H    U R                   S:X  a  gU R                   S:X  a  gg)z
Return a number if this defines a repeat bracket for an alternate ending
otherwise returns False.

>>> ab = abcFormat.ABCBar('[2')
>>> ab.parse()
>>> ab.isRepeat()
False
>>> ab.isRepeatBracket()
2
rG  rJ   rH  r   F)rB  rg   s    rV   isRepeatBracketABCBar.isRepeatBracket  s%     ??g%__(rU   c                l   SSK Jn  U R                  5       (       aT  U R                  S;   a  UR                  " U R                  S9nU$ [
        R                  SU R                   3/5        Sn U$ U R                  S:X  a  SnU$ U R                  S;   a  SnU$ UR                  " U R                  5      nU$ )	z
Return a music21 bar object

>>> ab = abcFormat.ABCBar('|:')
>>> ab.parse()
>>> barObject = ab.getBarObject()
>>> barObject
 <music21.bar.Repeat direction=start>
r   r'   )r   start)	directionz(found an unsupported repeatForm in ABC: NrG   )rG  rH  )	r   r(   rQ  rB  Repeatr#  r$  rA  Barline)rb   r(   m21bars      rV   getBarObjectABCBar.getBarObject  s     	 ==??"22doo>  ''??PQR   ]]i'F  __ 33F  [[/FrU   )rA  r@  rB  r8  r:  )rz   zint | t.Literal[False])rz   zbar.Barline | None)rP   rQ   rR   rS   r{   r|   rc   rt   rQ  rT  rW  r_  rT   r=  r>  s   @rV   r   r   /  s4     6IC3J& rU   r   c                  X   ^  \ rS rSrSrSrSSU 4S jjjr S	   S
S jjrSS jrSr	U =r
$ )r   i  zo
ABCTuplet tokens always precede the notes they describe.

In ABCHandler.tokenProcess(), rhythms are adjusted.
)	noteCountnumberNotesActualnumberNotesNormal	tupletObjc                \   > [         TU ]  U5        SU l        SU l        SU l        S U l        g )Nr  rJ   )r   rc   rb  rc  rd  re  r   s     rV   rc   ABCTuplet.__init__  s6     ! ') '( 04rU   c                   Uc  SnOUR                   S:X  a  SnOSnU R                  R                  5       R                  S5      nUS   nSn[	        U5      S:  a  US   S:w  a  [        US   5      nUS:X  a  S	u  pgOdUS
:X  a  Su  pgOYUS:X  a  Su  pgONUS:X  a  Su  pgOCUS:X  a  SUpvO9US:X  a  Su  pgO.US:X  a  SUpvO$US:X  a  Su  pgOUS:X  a  SUpvO[        SU< 35      eUc  UnX`l        XPl        g)a  
Cannot be called until local meter context
is established.

>>> at = abcFormat.ABCTuplet('(3')
>>> at.updateRatio()
>>> at.numberNotesActual, at.numberNotesNormal
(3, 2)

Generally a 5:n tuplet is 5 in the place of 2.

>>> at = abcFormat.ABCTuplet('(5')
>>> at.updateRatio()
>>> at.numberNotesActual, at.numberNotesNormal
(5, 2)

Unless it's in a meter.TimeSignature compound (triple) context:

>>> at = abcFormat.ABCTuplet('(5')
>>> at.updateRatio(meter.TimeSignature('6/8'))
>>> at.numberNotesActual, at.numberNotesNormal
(5, 3)

Six is 6:2, not 6:4!

>>> at = abcFormat.ABCTuplet('(6')
>>> at.updateRatio()
>>> at.numberNotesActual, at.numberNotesNormal
(6, 2)

>>> at = abcFormat.ABCTuplet('(6:4')
>>> at.updateRatio()
>>> at.numberNotesActual, at.numberNotesNormal
(6, 4)

>>> at = abcFormat.ABCTuplet('(6::6')
>>> at.updateRatio()
>>> at.numberNotesActual, at.numberNotesNormal
(6, 2)

2 is 2 in 3...

>>> at = abcFormat.ABCTuplet('(2')
>>> at.updateRatio()
>>> at.numberNotesActual, at.numberNotesNormal
(2, 3)


Some other types:

>>> for n in 1, 2, 3, 4, 5, 6, 7, 8, 9:
...     at = abcFormat.ABCTuplet(f'({n}')
...     at.updateRatio()
...     print(at.numberNotesActual, at.numberNotesNormal)
1 1
2 3
3 2
4 3
5 2
6 2
7 2
8 3
9 2

Tuplets > 9 raise an exception:

>>> at = abcFormat.ABCTuplet('(10')
>>> at.updateRatio()
Traceback (most recent call last):
music21.abcFormat.ABCTokenException: cannot handle tuplet of form: '(10'
Nr   rJ  rH   r   rJ   rw   z(1rJ   rJ   z(2)r   rJ  z(3)rJ  r   z(4)r   rJ  z(5   z(6)   r   z(7   z(8)   rJ  z(9	   zcannot handle tuplet of form: )	beatDivisionCountr_   r   rl   r   r   r   rc  rd  )rb   timeSignatureObjnormalSwitchsplitTuplettupletNumbernormalNotesr   r   s           rV   updateRatioABCTuplet.updateRatio  s7   X #L//14LLhhnn&,,S1"1~ ${q [^r%9k!n-K 4DAqT!DAqT!DAqT!DAqT!lqT!DAqT!lqT!DAqT!lq#&D\DT$UVVK!"!,rU   c                f   U R                   S:X  a  [        S5      eSSKJn  UR                  " U R                   U R
                  S9U l        U R                  R                  5       R                  S5      n[        U5      S:  a  US   S	:w  a  [        US   5      U l        g
U R                   U l        g
)a  
Update the note count of notes that are
affected by this tuplet. Can be set by p:q:r style tuplets.
Also creates a tuplet object.

>>> at = abcFormat.ABCTuplet('(6')
>>> at.updateRatio()
>>> at.updateNoteCount()
>>> at.noteCount
6
>>> at.tupletObj
<music21.duration.Tuplet 6/2>

>>> at = abcFormat.ABCTuplet('(6:4:12')
>>> at.updateRatio()
>>> at.updateNoteCount()
>>> at.noteCount
12
>>> at.tupletObj
<music21.duration.Tuplet 6/4>

>>> at = abcFormat.ABCTuplet('(6::18')
>>> at.updateRatio()
>>> at.updateNoteCount()
>>> at.noteCount
18
r  z-must set numberNotesActual with updateRatio()r   r+   )rc  rd  rH   rJ  r   rw   N)rc  r   r   r,   Tupletrd  re  r_   r   rl   r   r   rb  )rb   r,   rr  s      rV   updateNoteCountABCTuplet.updateNoteCount[  s    8 !!R'#$STT 	%!"44"446
 hhnn&,,S1{q [^r%9 Q0DN!33DNrU   rv   rx   ra   )rp  r<  rz   r9  r8  )rP   rQ   rR   rS   r{   r|   rc   ru  ry  rT   r=  r>  s   @rV   r   r     sD    
 UI4 4$ 6:v-2v- 
v-p*4 *4rU   r   c                  4   ^  \ rS rSrSrSrSU 4S jjrSrU =r$ )r   i  z
Handles instances of ties '-' between notes in an ABC score.
Ties are treated as an attribute of the note before the '-';
the note after is marked as the end of the tie.
)noteObjc                2   > [         TU ]  U5        S U l        g ra   )r   rc   r|  r   s     rV   rc   ABCTie.__init__  s    rU   rv   )	rP   rQ   rR   rS   r{   r|   rc   rT   r=  r>  s   @rV   r   r     s    
 I rU   r   c                  >   ^  \ rS rSrSrSrSSU 4S jjjrS rSrU =r	$ )r   i  zu
ABCSlurStart tokens always precede the notes in a slur.
For nested slurs, each open parenthesis gets its own token.
)slurObjc                2   > [         TU ]  U5        S U l        g ra   )r   rc   r  r   s     rV   rc   ABCSlurStart.__init__  s    *.rU   c                <    SSK Jn  UR                  " 5       U l        g)z
Creates a spanner object for each open paren associated with a slur;
these slurs are filled with notes until end parens are read.
r   r5   N)r   r6   Slurr  )rb   r6   s     rV   fillSlurABCSlurStart.fillSlur  s    
 	$||~rU   rv   rx   )
rP   rQ   rR   rS   r{   r|   rc   r  rT   r=  r>  s   @rV   r   r     s#     I/ /& &rU   r   c                      \ rS rSrSrSrSrg)r   i  zU
A general parenthesis stop;
comes at the end of a tuplet, slur, or dynamic marking.
rN   NrP   rQ   rR   rS   r{   r|   rT   rN   rU   rV   r   r          IrU   r   c                  B   ^  \ rS rSrSrSrSSU 4S jjjrSS jrSrU =r	$ )	r   i  z
ABCCrescStart tokens always precede the notes in a crescendo.
These tokens coincide with the string "!crescendo(";
the closing string "!crescendo)" counts as an ABCParenStop.
)crescObjc                2   > [         TU ]  U5        S U l        g ra   )r   rc   r  r   s     rV   rc   ABCCrescStart.__init__  s    15rU   c                <    SSK Jn  UR                  " 5       U l        g Nr   r-   )r   r.   	Crescendor  rb   r.   s     rV   	fillCrescABCCrescStart.fillCresc  s    $ **,rU   rv   rx   r8  )
rP   rQ   rR   rS   r{   r|   rc   r  rT   r=  r>  s   @rV   r   r     s#    
 I6 6- -rU   r   c                  >   ^  \ rS rSrSrSrSSU 4S jjjrS rSrU =r	$ )r   i  zq
ABCDimStart tokens always precede the notes in a diminuendo.
They function identically to ABCCrescStart tokens.
)dimObjc                2   > [         TU ]  U5        S U l        g ra   )r   rc   r  r   s     rV   rc   ABCDimStart.__init__  s    04rU   c                <    SSK Jn  UR                  " 5       U l        g r  )r   r.   
Diminuendor  r  s     rV   fillDimABCDimStart.fillDim  s    $))+rU   rv   rx   )
rP   rQ   rR   rS   r{   r|   rc   r  rT   r=  r>  s   @rV   r   r     s#     I5 5, ,rU   r   c                      \ rS rSrSrSrSrg)r   i  zY
ABCStaccato tokens "." precede a note or chord;
they are a property of that note/chord.
rN   Nr  rN   rU   rV   r   r     r  rU   r   c                      \ rS rSrSrSrSrg)r   i  zV
ABCUpbow tokens "u" precede a note or chord;
they are a property of that note/chord.
rN   Nr  rN   rU   rV   r   r     r  rU   r   c                      \ rS rSrSrSrSrg)r   i  zX
ABCDownbow tokens "v" precede a note or chord;
they are a property of that note/chord.
rN   Nr  rN   rU   rV   r   r     r  rU   r   c                      \ rS rSrSrSrSrg)r   i  zz
ABCAccent tokens "K" precede a note or chord;
they are a property of that note/chord.
These appear as ">" in the output.
rN   Nr  rN   rU   rV   r   r         
 IrU   r   c                      \ rS rSrSrSrSrg)r   i  z}
ABCStraccent tokens "k" precede a note or chord;
they are a property of that note/chord.
These appear as "^" in the output.
rN   Nr  rN   rU   rV   r   r     r  rU   r   c                      \ rS rSrSrSrSrg)r   i  zW
ABCTenuto tokens "M" precede a note or chord;
they are a property of that note/chord.
rN   Nr  rN   rU   rV   r   r     r  rU   r   c                      \ rS rSrSrSrSrg)r   i  z
Grace note start
rN   Nr  rN   rU   rV   r   r          IrU   r   c                      \ rS rSrSrSrSrg)r   i  z
Grace note end
rN   Nr  rN   rU   rV   r   r     r  rU   r   c                  >   ^  \ rS rSrSrSrSSU 4S jjjrS rSrU =r	$ )r   i  z(
Marks that rhythm is broken with '>>>'
)r   c                2   > [         TU ]  U5        SU l        g r   )r   rc   r   r   s     rV   rc   ABCBrokenRhythmMarker.__init__  s    	rU   c                B    U R                   R                  5       U l        g)z
Called before context adjustments: need to have access to data

>>> brokenRhythm = abcFormat.ABCBrokenRhythmMarker('>>>')
>>> brokenRhythm.preParse()
>>> brokenRhythm.data
'>>>'
N)r_   r   r   rg   s    rV   rq   ABCBrokenRhythmMarker.preParse  s     HHNN$	rU   rv   rx   )
rP   rQ   rR   rS   r{   r|   rc   rq   rT   r=  r>  s   @rV   r   r     s#     I 	% 	%rU   r   c                     ^  \ rS rSrSrSrS
SU 4S jjjr\SS j5       r S   SS jjr	 S     SS jjr
  S     SS jjrS	rU =r$ )r   i*  a  
A model of an ABCNote.

General usage requires multi-pass processing. After being tokenized,
each ABCNote needs a number of attributes updates. Attributes to
be updated after tokenizing, and based on the linear sequence of
tokens: `inBar`, `inBeam` (not used), `inGrace`,
`activeDefaultQuarterLength`, `brokenRhythmMarker`, and
`activeKeySignature`.

The `chordSymbols` list stores one or more chord symbols (ABC calls
these guitar chords) associated with this note. This attribute is
updated when parse() is called.
)carriedAccidentalchordSymbolsinBarinBeaminGraceactiveDefaultQuarterLengthbrokenRhythmMarkeractiveKeySignatureactiveTupletapplicableSpannerstiearticulationsaccidentalDisplayStatusisRest	pitchNamequarterLengthc                  > [         TU ]  U5        X l        / U l        S U l        S U l        S U l        S U l        S U l        S U l	        S U l
        / U l        S U l        / U l        S U l        SU l        S U l        SU l        g )NFr  )r   rc   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  )rb   r_   r  r   s      rV   rc   ABCNote.__init__?  s     '8 (* !%
!%"& 7;'8< :> 37 :< " )+ 37$ " $($'rU   c                    SU ;   aJ  [         R                  U 5      n[        [         R                  U 5      5      S   R	                  5       nXUS 4$ / U 4$ )a[  
Splits chord symbols from other string characteristics.
Returns a 2-tuple of a list of chord symbols, and clean remaining chars

Staticmethod:

>>> an = abcFormat.ABCNote()
>>> an._splitChordSymbols('"C"e2')
(['"C"'], 'e2')
>>> an._splitChordSymbols('b2')
([], 'b2')

>>> abcFormat.ABCNote._splitChordSymbols('"D7""D"d2')
(['"D7"', '"D"'], 'd2')
r  r  N)reChordSymbolfindalllistfinditerr   )rm   r  is      rV   _splitChordSymbolsABCNote._splitChordSymbolsp  sY    " &=(008L ]++F34R8<<>A++v:rU   c                   [         R                  SU/5        [        U5      S:  a  US   S;   a  USS nUR                  SS5      n [        R                  U5      S   nUS	:X  a  g
Ub  UnOU R                  n [        UU R                  [        U5      4   $ ! [         a    [        SU< 35      ef = f! [         a     Of = fUR                  5       (       a  SnOSnXQR                  S5      -  nXQR                  S5      -  nSn[        UR                  S5      5       H  nUS-  nM
     [        UR                  S5      5       H  nUS-  nM
     [        UR                  S5      5       H  nUS-  nM
     SnU R                  (       a  [        U R                  R                  S5      5       H  nUS-  nM
     [        U R                  R                  S5      5       H  nUS-  nM
     [        U R                  R                  S5      5       H  nUS-  nM
     U(       a  U(       a  [        S5      eU(       a  Sn	OUS:w  a  Sn	OUc  Sn	OUR                   n
U
 Vs/ s H  oR"                  R%                  5       PM     Os  snf nnU
 Vs/ s H  oR&                  R%                  5       PM     Os  snf nnUR%                  5       U;   a!  XR)                  UR%                  5       5         nSn	U(       a  UR+                  5        U U 3nOUR+                  5        U U 3nUU R                  [        U5      4nX4[        U'   X4$ )a  
Given a note or rest string without a chord symbol,
return a music21 pitch string or None (if a rest),
and the accidental display status. This value is paired
with an accidental display status. Pitch alterations, and
accidental display status, are adjusted if a key is
declared in the Note.

>>> an = abcFormat.ABCNote()
>>> an.getPitchName('e2')
('E5', None)
>>> an.getPitchName('C')
('C4', None)
>>> an.getPitchName('B,,')
('B2', None)
>>> an.getPitchName('C,')
('C3', None)
>>> an.getPitchName('c')
('C5', None)
>>> an.getPitchName("c'")
('C6', None)
>>> an.getPitchName("c''")
('C7', None)
>>> an.getPitchName("^g")
('G#5', True)
>>> an.getPitchName("_g''")
('G-7', True)
>>> an.getPitchName('=c')
('Cn5', True)

If pitch is a rest (z) then the Pitch name is None:

>>> an.getPitchName('z4')
(None, None)

Grace note:

>>> an.getPitchName('{c}')
('C5', None)


Given an active KeySignature object, the pitch name might
change:

>>> an.activeKeySignature = key.KeySignature(3)
>>> an.getPitchName('c')
('C#5', False)

Illegal pitch names raise an ABCHandlerException

>>> an.getPitchName('x')
Traceback (most recent call last):
music21.abcFormat.ABCHandlerException: cannot find any pitch information in: 'x'
zgetPitchName:rJ   r   uTNr   rw   z&cannot find any pitch information in: zNNrj  r   ,'_r   ^#r  r   z&Carried accidentals not rendered moot.TF)r#  r$  r   replacerePitchNamer  
IndexErrorr   r  rK   r  ry   KeyErrorislowercountrangealteredPitchesstepr   nameindexupper)rb   rm   forceKeySignaturer  r  octave	accStringdummycarriedAccStringr  r  palteredPitchStepsalteredPitchNamespStr	_cacheKeys                   rV   getPitchNameABCNote.getPitchName  sR   v 	& 9: v;?vayD0ABZFR(	[&&v.q1D 3;(!2!%!8!8	)6+/+A+A+./A+B+D E E  	[%(Nvj&YZZ	[  		 <<>>FF,,s##,,s## 	6<<,-EI .6<<,-EI .6<<,-EI . !! t55;;C@A C'  Bt55;;C@A C'  Bt55;;C@A C'  B 	%&NOO  '+#"_&*#'&*#
 0>>N9G HA H H9G HA H H zz|00()@)@)NO&+# jjl^$4#5fX>Djjl^I;vh7D """#
	 .2,Ky)..s*   B :B6 B36
CC#J#J2c                   Ub  UnOU R                   nUc  [        S5      e/ nU H1  nUR                  5       (       d  US:X  d  M   UR                  U5        M3     SR	                  U5      nUR                  5       nUS:X  a  UnGOWUS:X  a  US-  nGOJUS:X  a  US-  nGO=US:X  a  US-  nGO0UR                  S5      (       a!  U[        UR                  S5      S	   5      -  nOUR                  S5      (       a4  [        UR                  SS	S
9S   R                  5       5      nSn	X8-  U	-  nOUR                  S5      S:X  a  [        R                  SU/5        S	nOSU;   al  UR                  S5      u  p[        R                  (       a
  U
c   eUc   e[        U
R                  5       5      n[        UR                  5       5      n	X8-  U	-  nOU[        U5      -  nU R                  bb  U R                  u  pUS:X  a  SnO/US:X  a  SnO&US:X  a  SnOUS:X  a  SnOUS:X  a  SnOUS:X  a  SnOSnUS:X  a	  X~S   -  nU$ US:X  a  X~S	   -  nU$ )a  
Called with parse(), after context processing, to calculate duration

>>> an = abcFormat.ABCNote()
>>> an.activeDefaultQuarterLength = 0.5
>>> an.getQuarterLength('e2')
1.0
>>> an.getQuarterLength('G')
0.5
>>> an.getQuarterLength('=c/2')
0.25
>>> an.getQuarterLength('A3/2')
0.75
>>> an.getQuarterLength('A/')
0.25

>>> an.getQuarterLength('A//')
0.125
>>> an.getQuarterLength('A///')
0.0625

>>> an = abcFormat.ABCNote()
>>> an.activeDefaultQuarterLength = 0.5
>>> an.brokenRhythmMarker = ('>', 'left')
>>> an.getQuarterLength('A')
0.75
>>> an.brokenRhythmMarker = ('>', 'right')
>>> an.getQuarterLength('A')
0.25

>>> an.brokenRhythmMarker = ('<<', 'left')
>>> an.getQuarterLength('A')
0.125
>>> an.brokenRhythmMarker = ('<<', 'right')
>>> an.getQuarterLength('A')
0.875

>>> an.brokenRhythmMarker = ('<<<', 'left')
>>> an.getQuarterLength('A')
0.0625
>>> an.brokenRhythmMarker = ('<<<', 'right')
>>> an.getQuarterLength('A')
0.9375

>>> an.getQuarterLength('A', forceDefaultQuarterLength=1.0)
1.875
z@cannot calculate quarter length without a default quarter lengthr   rw   r4  z//r5  z///      ?rJ   )maxsplitr   r   r  >)      ?r4  <)r4  r  z>>)      ?r5  z<<)r5  r  z>>>)      ?r  z<<<)r  r  ri  leftright)r  r   isdigitr   r!  r   r   r   rl   endswithr  r#  r$  tTYPE_CHECKINGr  )rb   rm   forceDefaultQuarterLengthr  
numStrListr   numStrqlr   r   r   r   r   r[  modPairs                  rV   getQuarterLengthABCNote.getQuarterLength.  st   f %0)B&)-)H)H&%-#RT T !#
Ayy{{a3h!!!$  $
 R<+Bs]+c1Bt^+d2Bu_+e3Bs##+c&,,s2CA2F.GGB__S!!FLLqL1!4::<=AA+/!3B\\#!###%QSY$Z[B F]c*JD''''''DJJL!ADJJL!A+/!3B ,c&k9B"". $ 7 7F}$3$4&4&5(5(  F"aj  	 g%aj 	rU   c                J   U R                  U R                  5      u  U l        n U R                  UUS9u  pEXEsU l        U l        U R                  c  SU l	        OSU l	        U R                  UUS9U l        g ! [         a!    [
        R                  SU S3/5        SnSn Njf = f)N)r  z+Could not get pitch information from note: z, assuming Cr   FTr  )r  r_   r  r  r   r#  warnr  r  r  r  r  )rb   r  r  nonChordSymStrpnaccDisps         rV   rt   ABCNote.parse  s     -1,C,CDHH,M)>	++N>O , QKB 8:44>>!DKDK!22&? 3 A # 	L"0!1>@ ABG		s   A7 7(B"!B")r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  )rw   rw   )r  ry   )rm   ry   rz   ztuple[list[str], str]ra   )rm   ry   rz   ztuple[str | None, bool | None])rm   ry   r  float | Nonerz   r"  r  )r  r  r  zkey.KeySignature | Nonerz   r9  )rP   rQ   rR   rS   r{   r|   rc   r}   r  r  r  rt   rT   r=  r>  s   @rV   r   r   *  s    0I/( /(b  : a/a/ 
$	a/J BF@!$@4>@JO@H 1537A#-A 1A 
	A ArU   r   c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	r   i  zr
A representation of an ABC Chord, which contains within its delimiters individual notes.

A subclass of ABCNote.
c                2   > [         TU ]  U5        / U l        g ra   )r   rc   	subTokensr   s     rV   rc   ABCChord.__init__  s    )+rU   c                n   U R                  U R                  5      u  U l        n UR                  S5      nX4S-   S nUSU nU R                  USS9nUb  UnOU R                  n[        5       n	U	R                  U5        Sn
U	R                   Hu  n[        U[        5      (       d  M  UR                  U R                  US	9  UR                  (       a  MG  U
(       d  UR                   n
U R"                  R%                  U5        Mw     Xz-  U l        g! [         a    [        SU R                   S35      ef = f)
a  
Handles the following types of chords:

* Chord without length modifier: [ceg]

* Chords with outer length modifier: [ceg]2, [ceg]/2

* Chords with inner length modifier: [c2e2g2], [c2eg]

* Chords with inner and outer length modifier: [c2e2g2]/2, [c/2e/2g/2]2
]zBad chord indicator: z: no closing bracket found.rJ   Ng      ?r  r   )r  r  )r  r_   r  r  
ValueErrorr   r  r  r   tokenizetokens
isinstancer   rt   r  r  r  r  r   )rb   r  r  r  posouterLengthModifierStrtokenStrouter_lengthModifierr  ahinner_quarterLengthtokens               rV   rt   ABCChord.parse  sN    -1,C,CDHH,M)>	 &&s+C "0a!9!!C(  $445KOR  5  T (!2!%!8!8 \ 	HYYE %)).2.M.M&8  : <<
 +*/*=*='%%e,# , 2Gk  	%'z1LM 	s   D $D4)r  r  r  rv   rx   r  )	rP   rQ   rR   rS   r{   rc   rt   rT   r=  r>  s   @rV   r   r     s     , ,
GH GHrU   r   c                  j   \ rS rSrSr\R                  S4 SS jjr\    SS j5       r	\S S j5       r
\S!S j5       rS"S jrS#S	 jr\S$S
 j5       rS r\      S%S j5       rS&S jrS'S jrS&S jrS rS rS rS(S jrS rS rS)S jr\      S*S j5       rS+S jrS,S jrS-S jrS.S jrSr g)/r   i+  a  
An ABCHandler is able to divide elements of a character stream into objects and handle
store in a list, and passes global information to components

Optionally, specify the (major, minor, patch) version of ABC to process--
e.g., (1.2.0). If not set, default ABC 1.3 parsing is performed.

If lineBreaksDefinePhrases is True then new lines within music elements
define new phrases.  This is useful for parsing extra information from
the Essen Folksong repertory

* New in v6.3: lineBreaksDefinePhrases -- does not yet do anything
Fc                    Xl         0 U l        / U l        / U l        / U l        X l        SU l        SU l        SU l        [        U R                  5      U l
        SU l        g )Nr  r   rw   )
abcVersionabcDirectivesr  activeParensactiveSpannerslineBreaksDefinePhrasesr  	skipAheadrm   r   srcLencurrentCollectStr)rb   r  r  s      rV   rc   ABCHandler.__init__9  s[     ,6-/&(')57-D$t{{+!#rU   c                    [        U 5      S-
  nX:  a  [        SU SU 35      eSnUS:  a  XS-
     nX   nSnU[        U 5      S-
  :  a  XS-      nSnU[        U 5      S-
  :  a  XS-      nX4XV4$ )a  
Find the local context of a string or iterable of objects
beginning at a particular index.

Returns a tuple of charPrev, charThis, charNext, charNextNext.

Staticmethod

>>> ah = abcFormat.ABCHandler()
>>> ah._getLinearContext('12345', 0)
(None, '1', '2', '3')
>>> ah._getLinearContext('12345', 1)
('1', '2', '3', '4')
>>> abcFormat.ABCHandler._getLinearContext('12345', 3)
('3', '4', '5', None)
>>> abcFormat.ABCHandler._getLinearContext('12345', 4)
('4', '5', None, None)

>>> abcFormat.ABCHandler._getLinearContext([32, None, 8, 11, 53], 4)
(11, 53, None, None)
>>> ah._getLinearContext([32, None, 8, 11, 53], 2)
(None, 8, 11, 53)
>>> ah._getLinearContext([32, None, 8, 11, 53], 0)
(None, 32, None, 8)
rJ   zbad index value z	, max is Nr   r   )r   r   )sourcer  	lastIndexcPrevr   cNext	cNextNexts          rV   _getLinearContextABCHandler._getLinearContextI  s    : K!O	=%(89YK&PQQ q5q5ME Is6{Qq5ME 	s6{Q1uI))rU   c                r    [        U 5      S-
  n[        US-   US-   5       H  nX   S:X  d  M  Us  $    US-   $ )an  
Return index of next line break after character i.

Staticmethod

>>> ah = abcFormat.ABCHandler()
>>> inputString = 'de  we\n wer bfg\n'
>>> ah._getNextLineBreak(inputString, 0)
6
>>> inputString[0:6]
'de  we'

from last line break

>>> abcFormat.ABCHandler._getNextLineBreak(inputString, 6)
15
>>> inputString[ah._getNextLineBreak(inputString, 0):]
'\n wer bfg\n'
rJ   
)r   r  )rm   r  r#  js       rV   _getNextLineBreakABCHandler._getNextLineBreak~  sE    * K!O	q1ui!m,AyD  - 1}rU   c                   / nU S:X  a6  UR                  [        S5      5        UR                  [        S5      5        U$ U S:X  a6  UR                  [        S5      5        UR                  [        S5      5        U$ U S:X  a6  UR                  [        S5      5        UR                  [        S5      5        U$ U S	:X  a6  UR                  [        S5      5        UR                  [        S5      5        U$ U S
:X  a6  UR                  [        S5      5        UR                  [        S5      5        U$ UR                  [        U 5      5        U$ )a  
Some single barline tokens are better replaced
with two tokens. This method, given a token,
returns a list of tokens. If there is no change
necessary, the provided token will be returned within
the list.

A staticmethod.  Call on the class itself.

>>> abcFormat.ABCHandler.barlineTokenFilter('::')
[<music21.abcFormat.ABCBar ':|'>, <music21.abcFormat.ABCBar '|:'>]

>>> abcFormat.ABCHandler.barlineTokenFilter('|2')
[<music21.abcFormat.ABCBar '|'>, <music21.abcFormat.ABCBar '[2'>]

>>> abcFormat.ABCHandler.barlineTokenFilter(':|1')
[<music21.abcFormat.ABCBar ':|'>, <music21.abcFormat.ABCBar '[1'>]

If nothing matches, the original token is returned as an ABCBar object:

>>> abcFormat.ABCHandler.barlineTokenFilter('hi')
[<music21.abcFormat.ABCBar 'hi'>]
rE   rC   rD   rA   rF   r=   rB   r?   r9   r:   )r   r   )r  	barTokenss     rV   barlineTokenFilterABCHandler.barlineTokenFilter  s*   2 #%	D=VD\*VD\*& % d]VC[)VD\*  d]VC[)VD\*  e^VD\*VD\*  e^VD\*VD\*  VE]+rU   c                h    SnU R                   U:  a  gSU R                  ;   a  U R                  S   $ g)z
Determine how accidentals should 'carry through the measure.'

>>> ah = abcFormat.ABCHandler(abcVersion=(1, 3, 0))
>>> ah._accidentalPropagation()
'not'
>>> ah = abcFormat.ABCHandler(abcVersion=(2, 0, 0))
>>> ah._accidentalPropagation()
'pitch'
)r   r   r   notzpropagate-accidentalspitch)r  r  )rb   
minVersions     rV   _accidentalPropagation!ABCHandler._accidentalPropagation  s;     
??Z'"d&8&88%%&=>>rU   c                j    [         R                  U5      nU(       a  U R                  U5      U l        gg)a  
Search a line of text for a comment abc version number

>>> ah = abcFormat.ABCHandler()
>>> ah.abcVersion
(1, 3, 0)

>>> ah.parseHeaderForVersionInformation('%abc-2.3.2')
>>> ah.abcVersion
(2, 3, 2)

Changed in v9: abcVersion defaults to (1, 3, 0) as documented.
N)reAbcVersionsearchreturnAbcVersionFromMatchr  )rb   inputSearchverMatss      rV    parseHeaderForVersionInformation+ABCHandler.parseHeaderForVersionInformation  s.     %%k2"<<WEDO rU   c                    [        U R                  S5      5      n[        U R                  S5      5      nU R                  S5      (       a  [        U R                  S5      5      nOSnXU4$ )aB  
Given a match from a regular expression return the parsed ABC version

>>> import re
>>> match = re.match(r'(\d+).(\d+).(\d+)', '2.3.4')
>>> ah = abcFormat.ABCHandler()
>>> ah.returnAbcVersionFromMatch(match)
(2, 3, 4)

>>> match = re.match(r'(\d+).(\d+).?(\d?)', '1.7')
>>> ah.returnAbcVersionFromMatch(match)
(1, 7, 0)
rJ   r   rJ  r   )r   group)r=  abcMajorabcMinorabcPatchs       rV   r;  $ABCHandler.returnAbcVersionFromMatch  s\     w}}Q'(w}}Q'(==7==+,HHH--rU   c                z   U R                  U R                  U R                  5      U R                  S-   -
  U l        U R                  U R                  U R                  U R                  -   S-    n[        R                  U5      nU(       a1  UR                  S5      nUR                  S5      nX@R                  U'   gg)a  
Processes the comment at self.pos in self.strSrc, setting self.skipAhead
and self.abcDirectives for the directiveKey.

>>> from textwrap import dedent
>>> ah = abcFormat.ABCHandler()
>>> data = dedent("""
...    Hello % this is a comment
...    Bye
...    """)
>>> ah.strSrc = data
>>> ah.pos = 6
>>> ah.processComment()
>>> ah.skipAhead
19
>>> len(' this is a comment\n')
19

Directives get stored in the handler:

>>> data = '%%abc-hello world'
>>> ah = abcFormat.ABCHandler()
>>> ah.strSrc = data
>>> ah.pos = 0
>>> ah.processComment()
>>> ah.abcDirectives
{'abc-hello': 'world'}
>>> ah.abcDirectives['abc-hello']
'world'

* Changed in v9: version is not parsed by this method.
rJ   r   N)r,  rm   r  r  reDirectiver   rA  r  )rb   commentLinedirectiveMatchesdirectiveKeydirectiveValues        rV   processCommentABCHandler.processComment	  s    F //KK
XX\ kk$((488dnn+Dq+HI&,,[9+11!4L-33A6N/=|, rU   c                    US:w  a  gUc  gUS:X  a  gU S:X  a  gU R                  5       (       a  U R                  5       (       a  gg)a  
Returns True if this context describes the start of a metadata section, like

A:something

Metadata: capital letter, with next char as ':' and some following character

>>> ah = abcFormat.ABCHandler
>>> ah.startsMetadata('A', ':', 's')
True

lowercase w: is a special case for lyric defs

>>> ah.startsMetadata('w', ':', 's')
True

Following char must be ":"

>>> ah.startsMetadata('A', ' ', 's')
False

Pipe after colon indicates not metadata (bar info).
For example need to not misinterpret repeat bars as metadata
e.g. `dAG FED:|2 dAG FGA|`

this is incorrect, but we can avoid it by
looking for a leading pipe and returning False

>>> ah.startsMetadata('A', ':', '|')
False

>>> ah.startsMetadata('A', ':', None)
False
rH   FrF   wT)isalphaisupper)r   r%  r&  s      rV   startsMetadataABCHandler.startsMetadata7  sH    L C<##XYY[[QYY[[rU   c                   [        U5      U l        Xl        SU l        SU l        SU l        SnSnSn0 nSnSnU R                  U R                  S-
  :  Ga  U =R                  S-  sl        U =R                  U R
                  -  sl        SU l        U R                  U R                  S-
  :  a  gU R                  U R                  U R                  5      nUu  ppU
S:X  a  U R                  5         M  U R                  XU5      (       a  U R                  U R                  U R                  5      nXR                  S-   -
  U l        U R                  U R                  U R                  5       U l        U R                  R                  [        U R                  5      5        GMj  U
R                  5       (       GdG  U
R                  5       (       Gd1  U
S;  Ga*  S	n[!        [        ["        5      5       H  n["        U   S   n[        U5      S
:X  a"  Ub  Ub  X-   U-   U:X  a  SU l        Sn  OSM<  M>  M@  Ub$  [        U5      S:X  a  X-   U:X  a  SU l        Sn  O(Mg  [        U5      S:X  d  Mx  U
U:X  d  M  SU l        Sn  O   USL a~  0 nSnU R                  U R
                  -   S-   nU R                  U R                  U U l        U R%                  U R                  5       H  nU R                  R                  U5        M      GM  U
S:X  Gar  UGbn  UR'                  5       (       GaX  SU l        U R                  U R
                  -   S-   nU R                  U R                  U5      u  nnnnUS:X  a  US-  nU =R
                  S-  sl        Ub/  UR'                  5       (       a  US-  nU =R
                  S-  sl        U R                  U R                  U5      u  nnnnUS:X  aL  US-  nU =R
                  S-  sl        Ub/  UR'                  5       (       a  US-  nU =R
                  S-  sl        U R                  U R                  U U l        U R                  R                  [)        U R                  5      5        GM@  U
S;   a  U R                  S-   nXR                  S-
  :  a?  U R                  U   S;   a,  US-  nXR                  S-
  :  a  U R                  U   S;   a  M,  U R                  U R                  U U l        U R                  R                  [+        U R                  5      5        XR                  S-   -
  U l        GM  U
S:X  Ga  [,        [.        [0        [.        S.nU R                  S-   nXR                  S-   :  a  XR                  :  a  U R                  U   S:X  a  U R                  U R                  US-    U;   aV  UU R                  U R                  US-       nU" U
5      nU R                  R                  U5        XR                  -
  U l        O<XR                  -
  U l        O(US-  nXR                  S-   :  a  XR                  :  a  M  GM!  U
S:X  a?  Ub<  UR'                  5       (       d'  U R                  R                  [3        U
5      5        GMf  U
S:X  a'  U R                  R                  [/        U
5      5        GM  U
S:X  a'  U R                  R                  [5        U
5      5        GM  U
S:X  a  U R                  S-   nXR                  S-
  :  a?  U R                  U   S:w  a,  US-  nXR                  S-
  :  a  U R                  U   S:w  a  M,  US-  nX@R                  U R                  U -  nXR                  S-   -
  U l        GM_  U
S:X  Ga  U R                  S-   nXR                  S-
  :  a?  U R                  U   S:w  a,  US-  nXR                  S-
  :  a  U R                  U   S:w  a  M,  US-  nXR                  :  a  U R                  U   R'                  5       (       d  U R                  U   S;   aM  US-  nXR                  :  a9  U R                  U   R'                  5       (       a  M8  U R                  U   S;   a  MM  US:w  a#  X@R                  U R                  U -   U l        SnOU R                  U R                  U U l        U R                  R                  [7        U R                  5      5        XR                  S-   -
  U l        GM  U
S:X  a'  U R                  R                  [9        U
5      5        G	M  U
S:X  a'  U R                  R                  [;        U
5      5        G	MD  U
S:X  a'  U R                  R                  [=        U
5      5        G	Mq  U
S:X  a'  U R                  R                  [?        U
5      5        G	M  U
S:X  a'  U R                  R                  [A        U
5      5        G	M  U
S:X  a'  U R                  R                  [C        U
5      5        G	M  U
S :X  a'  U R                  R                  [E        U
5      5        G
M%  U
S!:X  a'  U R                  R                  [G        U
5      5        G
MR  U
RI                  5       (       d  U
S";   Ga  U
RI                  5       =(       a    X;  nU(       a  U
nX;   a  U
nU R                  S-   nXR                  S-
  ::  a  U(       d>  U R                  U   U;   a+  US-  nU R                  U   U;   a  X`R                  U   -  nMW  U(       dM  U R                  U   RI                  5       (       a+  U R                  U   S#;  a  SnU R                  U   nUS-  nM  U R                  U   R'                  5       (       d  U R                  U   S$;   a,  U R                  U   S%;   a  XpR                  U   -  nUS-  nGM   US:w  a#  X@R                  U R                  U -   U l        SnOU R                  U R                  U U l        U R                  S&;   a  GOU R                  RK                  S5      (       a5  U R                  S   S';   d   U R                  RM                  S(5      (       a  GOU R                  RK                  S)5      (       d@  U R                  RK                  S*5      (       d   U R                  RK                  S+5      (       a  GO&[        U R                  5      S:  aC  U R                  RK                  S,5      (       a#  U R                  S   R'                  5       (       a  OU(       a  US   RO                  5       nSnU RQ                  5       nU(       a  US-:X  a  XeU'   O
US.:X  a  XeU'   SnO!US.:X  a  UU;   a  UU   nOUS-:X  a	  Xu;   a  XW   n[S        U R                  US/9nU R                  R                  U5        O.U R                  R                  [S        U R                  5      5        XR                  S-   -
  U l        GM   U R                  U R                  S-
  :  a  GM  gg)0a  
Walk the abc string, creating ABC objects along the way.

This may be called separately from process(), in the case
that pre-/post-parse processing is not needed.

>>> abch = abcFormat.ABCHandler()
>>> abch.tokens
[]
>>> abch.tokenize('X: 1')
>>> abch.tokens
[<music21.abcFormat.ABCMetadata 'X: 1'>]

>>> abch = abcFormat.ABCHandler()
>>> abch.tokenize('(6f')
>>> abch.tokens
[<music21.abcFormat.ABCTuplet '(6'>, <music21.abcFormat.ABCNote 'f'>]

>>> abch = abcFormat.ABCHandler()
>>> abch.tokenize('(6:4f')
>>> abch.tokens
[<music21.abcFormat.ABCTuplet '(6:4'>, <music21.abcFormat.ABCNote 'f'>]

>>> abch = abcFormat.ABCHandler()
>>> abch.tokenize('(6:4:2f')
>>> abch.tokens
[<music21.abcFormat.ABCTuplet '(6:4:2'>, <music21.abcFormat.ABCNote 'f'>]

>>> abch = abcFormat.ABCHandler()
>>> abch.tokenize('(6::2f')
>>> abch.tokens
[<music21.abcFormat.ABCTuplet '(6::2'>, <music21.abcFormat.ABCNote 'f'>]
r  rw   r   z.~^=_HLMOPSTuvz^=_rJ   rk   )~(FrJ  Nr   TrV  rH   z<>!)z!crescendo(!z!crescendo)!z!diminuendo(!z!diminuendo)!   )r   r  [r	  r   .u{}vr   kr   z~^=_z
~wuvhHLTSNz,/,'z,')'rO  r\  r_  v.hHvkukUrU  r[  r  r   ra  Ssr  r   uizu.r   HyHxrr   r   r   Nor   Plr   Ryr   r  xZ)r\  r_  r`  r   r   r[  rr  r   rO  rb  rs  ra  rs  rc  rt  r  r  r4  )r  )*r   r  rm   r  r  r  r'  rL  rR  r,  r   r  r   r
   isspaceisalnumr  ABC_BARSr0  r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rP  r   r  r  r6  r   )rb   rm   accidentalsAndDecorationsaccidentalsactiveChordSymbolaccidentalized
accidentalabcPitchqunused_cPrevr   r%  r&  r+  	matchBarsbarIndexbarTokenArchetypetokenSubunused1possibleColonqCharunused2rCharexclaimDictexclaimClassexclaimObjectfoundPitchAlpha
pitchClassr  propagationabcNotes                                  rV   r  ABCHandler.tokenizej  sB   D &k!#$4!)+
hhq(HHMHHH&HDNxx$++/)&&t{{DHH=A01-LU Cx##%""1Y77**4;;A!"hhl!3)-TXXa)@)F)F)H&"";t/E/E#FG 99;;qyy{{q
7J!	 %c(m 4H )1(:1(=%,-2!-$-$9$%I	$9=N$N-.DN(,I! %O %: . *4E0F!0K9(99-.DN(,I! : ./14 11-.DN(,I!) !5* $%'N!#J4>>1A5A-1[[!-DD*$($;$;D<R<R$S**84 %T  CxE-%--//!"HHt~~-19=9O9OPTP[P[]^9_6w C'FANNa'N(U]]__Q!+=A=S=STXT_T_ab=c:G]E7$+Q!+ ,FA NNa/N)-TXXa)@&""9T-C-C#DE DyHHqL++/)dkk!n.DFA ++/)dkk!n.D)-TXXa)@& ""#89O9O#PQ!"hhl!3 Cx/</;0;0<!
 HHqL((R-'AO{{1~,;;txxA6+E+6t{{488APQE7R+SL,8OM KK..}=-.\DN! ./\DN!FA ((R-'AO  CxE-emmoo""<?3 Cx""<?3 Cx""6!9- CxHHqL++/)dkk!n.CFA ++/)dkk!n.CQ![[!%<<!!"hhl!3 CxHHqL ++/)dkk!n.CFA ++/)dkk!n.C Q ++o4;;q>+A+A+C+Ct{{ST~Y\G\FA ++o4;;q>+A+A+C+Ct{{ST~Y\G\ %*->TXXVWAX-XD*(*%-1[[!-DD* ""8D,B,B#CD!"hhl!3 Cx"";q>2Cx""8A;/Cx""=#34Cx""<?3Cx"":a=1Cx""9Q<0Cx""<?3Cx""9Q<0 yy{{a6k. #$))+"T!2T" H#!"JHHqL;;?* +t{{1~AZ/ZQ;;q>[8&++a.8J -$++a.2H2H2J2J"kk!nL@*.#';;q>Q  Q//11T[[^v5M;;q>T1$A6HQ $*->TXXVWAX-XD*(*%-1[[!-DD* )) .8 8  ,,77<<11"5 :T T"44==dCC,,77<<//::3??//::3??$001A500;;C@@003;;==&.qk&7&7&9J(*%"&"="="?K!&(27A84(G39C:6%'
&'1jN6R0>z0J-(H49S0>0H-%d&<&<PabGKK&&w/KK&&wt/E/E'FG!"hhl!3 e
 hhq((rU   c           
        SSK Jn  U R                   H  nUR                  5         M     SnSnSnSnSnSnSn	Sn
SnSnSnSnSn[	        [        U R                  5      5       GH[  nU R                  U R                  U5      nUu  nnnn[        U[        5      (       a  UR                  5       (       a  UR                  5       nUR                  5       (       d  UR                  5       (       a  Uc  UR                  5       nOQUR                  5       (       a<  UR                  5       u  nnUR                  " U5      nUS;  a  UR!                  U5      nUR#                  5       (       a  / U l        / U l        GM  [        U[(        5      (       ax  [        U[*        5      (       a<  [        U[*        5      (       a'  UR,                  S4Ul        UR,                  S4Ul        O'[0        R3                  SSUR4                   S	3-   /5        [        U[6        5      (       a>  UR9                  U5        UR;                  5         UnU R$                  R=                  S
5        [        U[>        5      (       au  URA                  5         [B        RD                  (       a  URF                  c   eU R&                  R=                  URF                  5        U R$                  R=                  S5        O`[        U[H        5      (       aK  U R$                  (       a:  U R$                  RK                  5       nUS;   a  U R&                  RK                  5         [        U[L        5      (       a/  U(       a  URN                  S:X  a  SUl'        OU(       a  SUl'        Un[        U[P        5      (       a  Un[        U[R        5      (       a  Un	[        U[T        5      (       a  Un
[        U[V        5      (       a  Un[        U[X        5      (       a  Un[        U[Z        5      (       a  Un[        U[\        5      (       at  UR_                  5         [B        RD                  (       a  UR`                  c   eU R&                  R=                  UR`                  5        U R$                  R=                  S5        [        U[b        5      (       at  URe                  5         [B        RD                  (       a  URf                  c   eU R&                  R=                  URf                  5        U R$                  R=                  S5        [        U[h        5      (       a  Un[        U[j        5      (       a  Sn[        U[*        [l        45      (       d  GM  Uc  [o        SSU SU SU 3-   5      eX2l8        XBl9        U R&                  SS Ul:        Ub	  SUl'        SnUb  URv                  R=                  S5        SnU	b  URv                  R=                  S5        Sn	U
b  URv                  R=                  S5        Sn
Ub  URv                  R=                  S5        SnUb  URv                  R=                  S5        SnUb  URv                  R=                  S5        SnUb  SUl<        Uc  O9URz                  S:X  a  SnO&U=Rz                  S-  sl=        UR|                  Ul?        UnGM^     U R                   H  nUR                  5         M     g)zh
Process all token objects. First, calls preParse(), then
does context assignments, then calls parse().
r   r/   Nr   r  r  zbroken rhythm marker rV  z,) not positioned between two notes or chordsrx  r  )r  r  r  stopcontinuerZ  r  r  z<no active default note length provided for note processing. ztPrev: z	, token: z	, tNext: staccatoupbowdownbowaccentstrongaccenttenutoTrJ   )Ar   r0   r  rq   r  r   r'  r  r
   r   r   r   r6  r   r  r  r  r   r  r  r   r   r   r  r#  r$  r_   r   ru  ry  r   r   r  r  r  r  r   popr   r  r   r   r   r   r   r   r   r  r  r   r  r  r   r   r   r   r  r  r  r  r  rb  re  r  rt   )rb   r0   r  lastDefaultQLlastKeySignaturelastTimeSignatureObjlastTupletTokenlastTieTokenlastStaccTokenlastUpTokenlastDownTokenlastAccTokenlastStrAccTokenlastTenutoTokenlastGraceTokenlastNoteTokenr  r~  tPrevtNextunused_tNextNext
sharpCountr  r  s                           rV   tokenProcessABCHandler.tokenProcess	  s    	 
 [[ENN ! #*.$(s4;;'(A&&t{{A6A451E5%!1 %--==??+0+G+G+I(,,..5==??}G\$)$A$A$CM[[]]','F'F'H$J'*'7'7
'C$:-+;+A+A$+G(**,, )+D%*,D'%!677ug..&ug6605

F/CE,05

G/DE, ++0uyyk)UVW XY
 %++!!"67 %%'"'!!((2 %.. ?? ==444##**5==9!!((0E<00$$))--/A??++//1%(( ]%6%6&%@(2M%"(/M%$%--!&%**#%,, %%++$%.."'%++"'%//!?? >>555##**5>>:!!((5%--?? <<333##**5<<8!!((6%//!&%..!% %'8!455 (-V#E7)E7)E7KL  4A0+;(+/+>+>q+A(  + &EI#'L!-''..z:%)N*''..w7"&K ,''..y9$(M+''..x8#'L".''..~>&*O".''..x8&*O!-$(EM"*$..!3&*O#--2-)8)B)BE& %m )r [[EKKM !rU   c                |    U R                  US S 5        / U l        U R                  U5        U R                  5         g )Nd   )r>  r  r  r  )rb   rm   s     rV   processABCHandler.process
  s5    --fTcl;frU   c                ,    [        U R                  5      $ ra   )r   r  rg   s    rV   __len__ABCHandler.__len__
  s    4;;rU   c                b    U R                  5       nU R                  UR                  -   Ul        U$ )a  
Return a new handler adding the tokens in both

Contrived example appending two separate keys.

Used in polyphonic metadata merge


>>> abcStr = 'M:6/8\nL:1/8\nK:G\n'
>>> ah1 = abcFormat.ABCHandler()
>>> junk = ah1.process(abcStr)
>>> len(ah1)
3

>>> abcStr = 'M:3/4\nL:1/4\nK:D\n'
>>> ah2 = abcFormat.ABCHandler()
>>> junk = ah2.process(abcStr)
>>> len(ah2)
3

>>> ah3 = ah1 + ah2
>>> len(ah3)
6
>>> ah3.tokens[0] == ah1.tokens[0]
True
>>> ah3.tokens[3] == ah2.tokens[0]
True

)r   r  )rb   otherr  s      rV   __add__ABCHandler.__add__
  s)    < ^^KK%,,.		rU   c                   U R                   (       d  [        S5      eSn[        [        U R                   5      5       HM  nU R                   U   n[	        U[
        5      (       d  M)  UR                  5       (       d  M@  US-  nUS:  d  MM    g   g)a^  
Return True if this token structure defines more than 1 reference number,
usually implying multiple pieces encoded in one file.


>>> abcStr = 'X:5\nM:6/8\nL:1/8\nK:G\nB3 A3 | G6 | B3 A3 | G6 ||'
>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStr)
>>> ah.definesReferenceNumbers()  # only one returns False
False


>>> abcStr = 'X:5\nM:6/8\nL:1/8\nK:G\nB3 A3 | G6 | B3 A3 | G6 ||\n'
>>> abcStr += 'X:6\nM:6/8\nL:1/8\nK:G\nB3 A3 | G6 | B3 A3 | G6 ||'
>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStr)

There are two tokens, so this returns True

>>> ah.definesReferenceNumbers()
True
(must process tokens before calling splitr   rJ   TF)r  r   r  r   r  r
   r   rb   r  r  r  s       rV   definesReferenceNumbers"ABCHandler.definesReferenceNumbers
  su    . {{%&PQQs4;;'(AKKNE%--**,,QJEqy# ) rU   c                B   U R                   (       d  [        S5      e0 n/ n/ nSn[        U R                   5       H  u  pV[        U[        5      (       aL  UR                  5       (       a7  Ub  X4l         / n[        U R                  S9n[        UR                  5      nXAU'   Uc  UR                  U5        M|  UR                  U5        M     Ub  X4l         U(       d  [        U R                  S9US'   UR                  5        H  nUSS UR                   -   Ul         M     U$ )a  
Split tokens by reference numbers.

Returns a dictionary of ABCHandler instances, where the reference number
is used to access the music. If no reference numbers are defined,
the tune is available under the dictionary entry None.

>>> abcStr = 'X:5\nM:6/8\nL:1/8\nK:G\nB3 A3 | G6 | B3 A3 | G6 ||'
>>> abcStr += 'X:6\nM:6/8\nL:1/8\nK:G\nB3 A3 | G6 | B3 A3 | G6 ||'
>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStr)
>>> len(ah)
28
>>> ahDict = ah.splitByReferenceNumber()
>>> 5 in ahDict
True
>>> 6 in ahDict
True
>>> 7 in ahDict
False

Each entry is its own ABCHandler object.

>>> ahDict[5]
<music21.abcFormat.ABCHandler object at 0x10b0cf5f8>
>>> len(ahDict[5].tokens)
14

Header information (except for comments) should be appended to all pieces.

>>> from textwrap import dedent
>>> abcEarly = dedent("""X:4
...    M:6/8
...    L:1/8
...    K:F
...    I:abc-version 1.6
...    B=3 B3 | G6 | B3 A3 | G6 ||
...    """)
>>> abcStrWHeader = '%abc-2.1\nO: Irish\n' + abcEarly + abcStr

>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStrWHeader)
>>> len(ah)
44
>>> ahDict = ah.splitByReferenceNumber()

Did we get the origin header in each score?

>>> ahDict[5].tokens[0]
<music21.abcFormat.ABCMetadata 'O: Irish'>
>>> ahDict[6].tokens[0]
<music21.abcFormat.ABCMetadata 'O: Irish'>

Before parsing all the tokens should have the 2.1 version:

>>> ahDict[4].abcVersion
(2, 1, 0)
>>> ahDict[5].abcVersion
(2, 1, 0)

After parsing, the abcVersion should be set for score 4 and
revert for score 5.

>>> for f in ahDict:
...    _ = abcFormat.translate.abcToStreamScore(ahDict[f])
>>> ahDict[4].abcVersion
(1, 6, 0)
>>> ahDict[5].abcVersion
(2, 1, 0)
r  Nr  )r  r   	enumerater  r
   r   r   r  r   r   r   values)	rb   ahDictprependToAllListactiveTokenscurrentABCHandlerr  r  referenceNumberthisABCHandlers	            rV   splitByReferenceNumber!ABCHandler.splitByReferenceNumber
  s	   P {{%&PQQ-/  !$++.HA%--%2I2I2K2K$0/;,#%L$.$//$J!"%ejj/*;' ( ''.##E* / ('3$%AF4L$mmoN$4Q$7.:O:O$ON! . rU   c                    U R                   (       d  [        S5      eU R                    H=  n[        U[        5      (       d  M  UR	                  5       (       d  M1  UR
                  s  $    g)z
If tokens are processed, get the first
reference number defined.


>>> abcStr = 'X:5\nM:6/8\nL:1/8\nK:G\nB3 A3 | G6 | B3 A3 | G6 ||'
>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStr)
>>> ah.getReferenceNumber()
'5'
r  N)r  r   r  r
   r   r   rb   r  s     rV   getReferenceNumberABCHandler.getReferenceNumberj  sP     {{%&PQQ[[E%--**,, ::% ! rU   c                   U R                   (       d  [        S5      eSn[        [        U R                   5      5       HM  nU R                   U   n[	        U[
        5      (       d  M)  UR                  5       (       d  M@  US-  nUS:  d  MM    g   g)aU  
Returns True if this token structure defines Measures in a normal Measure form.
Otherwise False

>>> abcStr = ('M:6/8\nL:1/8\nK:G\nV:1 name="Whistle" ' +
...     'snm="wh"\nB3 A3 | G6 | B3 A3 | G6 ||\nV:2 name="violin" ' +
...     'snm="v"\nBdB AcA | GAG D3 | BdB AcA | GAG D6 ||\nV:3 name="Bass" ' +
...     'snm="b" clef=bass\nD3 D3 | D6 | D3 D3 | D6 ||')
>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStr)
>>> ah.definesMeasures()
True

>>> abcStr = 'M:6/8\nL:1/8\nK:G\nB3 A3 G6 B3 A3 G6'
>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStr)
>>> ah.definesMeasures()
False
r  r   rJ   r   TF)r  r   r  r   r  r   rT  r  s       rV   definesMeasuresABCHandler.definesMeasures~  su    ( {{%&PQQs4;;'(AKKNE%(( ??$$QJEz# ) rU   c                t   U R                   (       d  [        S5      eSn/ n[        [        U R                   5      5       H  nU R                   U   n[	        U[
        5      (       d  M)  UR                  5       (       d  M@  UR                  (       d  MS  UR                  S   R                  5       (       d  Mw  UR                  U5        US-  nM     / nUS::  a4  U R                  5       nU R                   Ul         UR                  U5        U$ / nUR                  SUS   /5        US   n[        S[        U5      5       H  nX(   n	UR                  X9/5        U	nM     UR                  U[        U 5      /5        U H9  u  pU R                  5       nU R                   X Ul         UR                  U5        M;     U$ )a  
Given a processed token list, look for voices. If voices exist,
split into parts: common metadata, then next voice, next voice, etc.

Each part is returned as a ABCHandler instance.

>>> abcStr = ('M:6/8\nL:1/8\nK:G\nV:1 name="Whistle" ' +
...     'snm="wh"\nB3 A3 | G6 | B3 A3 | G6 ||\nV:2 name="violin" ' +
...     'snm="v"\nBdB AcA | GAG D3 | BdB AcA | GAG D6 ||\nV:3 name="Bass" ' +
...     'snm="b" clef=bass\nD3 D3 | D6 | D3 D3 | D6 ||')
>>> ah = abcFormat.ABCHandler()
>>> ah.process(abcStr)
>>> tokenColls = ah.splitByVoice()
>>> tokenColls[0]
<music21.abcFormat.ABCHandler object at 0x...>

Common headers are first

>>> [token.src for token in tokenColls[0].tokens]
['M:6/8', 'L:1/8', 'K:G']

Then each voice

>>> [token.src for token in tokenColls[1].tokens]
['V:1 name="Whistle" snm="wh"',
 'B3', 'A3', '|', 'G6', '|', 'B3', 'A3', '|', 'G6', '||']
>>> [token.src for token in tokenColls[2].tokens]
['V:2 name="violin" snm="v"',
 'B', 'd', 'B', 'A', 'c', 'A', '|',
 'G', 'A', 'G', 'D3', '|',
 'B', 'd', 'B', 'A', 'c', 'A', '|',
 'G', 'A', 'G', 'D6', '||']
>>> [token.src for token in tokenColls[3].tokens]
['V:3 name="Bass" snm="b" clef=bass',
 'D3', 'D3', '|', 'D6', '|',
 'D3', 'D3', '|', 'D6', '||']

Then later the metadata can be merged at the start of each voice:

>>> mergedTokens = tokenColls[0] + tokenColls[1]
>>> mergedTokens
<music21.abcFormat.ABCHandler object at 0x...>
>>> [token.src for token in mergedTokens.tokens]
['M:6/8', 'L:1/8', 'K:G', 'V:1 name="Whistle" snm="wh"',
 'B3', 'A3', '|', 'G6', '|',
 'B3', 'A3', '|', 'G6', '||']
r  r   rJ   )r  r   r  r   r  r
   r   r   r  r   r   )rb   
voiceCountr  r  r  abcHandlersr  pairsrs  r+  rr  s              rV   splitByVoiceABCHandler.splitByVoice  sx   h {{%&PQQ
s4;;'(AKKNE%--==?? zzzejjm&;&;&=&=

1"a
 )  ?!BBIr"&  ELL!SV%AA1c#h'FaV$ (
 LL!SY(^^% KK,	""2& 
 rU   c                    / nUR                  SU S   /5        U S   n[        S[        U 5      5       H'  nX   nXSS-   :X  a  UnM  UR                  X5/5        UnM)     X1:w  a  UR                  X1/5        U$ )a&  
Staticmethod

Given a list of indices of a list marking the position of
each barline or implied barline, and the last valid index,
return a list of two-element lists, each indicating
the start and positions of a measure.

Here's an easy case that makes this method look worthless:

>>> AH = abcFormat.ABCHandler
>>> AH._buildMeasureBoundaryIndices([8, 12, 16], 20)
[[0, 8], [8, 12], [12, 16], [16, 20]]

But in this case, we need to see that 12 and 13 don't represent different measures but
probably represent an end and new barline (repeat bar), etc.

>>> AH._buildMeasureBoundaryIndices([8, 12, 13, 16], 20)
[[0, 8], [8, 12], [13, 16], [16, 20]]

Here 115 is both the last barline and the last index, so there is no [115, 115] entry.

>>> bi = [9, 10, 16, 23, 29, 36, 42, 49, 56, 61, 62, 64, 70, 77, 84, 90, 96, 103, 110, 115]
>>> AH._buildMeasureBoundaryIndices(bi, 115)
[[0, 9], [10, 16], [16, 23], [23, 29], [29, 36], [36, 42], [42, 49], [49, 56], [56, 61],
 [62, 64], [64, 70], [70, 77], [77, 84], [84, 90], [90, 96],
 [96, 103], [103, 110], [110, 115]]

r   rJ   )r   r  r   )positionListlastValidIndexr  r  rs  r+  s         rV   _buildMeasureBoundaryIndices'ABCHandler._buildMeasureBoundaryIndices  s    F aa)*Oq#l+,AAEzLL! A - LL!,-rU   c                   U R                   (       d  [        S5      e/ nU R                  5       nU R                  U[	        U 5      S-
  5      nU GH  u  pE[        5       nUnUnU R                   U   n	[        U	[        5      (       a/  U	n
U
R                  S:X  a  U
R                  S:X  a  OXl
        US-   nO/US:w  a(  [        U R                   U   [        5      (       a  US-   nO U[	        U 5      :  a  [	        U 5      nOUnU R                   U   n[        U[        5      (       a.  UnUR                  S:X  a  UR                  S:X  d  Xl        US-
  nOl[        U R                   U   [        5      (       a  OI[        U R                   U   [        [        45      (       a  U[	        U R                   5      S-
  :X  d  US-
  nU R                   XxS-    Ul         U(       d  GM  UR                  U5        GM     U$ )a'  
Divide a token list by Measures, also
defining start and end bars of each Measure.

If a component does not have notes, leave
as an empty bar. This is often done with leading metadata.

Returns a list of ABCHandlerBar instances.
The first usually defines only Metadata

TODO: Test and examples
r  rJ   rF  r   r   rZ  )r  r   tokensToBarIndicesr  r   r   r  r   r@  rB  leftBarTokenr
   rightBarTokenr   r   r   )rb   abcBarHandlers
barIndicesmeasureIndicesrs  rr  r  xClipyCliptokenAtXlbCandidate
yTestIndextokenAtYTestIndexrbCandidates                 rV   splitByMeasureABCHandler.splitByMeasure4  s    {{%&PQQ,,.
 :::s4yST}U #DAB EE {{1~H(F++&.  ''83'22e;&1O A
 aJt{{1~{CCA
 CI~ Y

 $J 7+V44&7#++x7'22g= (3$ ADKK
3[AA !Z!87H:MNN$DKK(81(<< #Q E!)4BI!!"%Q #` rU   c                x   / nSn[        U R                  5       H  u  p4 U R                  US-      n[        U[        5      (       a  UR                  U5        M@  [        U[        5      (       d  MW  Uc  M\  [        U[        [        45      (       d  My  UR                  U5        M     U$ ! [         a    Sn Nf = f)z
Return a list of indices indicating which tokens in self.tokens are
bar lines or the last piece of metadata before a note or chord.
NrJ   )	r  r  r  r  r   r   r
   r   r   )rb   r  r  r  r  s        rV   r  ABCHandler.tokensToBarIndices  s    
 
!$++.HAAE* %((!!!$ UK00' ((;<<!!!$# /& !  s   B**B98B9c                    U R                   (       d  [        S5      eSnU R                    H%  n[        U[        [        45      (       d  M   US-  nM'     US:  a  gg)aN  
If tokens are processed, return True if ABCNote or
ABCChord classes are defined

>>> abcStr = 'M:6/8\nL:1/8\nK:G\n'
>>> ah1 = abcFormat.ABCHandler()
>>> junk = ah1.process(abcStr)
>>> ah1.hasNotes()
False

>>> abcStr = 'M:6/8\nL:1/8\nK:G\nc1D2'
>>> ah2 = abcFormat.ABCHandler()
>>> junk = ah2.process(abcStr)
>>> ah2.hasNotes()
True
z"must process tokens before callingr   rJ   TF)r  r   r  r   r   )rb   r  r  s      rV   hasNotesABCHandler.hasNotes  sT    " {{%&JKK[[E%'8!455
 ! 19rU   c                    U R                   (       d  [        S5      eU R                    H=  n[        U[        5      (       d  M  UR	                  5       (       d  M1  UR
                  s  $    g)zU
Get the first title tag. Used for testing.

Requires tokens to have been processed.
r  N)r  r   r  r
   r   r   r  s     rV   getTitleABCHandler.getTitle  sL     {{%&PQQ[[E%--==?? ::% ! rU   )r  r  r  r  r  r  r  r  r  rm   r  N)r  ztuple[int, ...])r"  zSequence[_T]r  r   rz   z*tuple[_T | None, _T, _T | None, _T | None])rm   ry   r  r   rz   r   )r  ry   rz   zlist[ABCBar])rz   ry   )r<  ry   rz   r9  )r=  zre.Matchrz   tuple[int, int, int])r   ry   r%  
str | Noner&  r  rz   r;  )rm   ry   rz   r9  r8  )rz   zdict[int | None, ABCHandler])rz   zlist[ABCHandler])r  	list[int]r  r   rz   zlist[list[int]])rz   list[ABCHandlerBar])rz   r  r:  )rz   r  )!rP   rQ   rR   rS   r{   r#   abcVersionDefaultrc   r}   r'  r,  r0  r6  r>  r;  rL  rR  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rT   rN   rU   rV   r   r   +  sD    08/I/I).$,$  1* 1*%I1* 1*h  4 / /h$F$ . .,+>\ /&/"*//3/ /dBHzx  J!FiV(!F\| 222 
2 2hm^8:rU   r   c                  6   ^  \ rS rSrSrSU 4S jjrS rSrU =r$ )r   i  z|
A Handler specialized for storing bars. All left
and right bars are collected and assigned to their respective attributes.
c                >   > [         TU ]  5         S U l        S U l        g ra   )r   rc   r  r  )rb   r   s    rV   rc   ABCHandlerBar.__init__  s    )-*.rU   c                   U R                  5       nU R                  UR                  -   Ul        S H  n[        X5      n[        X5      nUc  Uc  M!  Ub  Uc  [        X#U5        M5  Uc  Ub  [        X#U5        MI  UR                  UR                  :X  a  [        X#U5        Mq  [
        R                  SXT/5        [        X#U5        M     U$ )Nr  r  z3cannot handle two non-None bars yet: got bNew, bOld)r   r  getattrsetattrr_   r#  r$  )rb   r  r  barAttrbOldbNews         rV   r  ABCHandlerBar.__add__  s    ^^KK%,,.	8G4)D5*D|!dlT*$"2T* 88txx'B. !++-b-1-9 : B.' 9* 	rU   r  r8  )	rP   rQ   rR   rS   r{   rc   r  rT   r=  r>  s   @rV   r   r     s    / rU   r   c                   Sn/ n[        [        U 5      5       H2  nX   R                  5       (       a  US-  nM!  UR                  U5        M4     / nUS::  a*  [	        5       nU  H  nXV-  nM	     UR                  U5        U$ SnU[        U 5      :  aa  X2;   a3  U[        U 5      S-
  :w  a!  UR                  X   XS-      -   5        US-  nOUR                  X   5        US-  nU[        U 5      :  a  Ma  U$ )z
Given a list of ABCHandlerBar objects, return a list of ABCHandlerBar
objects where leading metadata is merged, if possible,
with the bar data following.

This consolidates all metadata in bar-like entities.
r   rJ   r   )r  r   r  r   r   )barHandlersmCountmetadataPosr  mergedHandlersahbrb  s          rV   r   r     s    FK3{#$>""$$aKFq!	 % N{oAHC c"   #k"" A[)9A)=$=%%kn{q57I&IJQ%%kn5Q #k"" rU   c                      \ rS rSrSr\R                  4SS jjrSS jrS r	S r
S rSS	 jr\SS
 j5       rSSS jjrSrg)r    iB  z
ABC File or String access

The abcVersion attribution optionally specifies the (major, minor, patch)
version of ABC to process-- e.g., (2, 1, 0).

If not set, default ABC 1.3 parsing is performed.
c                ,    Xl         S U l        SU l        g r   r  filefilename)rb   r  s     rV   rc   ABCFile.__init__K  s    0:#	*,rU   c                D    [         R                  " USS9U l        Xl        g)z
Open a file for reading
zutf-8)encodingN)ioopenr  r  )rb   r  s     rV   r  ABCFile.openP  s    
 GGHw7	 !rU   c                    Xl         g)z
Assign a file-like object, such as those provided by
StringIO, as an open file object.

>>> from io import StringIO
>>> fileLikeOpen = StringIO()
N)r  )rb   fileLikes     rV   openFileLikeABCFile.openFileLikeZ  s	     	rU   c                    gr   rN   rg   s    rV   rh   ABCFile._reprInternald  s    rU   c                8    U R                   R                  5         g ra   )r  closerg   s    rV   r  ABCFile.closeg  s    		rU   Nc                V    U R                  U R                  R                  5       U5      $ )z
Read a file. Note that this calls readstr,
which processes all tokens.

If `number` is given, a work number will be extracted if possible.
)readstrr  read)rb   r  s     rV   r   ABCFile.readj  s      ||DIINN,f55rU   c                   / nSnU R                  S5       GH  nUR                  5       R                  S5      (       a*  UR                  SS5      R	                  5       SU 3:X  a  SnOUR                  5       R                  S5      (       aS  U(       dL   [        UR                  SS5      R	                  5       R                  SS5      5      nU[        U5      :X  a  SnO-U(       a&  UR                  5       R                  S5      (       a    OU(       d  M  UR                  U5        GM     U(       d  [        SU 35      eSR                  U5      nU$ ! [         a     NSf = f)an  
Extract the string data relating to a single reference number
from a file that defines multiple songs or pieces.

This method permits loading a single work from a collection/opus
without parsing the entire file.

Here is sample data that is not correct ABC but demonstrates the basic concept:

>>> fileData = """
...   X:1
...   Hello
...   X:2
...   Aloha
...   X:3
...   Goodbye
...   """

>>> file2 = abcFormat.ABCFile.extractReferenceNumber(fileData, 2)
>>> print(file2)
X:2
Aloha

If the number does not exist, raises an ABCFileException:

>>> abcFormat.ABCFile.extractReferenceNumber(fileData, 99)
Traceback (most recent call last):
music21.abcFormat.ABCFileException: cannot find requested
    reference number in source file: 99


If the same number is defined twice in one file (should not be) only
the first data is returned.

* Changed in v6.2: now a static method.
Fr*  zX:r  rw   Tz7cannot find requested reference number in source file: )
rl   r   r   r  rstripr   	TypeErrorr   r   r!  )rm   r  collectgatherline	forcedNumreferenceNumberss          rV   extractReferenceNumberABCFile.extractReferenceNumbers  s9   L LL&D zz|&&t,,c21F1M1M1OUWX^W_S`1`((..v #DLLb$9$@$@$B$J$J4QS$T UI CK/!%
 DJJL33D99vt$' '* "I&RT T  99W- ! s   A
E
E E c                    Ub  U R                  X5      n[        U R                  S9nU R                  [        R                  :X  a  UR                  USS 5        UR                  U5        U$ )zF
Read a string and process all Tokens.
Returns a ABCHandler instance.
Nr  r  )r*  r   r  r#   r  r>  r  )rb   rm   r  handlers       rV   r  ABCFile.readstr  sa    
 00@F8??h88844VDS\B 	rU   r  )r  r  )r  zstr | pathlib.Pathra   )rm   ry   r  r   rz   ry   )rm   ry   r  z
int | Nonerz   r   )rP   rQ   rR   rS   r{   r#   r  rc   r  r  rh   r  r   r}   r*  r  rT   rN   rU   rV   r    r    B  sR     ;C:T:T -
!6 A  A F rU   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 rS rS rSrg)Testi  c                2    SSK Jn  U" U [        5       5        g )Nr   )testCopyAll)music21.test.commonTestr2  globals)rb   r2  s     rV   testCopyAndDeepcopyTest.testCopyAndDeepcopy  s    7D')$rU   c           	     .   SSK Jn  UR                  SSS4UR                  SSS4UR                  SSS	4UR
                  S
SS4UR                  SSS4UR                  SSS44 H  u  p#pE[        5       nUR                  U5        UR                  nU R                  [        U5      U5        SnSn	U H;  n
[        U
[        5      (       a  U	S-  n	M  [        U
[        5      (       d  M6  US-  nM=     U R                  X5        U R                  X5        M     g )Nr   r               i#         r  K   r      ]      rY   rJ   )music21.abcFormatr   fyrareprisarnmysteryReel	aleIsDeartestPrimitivewilliamAndNancymorrisonsJigr   r  r  assertEqualr   r  r   r   )rb   r   tfcountTokens
noteTokenschordTokensr-  r  
countNotescountChordsrn  s              rV   testTokenizationTest.testTokenization  s   / $$c32""Ca0  #sB/$$c2q1&&R3##S#q1;
6Rj !lGR ^^FS[+6JKa**1$K7++!OJ	  Z4[6-;
rU   c                p   Sn[         R                  U5      R                  5       nU R                  US U S5        U R                  XS  S5        Sn[         R                  U5      R                  5       nU R                  US U S5        Sn[        R                  U5      nU R                  U/ SQ5        [        [        R                  U5      5      S   R                  5       nS	nU R                  [        R                  U5      S
   S5        SnU R                  [        R                  U5      S
   S5        g )NzA: this is a testzA:z this is a testz+Q: this is a test % and a following commentzQ:z=d|"G"e2d B2d|"C"gfe "D7"d2d|"G"e2d B2d|"A7""C"gfe "D7""D"d2c|)"G""C""D7"rT  z"A7"rU  rV  z"D"r  z=d2r   r   zA3/2A)	r   r   r   rJ  r  r  r  r  r  )rb   r_   postr  s       rV   testReTest.testRe  s   !""3'++-UdT*U%67;""3'++-UdT* N$$S)  6 	7 '',-b1557,,S1!4c:,,S1!4c:rU   c                   SSK Jn  UR                  SSS4UR                  SSS4UR                  S	S
S4UR
                  SS
S4UR                  SSS44 H  u  p#pE[        5       nUR                  U5        UR                  5         UR                  nU H  n[        U[        5      (       d  M  UR                  S:X  a  U R                  UR                  U5        MH  UR                  S:X  a  U R                  UR                  U5        Mv  UR                  S:X  d  M  U R                  UR                  U5        M     M     g )Nr   r8  Fyrareprisarnz3/4FzMystery Reelr   r3  zAle is Dear, Thez4/4r   zKitchen GirlzWilliam and Nancyz6/8r   r   r   )rC  r   rD  rE  rF  	kitchGirlrH  r   r  r  r  r  r
   r   rJ  r   )	rb   r   rK  titleEncodedmeterEncoded
keyEncodedr-  r  r  s	            rV   testTokenProcessMetadataTest.testTokenProcessMetadata  s   / $$oucB""ND#>  "4eSC  .%=&&(;UCH=
8R| !lGR   "^^Fe[11yyC'((\Bc)((\Bc)((Z@  =
rU   c                    SSK Jn  UR                  UR                  UR                  UR
                  UR                  UR                  4 H.  n[        5       nUR                  U5        UR                  5         M0     g )Nr   r8  )rC  r   rD  rE  rF  rG  r^  rH  r   r  r  )rb   r   rK  r-  s       rV   testTokenProcessTest.testTokenProcess  sl    / ##!!##%%
B !lGR   "
rU   c                (   SSK Jn  [        5       nUR                  " S5      Ul        U R                  UR                  S5      S5        S Ul        U R                  UR                  S5      S5        U R                  UR                  S5      S5        UR                  " S	5      Ul        U R                  UR                  S
5      S5        S Ul        U R                  UR                  S
5      S5        U R                  UR                  S5      S5        g )Nr   r/   rJ  r   )C#5F)C5Nz^c)rh  TB)B-4F)B4N_B)rl  T)r   r0   r   r  r  rJ  r  )rb   r0   ans      rV   testNoteParseTest.testNoteParse.  s    Y !$ 0 0 3-~> $-|<.> # 0 0 4-~> $-|<.>rU   c                    SSK Jn  [        5       nUR                  UR                  5        UR                  5       nS H  u  pEnUc  U R                  X4   R                  S 5        O(U R                  X4   R                  R                  U5        Uc   U R                  X4   R                  S 5        Ms  U R                  X4   R                  R                  U5        M     [        5       nUR                  UR                  5        UR                  5       nS H  u  pEnUc  U R                  X4   R                  S 5        O(U R                  X4   R                  R                  U5        Uc   U R                  X4   R                  S 5        Ms  U R                  X4   R                  R                  U5        M     [        5       nUR                  S5        UR                  5       nS H  u  pEnUc  U R                  X4   R                  S 5        O(U R                  X4   R                  R                  U5        Uc   U R                  X4   R                  S 5        Ms  U R                  X4   R                  R                  U5        M     g )Nr   r8  )r   NN)r   rD   rF   )rJ  rF   rF   )r=   rC   )r  r?   rF   )rs  )rJ   NrF   )r  r<   NM:6/8
L:1/8
K:G
c1D2)rs  )r  NN)rC  r   r   r  hectorTheHeror  rJ  r  r_   r  theBeggerBoy)rb   r   r  ahmr  rp  rl  s          rV   testSplitByMeasureTest.testSplitByMeasureB  s   /\


9**+!GA! y  !4!4d;  !4!4!8!8!<y  !5!5t<  !5!5!9!91=* \


9))*!GA! y  !4!4d;  !4!4!8!8!<y  !5!5t<  !5!5!9!91= \


,-!GA! y  !4!4d;  !4!4!8!8!<y  !5!5t<  !5!5!9!91=rU   c                @   SSK Jn  [        5       nUR                  UR                  5        UR                  5       nU R                  [        U5      S5        [        U5      nU R                  [        U5      S5        U R                  US   R                  5       5        U R                  US   R                  5       5        U R                  US   R                  5       5        U R                  US   R                  R                  S5        [        5       nUR                  UR                  5        UR                  5       nU R                  [        U5      S5        [        U5      nU R                  [        U5      S5        U R                  US   R                  5       5        U R                  US   R                  5       5        U R                  US   R                  5       5        U R                  US   R                  R                  S	5        [        5       nUR                  S
5        UR                  5       nU R                  [        U5      S5        [        U5      nU R                  [        U5      S5        U R                  US   R                  5       5        g )Nr   r8        r  rt  r<   
   r;   ru  r   rJ   )rC  r   r   r  rw  r  rJ  r   r   
assertTruer  assertFalser  r_   theAleWifesDaughter)rb   r   r  rx  r  s        rV   testMergeLeadingMetaDataTest.testMergeLeadingMetaData  s   / \


9))*!S2&-c2 	^,b1q)2245+4467r*3356+99==tD \


9001!S2&-c2^,b1q)2245r*3356r*3356+99==tD \


,-! 	S1%-c2^,a0q)2245rU   c                h   SSK Jn  [        5       nUR                  UR                  5        UR                  5       nU R                  [        U5      S5        U R                  [        UR                  5       5      S/5        U R                  [        US   5      S5        U R                  US   R                  S   R                  S5        U R                  US   R                  5       S5        [        5       nUR                  UR                  5        U R                  [        U5      S5        UR                  5       nU R                  [        U5      S5        U R                  [        UR                  5       5      S /5        U R                  US    R                  S   R                  S	5        U R                  [        US    5      S5        [        5       nUR                  UR                  5        U R                  [        U5      S
5        UR                  5       nU R                  [        U5      S5        U R                  [        [        UR                  5       5      5      / SQ5        U R                  US   R                  S   R                  S5        U R                  US   R                  5       S5        U R                  [        US   5      S5        U R                  US   R                  S   R                  S5        U R                  US   R                  5       S5        U R                  [        US   5      S5        U R                  US   R                  S   R                  S5        U R                  US   R                  5       S5        U R                  [        US   5      S5        g )Nr   r8  rJ   rj  X   zX:5zThe Begger Boy/   zM:6/8   rJ  )         r  zX:168z168  The Castle Gate   (HJ)Y   r  zX:166z166  Valentine Jigg   (Pe)C   r  zX:167z167  The Dublin Jig     (HJ))rC  r   r   r  rw  r  rJ  r   r  keysr  r_   r  testPrimitivePolyphonicvalentineJiggr   )rb   r   r  ahss       rV   testSplitByReferenceNumberTest.testSplitByReferenceNumber  s   / \


9))*'')S1%chhj)A3/SVb)Qq)--u5Q*,<=\


9445R"%'')S1%chhj)D62T))!,00':SY,\


9**+R#&'')S1%SXXZ 01?CS+//9S**,.KLSX+S+//9S**,.JKSX+S+//9S**,.LMSX+rU   c                ^   SSK Jn  UR                  S5      n[        5       nUR	                  U5        UR                  S5      nUR                  5         U R                  [        U5      S5        [        5       nUR	                  U5        UR                  S5      nUR                  5         U R                  [        U5      S5        UR                  S5      n[        5       nUR	                  U5        UR                  S	5      nUR                  5         U R                  [        U5      S
5        g )Nr   )corpuszessenFolksong/test0rj  J   rl  T   zessenFolksong/han1iS  e   )	r   r  getWorkr    r  r   r  rJ  r   )rb   r  fpafr  s        rV   testExtractReferenceNumberTest.testExtractReferenceNumber  s    "^^12Y
WWQZ

R"%Y
WWQZ

R"%^^01Y
WWS\

R#&rU   c                    SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        g )Nr   r8  F   )rC  r   r   r  slurTestrJ  r   rb   r   r  s      rV   	testSlursTest.testSlurs  s2    /\


9%%&R"%rU   c                    SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        g )Nr   r8  I   )rC  r   r   r  tieTestrJ  r   r  s      rV   testTiesTest.testTies   s2    /\


9$$%R"%rU   c                   SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        UR                  nSnU H  n[        U[        5      (       d  M  US-  nM!     U R                  US5        g Nr   r8  r?  rJ   )
rC  r   r   r  	crescTestrJ  r   r  r  r   rb   r   r  r  r  r  s         rV   	testCrescTest.testCresc  sr    /\


9&&'R"%E%//Q  	ArU   c                   SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        UR                  nSnU H  n[        U[        5      (       d  M  US-  nM!     U R                  US5        g r  )
rC  r   r   r  dimTestrJ  r   r  r  r   r  s         rV   testDimTest.testDim  sr    /\


9$$%R"%E%--Q  	ArU   c                    SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        g )Nr   r8  P   )rC  r   r   r  	staccTestrJ  r   r  s      rV   testStaccatoTest.testStaccato  2    /\


9&&'R"%rU   c                z   SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        UR                  nSnSnU H;  n[        U[        5      (       a  US-  nM  [        U[        5      (       d  M6  US-  nM=     U R                  US5        U R                  US5        g )Nr   r8  S   rJ   r   )rC  r   r   r  bowTestrJ  r   r  r  r   r   )rb   r   r  r  upBowsdownBowsr  s          rV   testBowTest.testBow$  s    /\


9$$%R"%E%**!E:..A	 
 	#1%rU   c                   SSK Jn  SSKJn  UR	                  5       nUR                  UR                  5        SR                  5       nUR                   Vs/ s H  n[        U5      PM     nnU R                  XF5        U R                  [        U5      S5        UR                  nSnSn	Sn
U Hf  n[        XR                  5      (       a  US-  nM$  [        XR                  5      (       a  U	S-  n	ME  [        XR                  5      (       d  Ma  U
S-  n
Mh     U R                  US5        U R                  U	S5        U R                  U
S5        g s  snf )Nr   r8  )r8   a  <music21.abcFormat.ABCMetadata 'X: 979'>
<music21.abcFormat.ABCMetadata 'T: Staccato test, plus accents and tenuto marks'>
<music21.abcFormat.ABCMetadata 'M: 2/4'>
<music21.abcFormat.ABCMetadata 'L: 1/16'>
<music21.abcFormat.ABCMetadata 'K: Edor'>
<music21.abcFormat.ABCNote 'B,2'>
<music21.abcFormat.ABCBar '|'>
<music21.abcFormat.ABCDimStart '!'>
<music21.abcFormat.ABCStaccato '.'>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCNote '^D'>
<music21.abcFormat.ABCStaccato '.'>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCTie '-'>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCParenStop '!'>
<music21.abcFormat.ABCSlurStart '('>
<music21.abcFormat.ABCTuplet '(3'>
<music21.abcFormat.ABCStaccato '.'>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCStaccato '.'>
<music21.abcFormat.ABCNote 'F'>
<music21.abcFormat.ABCStaccato '.'>
<music21.abcFormat.ABCAccent 'K'>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCNote 'B'>
<music21.abcFormat.ABCNote 'A'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCBar '|'>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCNote '^D'>
<music21.abcFormat.ABCTenuto 'M'>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCNote 'F'>
<music21.abcFormat.ABCTuplet '(3'>
<music21.abcFormat.ABCSlurStart '('>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCTie '-'>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCNote 'B'>
<music21.abcFormat.ABCStraccent 'k'>
<music21.abcFormat.ABCTenuto 'M'>
<music21.abcFormat.ABCNote 'A'>
<music21.abcFormat.ABCBar '|'>
<music21.abcFormat.ABCSlurStart '('>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCSlurStart '('>
<music21.abcFormat.ABCNote '^D'>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCNote 'F'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCTuplet '(3'>
<music21.abcFormat.ABCSlurStart '('>
<music21.abcFormat.ABCStraccent 'k'>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCAccent 'K'>
<music21.abcFormat.ABCNote 'F'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCNote 'A'>
<music21.abcFormat.ABCTie '-'>
<music21.abcFormat.ABCNote 'A'>
<music21.abcFormat.ABCBar '|'>
<music21.abcFormat.ABCSlurStart '('>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCNote '^D'>
<music21.abcFormat.ABCNote 'E'>
<music21.abcFormat.ABCNote 'F'>
<music21.abcFormat.ABCTuplet '(3'>
<music21.abcFormat.ABCSlurStart '('>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCNote 'F'>
<music21.abcFormat.ABCNote 'G'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCParenStop ')'>
<music21.abcFormat.ABCNote 'B'>
<music21.abcFormat.ABCNote 'A'>
<music21.abcFormat.ABCBar '|'>
<music21.abcFormat.ABCNote 'G6'>
V   rJ   r   )rC  r   r   r8   r   r  accTest
splitlinesr  ry   rJ  r   r  r   r   r   )rb   r   r8   r  tokensCorrectrs  tokensReceivedr  r  r+  r`  r  s               rV   testAccTest.testAcc4  s&   /%!!#


9$$%Vl JLm 	n +-))4)Q#a&)47R"%E%!4!455QE#9#9::QE#6#677Q  	AAA# 5s   Ec                    SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        g )Nr   r8  U   )rC  r   r   r  	graceTestrJ  r   r  s      rV   	testGraceTest.testGrace  r  rU   c                    SSK Jn  [        5       nUR                  UR                  5        U R                  [        U5      S5        g )Nr   r8  i   )rC  r   r   r  guineapigTestrJ  r   r  s      rV   testGuineaPigTest.testGuineaPig  s2    /\


9**+R#&rU   rN   N)rP   rQ   rR   rS   r5  rQ  rY  rb  re  rp  ry  r  r  r  r  r  r  r  r  r  r  r  r  rT   rN   rU   rV   r0  r0    sg    %76;4A4# ?(?>B16f+,Z'.&&

&& n`&'rU   r0  __main__)r  r  rz   r  )Pr{   
__future__r   __all__collections.abcr!   r  retypingr  unittestr   r"   r#   r$   r%   r&   rC  r   r  pathlibr(   r*   r,   r.   r0   r2   r4   r6   TypeVarr7   Environmentr#  rw  rK  rK   __annotations__compiler   r  r  reChordr9  rG  Music21Exceptionr   r   r   ProtoM21ObjectobjectsEqualSlottedObjectMixinr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    TestCaser0  
_DOC_ORDERrP   mainTest)r   s   0rV   <module>r     s  "F # % 	 	         '??  YYt_&&{3" &..X1qtX.
 MO I N
 

9%jj%

9%
**W
zz78jj56	55 		,77 		|44 	Bw%%v~~'M'M BJT	Q( T	QnYX Yxz4 z4~
X 
&8 &(8 -H -",( , ( x   8  H 8 %H %,dAh dATSHw SHn} }@.(J (V'XDg$$ DPd'8 d'R z=1
 zT Iz /s   9K"