
    rhZ                       S r SSKJr  SSKrSSKrSSKJr  SSKJr  SSK	J
r
  \R                  (       a  SSKJr   " S S	\R                  5      r " S
 S\R                  5      r " S S\
5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\R2                  5      r " S S\R6                  5      r\S :X  a  SSKr\R<                  " \5        gg)!z
The style module represents information about the style of a Note, Accidental,
etc. such that precise positioning information, layout, size, etc. can be specified.
    )annotationsN)common)exceptions21)ProtoM21Object	editorialc                      \ rS rSrSrg)TextFormatException    N__name__
__module____qualname____firstlineno____static_attributes__r       G/home/james-whalen/.local/lib/python3.13/site-packages/music21/style.pyr
   r
          r   r
   c                  P    \ 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)	Enclosure!   	rectanglesquareovalcirclebrackettrianglediamondpentagonhexagonheptagonoctagonnonagondecagonzinverted-bracketnoner   N)r   r   r   r   	RECTANGLESQUAREOVALCIRCLEBRACKETTRIANGLEDIAMONDPENTAGONHEXAGONHEPTAGONOCTAGONNONAGONDECAGONINVERTED_BRACKETNO_ENCLOSUREr   r   r   r   r   r   !   sN    IFDFGHGHGHGGG)Lr   r   c                      \ rS rSr% SrSSS.rS\S'   SS jr\SS	 j5       r	\	R                  SS
 j5       r	S rS r\" \\SS9rSrg)Style3   z
A style object is a lightweight object that
keeps track of information about the look of an object.

>>> st = style.Style()
>>> st.units
'tenths'
>>> st.absoluteX is None
True

>>> st.absoluteX = 20.4
>>> st.absoluteX
20.4

z
            If set to `True`, the Music21Object will not print upon output
            (only used in MusicXML output at this point and
            in Lilypond output for notes, chords, and rests).
            z
            What distances are measured in.  The default "tenths" is a concept
            borrowed from MusicXML which refers to 1/10th of the distance between
            two staff lines.  It is currently also the only supported unit.
            )hideObjectOnPrintunitsdict[str, str]	_DOC_ATTRc                    S U l         S U l        S U l        S U l        S U l        S U l        S U l        S U l        SU l        SU l	        S U l
        S U l        g )NtenthsF)size	relativeX	relativeY	absoluteX
_absoluteY
_enclosurefontRepresentationcolorr:   r9   
dashLengthspaceLengthselfs    r   __init__Style.__init__P   s_    	)-)-)- +/ +/ #'#
"
',*.+/r   c                    U R                   $ )as  
Get or set the enclosure as a style.Enclosure enum (or
None, which means the enclosure is left unspecified).

Valid names are:

* "rectangle"/style.Enclosure.RECTANGLE,
* "square"/style.Enclosure.SQUARE,
* "oval"/style.Enclosure.OVAL,
* "circle"/style.Enclosure.CIRCLE,
* "bracket"/style.Enclosure.BRACKET,
* "inverted-bracket"/style.Enclosure.INVERTED_BRACKET (output in musicxml 4 only)
* "none"/style.Enclosure.NO_ENCLOSURE
* None (i.e. enclosure is unspecified)

or the following other shapes with their ALLCAPS Enclosure equivalents:

triangle, diamond, pentagon, hexagon, heptagon, octagon,
nonagon, or decagon.

>>> tst = style.TextStyle()
>>> tst.enclosure = None
>>> tst.enclosure = style.Enclosure.RECTANGLE
>>> tst.enclosure
<Enclosure.RECTANGLE>

Setting as a string is still supported, but is converted to
an enum.

>>> tst.enclosure = 'octagon'
>>> tst.enclosure
<Enclosure.OCTAGON>

Setting an invalid enclosure raises a TextFormatException

>>> tst.enclosure = 'parabola'
Traceback (most recent call last):
music21.style.TextFormatException:
    Not a supported enclosure: 'parabola'


OMIT_FROM_DOCS

Similarly for non-strings:

>>> tst.enclosure = 4
Traceback (most recent call last):
music21.style.TextFormatException:
    Not a supported enclosure: 4

* Changed in v9.7: We now differentiate between no enclosure
  (Enclosure.NO_ENCLOSURE) and unspecified enclosure (None).
)rD   rI   s    r   	enclosureStyle.enclosurek   s    n r   c                   Uc  Xl         g [        U[        5      (       a  Xl         g [        U[        5      (       a!   [        UR	                  5       5      nX l         g [        SU< 35      e! [
         a  n[        SU< 35      UeS nAff = f)NzNot a supported enclosure: )rD   
isinstancer   strlower
ValueErrorr
   )rJ   value	enc_valueves       r   rN   rO      s    =#Oy))#Os##[%ekkm4	 (O &(CE9&MNN  [),Gy*QRXZZ[s   A, ,
B6BBc                    U R                   $ N)rC   rI   s    r   _getAbsoluteYStyle._getAbsoluteY   s    r   c                    Uc  S U l         g US:X  a  SU l         g US:X  a  SU l         g  [        R                  " U5      U l         g ! [         a  n[	        SU< 35      UeS nAff = f)Nabove
   belowiz$Not a supported absoluteY position: )rC   r   numToIntOrFloatrT   r
   rJ   rU   rW   s      r   _setAbsoluteYStyle._setAbsoluteY   sm    ="DOg DOg!DO"("8"8"? ):5)Ds   A 
A$AA$a\  
        Get or set the vertical position, where 0
        is the top line of the staff and units
        are whatever is defined in `.units`, generally "tenths", meaning
        1/10th of a staff space.

        Other legal positions are 'above' and 'below' which
        are synonyms for 10 and -70 respectively (for 5-line
        staves; other staves are not yet implemented)
        This behavior may change in music21 v8 or after.

        >>> te = style.Style()
        >>> te.absoluteY = 10
        >>> te.absoluteY
        10

        >>> te.absoluteY = 'below'
        >>> te.absoluteY
        -70

        Setting an invalid position raises a TextFormatException

        >>> te.absoluteY = 'hello'
        Traceback (most recent call last):
        music21.style.TextFormatException:
            Not a supported absoluteY position: 'hello'
        doc)rC   rD   rB   rF   rG   rE   r9   r@   rA   r?   rH   r:   NreturnNone)rg   zEnclosure | None)rU   zEnclosure | str | None)r   r   r   r   __doc__r<   __annotations__rK   propertyrN   setterrZ   rb   	absoluteYr   r   r   r   r7   r7   3   su     
!I~ 06 6 6p O O  &Ir   r7   c                  H   ^  \ rS rSr% SrSSSS.rS\S'   SU 4S	 jjrS
rU =r	$ )	NoteStyle   z
A Style object that also includes stem and accidental style information.

Beam style is stored on the Beams object.  Lyric style is stored on the Lyric
object.
a  
            An optional style.Style object describing what the stem looks like.

            >>> n = note.Note()
            >>> n.style.stemStyle is None
            True

            Note that stemStyle is not created automatically.  Users must
            instantiate a :class:`~music21.style.Style` object.

            >>> n.style.stemStyle = style.Style()
            >>> n.style.stemStyle.color = 'red'
            a  
            An optional style.Style object describing what the accidental looks like.

            >>> n = note.Note()
            >>> n.style.accidentalStyle is None
            True

            Note that accidentalStyle is not created automatically.  Users must
            instantiate a :class:`~music21.style.Style` object.

            >>> n.style.accidentalStyle = style.Style()
            >>> n.style.accidentalStyle.relativeX = -2.0

            Note: do not use .hideObjectOnPrint in accidentalStyle to hide the
            accidental.  Set the displayType on the Accidental itself.

            This object may eventually move to Note.pitch.accidental.style.
            a	  
            An optional string representing the size of the note as a type of note.

            Valid values are None (=normal), `'cue'`, `'grace'`, `'graceCue'`, and `'large'`
            (taken from MusicXML, with "graceCue" replacing "grace-cue").
            )	stemStyleaccidentalStylenoteSizer;   r<   c                L   > [         TU ]  5         S U l        S U l        S U l        g rY   )superrK   rq   rr   rs   rJ   	__class__s    r   rK   NoteStyle.__init__  s$    %)+/"&r   )rr   rs   rq   rf   )
r   r   r   r   ri   r<   rj   rK   r   __classcell__rw   s   @r   ro   ro      s1    $A&!I~ &P' 'r   ro   c                  d  ^  \ rS rSrSrU 4S jrS rS r\" \\SS9r	S r
S	 r\" \
\S
S9r\SS j5       r\R                  SS j5       r\SS j5       r\R                  SS j5       rS rS r\" \\SS9rS rS r\" \\SS9rS rS r\" \\SS9r\S 5       r\R                  S 5       rSrU =r$ )	TextStylei  z
A Style object that also includes text formatting.

>>> ts = style.TextStyle()
>>> ts.classes
('TextStyle', 'Style', 'ProtoM21Object', 'object')
c                   > [         TU ]  5         S U l        S U l        S U l        S U l        S U l        S U l        S U l        S U l	        S U l
        S U l        S U l        S U l        S U l        g rY   )ru   rK   _fontFamily	_fontSize
_fontStyle_fontWeight_letterSpacing
lineHeighttextDirectiontextRotationlanguagetextDecoration_justify_alignHorizontal_alignVerticalrv   s    r   rK   TextStyle.__init__%  sq    "! " $"r   c                    U R                   $ rY   )r   rI   s    r   _getAlignVerticalTextStyle._getAlignVertical8      """r   c                :    US;   a  Xl         g [        SU< 35      e)N)NtopmiddlebottombaselinezInvalid vertical align: )r   r
   rJ   rU   s     r   _setAlignVerticalTextStyle._setAlignVertical;  s$    AA"'%(@	&JKKr   a  
        Get or set the vertical align. Valid values are top, middle, bottom, baseline
        or None

        >>> te = style.TextStyle()
        >>> te.alignVertical = 'top'
        >>> te.alignVertical
        'top'

        Invalid vertical aligns raise a TextFormatException:

        >>> te.alignVertical = 'hello'
        Traceback (most recent call last):
        music21.style.TextFormatException:
            Invalid vertical align: 'hello'
        rd   c                    U R                   $ rY   )r   rI   s    r   _getAlignHorizontalTextStyle._getAlignHorizontalU  s    $$$r   c                :    US;   a  Xl         g [        SU< 35      e)N)NleftrightcenterzInvalid horizontal align: )r   r
   r   s     r   _setAlignHorizontalTextStyle._setAlignHorizontalX  s$    55$)!%(B5)&LMMr   a  
        Get or set the horizontal alignment.  Valid values are left, right, center,
        or None

        >>> te = style.TextStyle()
        >>> te.alignHorizontal = 'right'
        >>> te.alignHorizontal
        'right'

        Invalid horizontal aligns raise a TextFormatException:

        >>> te.alignHorizontal = 'hello'
        Traceback (most recent call last):
        music21.style.TextFormatException:
            Invalid horizontal align: 'hello'
        c                    U R                   $ )az  
Get or set the justification.  Valid values are left,
center, right, full (not supported by MusicXML), and None

>>> tst = style.TextStyle()
>>> tst.justify = 'center'
>>> tst.justify
'center'

Invalid values raise a TextFormatException

>>> tst.justify = 'hello'
Traceback (most recent call last):
music21.style.TextFormatException:
    Not a supported justification: 'hello'
)r   rI   s    r   justifyTextStyle.justifyr  s    $ }}r   c                    Uc  S U l         g UR                  5       S;  a  [        SU< 35      eUR                  5       U l         g )N)r   r   r   fullzNot a supported justification: )r   rS   r
   r   s     r   r   r     s=    = DM{{}$GG),KE9*UVV!KKMDMr   c                    U R                   $ )a  
Get or set the style, as normal, italic, bold, and bolditalic.
None is currently an acceptable value which should be "normal".

>>> tst = style.TextStyle()
>>> tst.fontStyle = 'bold'
>>> tst.fontStyle
'bold'

Invalid values raise a TextFormatException

>>> tst.fontStyle = 'hello'
Traceback (most recent call last):
music21.style.TextFormatException:
    Not a supported fontStyle: 'hello'
)r   rI   s    r   	fontStyleTextStyle.fontStyle  s    $ r   c                    Uc  S U l         g UR                  5       S;  a  [        SU< 35      eUR                  5       U l         g )N)italicnormalbold
bolditaliczNot a supported fontStyle: )r   rS   r
   r   s     r   r   r     s=    ="DO{{}$NN),Gy*QRR#kkmDOr   c                    U R                   $ rY   )r   rI   s    r   
_getWeightTextStyle._getWeight  s    r   c                    Uc  S U l         g UR                  5       S;  a  [        SU 35      eUR                  5       U l         g )N)r   r   zNot a supported fontWeight: )r   rS   r
   r   s     r   
_setWeightTextStyle._setWeight  s?    =#D{{}$66),H*PQQ${{}Dr   z
        Get or set the weight, as normal, or bold.

        >>> tst = style.TextStyle()
        >>> tst.fontWeight = 'bold'
        >>> tst.fontWeight
        'bold'
        c                    U R                   $ rY   )r   rI   s    r   _getSizeTextStyle._getSize  s    ~~r   c                d    Ub   [         R                  " U5      nXl        g ! [         a     Nf = frY   )r   r`   rT   r   r   s     r   _setSizeTextStyle._setSize  s8    ..u5   s   " 
//z
        Get or set the size.  Best, an int or float, but also a css font size

        >>> tst = style.TextStyle()
        >>> tst.fontSize = 20
        >>> tst.fontSize
        20
        c                    U R                   $ rY   )r   rI   s    r   _getLetterSpacingTextStyle._getLetterSpacing  r   r   c                ~    US:w  a  Ub   [        U5      nXl        g ! [         a  n[        SU< 35      UeS nAff = f)Nr   zNot a supported letterSpacing: )floatrT   r
   r   ra   s      r   _setLetterSpacingTextStyle._setLetterSpacing  sQ    H!2e $  )5eY?s    
<7<z
         Get or set the letter spacing.

        >>> tst = style.TextStyle()
        >>> tst.letterSpacing = 20
        >>> tst.letterSpacing
        20.0
        >>> tst.letterSpacing = 'normal'
        c                B    U R                   c  / U l         U R                   $ )a  
Returns a list of font family names associated with
the style, or sets the font family name list.

If a single string is passed then it is converted to
a list.

>>> ts = style.TextStyle()
>>> ff = ts.fontFamily
>>> ff
[]
>>> ff.append('Times')
>>> ts.fontFamily
['Times']
>>> ts.fontFamily.append('Garamond')
>>> ts.fontFamily
['Times', 'Garamond']
>>> ts.fontFamily = 'Helvetica, sans-serif'
>>> ts.fontFamily
['Helvetica', 'sans-serif']
)r~   rI   s    r   
fontFamilyTextStyle.fontFamily  s$    . #!Dr   c                    [         R                  " U5      (       a  Xl        g UR                  S5       Vs/ s H  o"R	                  5       PM     snU l        g s  snf )N,)r   
isIterabler~   splitstrip)rJ   	newFamilyfs      r   r   r     sB    Y''(3<??33GH3Ga	3GHDHs   A)r   r   r~   r   r   r   r   r   r   r   r   r   r   )rg   
str | None)rU   r   )rU   r   rg   rh   )r   r   r   r   ri   rK   r   r   rk   alignVerticalr   r   alignHorizontalr   rl   r   r   r   
fontWeightr   r   fontSizer   r   letterSpacingr   r   ry   rz   s   @r   r|   r|     s<   #&#L .."M&%N 22$O(  & ^^* *  & , , - *$	J  	H#
$ .."
M    4 I Ir   r|   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )TextStylePlacementi  z&
TextStyle plus a placement attribute
c                0   > [         TU ]  5         S U l        g rY   )ru   rK   	placementrv   s    r   rK   TextStylePlacement.__init__  s    r   )r   r   r   r   r   ri   rK   r   ry   rz   s   @r   r   r     s     r   r   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )BezierStylei#  z
From the MusicXML Definition.
c                v   > [         TU ]  5         S U l        S U l        S U l        S U l        S U l        S U l        g rY   )ru   rK   bezierOffsetbezierOffset2bezierXbezierYbezierX2bezierY2rv   s    r   rK   BezierStyle.__init__(  s:     !r   )r   r   r   r   r   r   r   rz   s   @r   r   r   #  s    	 	r   r   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )	LineStylei4  z
from the MusicXML Definition

Defines lineShape ('straight', 'curved' or None)
lineType ('solid', 'dashed', 'dotted', 'wavy' or None)
dashLength (in tenths)
spaceLength (in tenths)
c                Z   > [         TU ]  5         S U l        S U l        S U l        S U l        g rY   )ru   rK   	lineShapelineTyperG   rH   rv   s    r   rK   LineStyle.__init__>  s+    r   )rG   r   r   rH   r   rz   s   @r   r   r   4  s       r   r   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )StreamStyleiG  zr
Includes several elements in the MusicXML <appearance> tag in <defaults>
along with <music-font> and <word-font>
c                   > [         TU ]  5         / U l        / U l        / U l        / U l        S U l        S U l        / U l        / U l	        SU l
        SU l        S U l        S U l        g )NT)ru   rK   
lineWidths	noteSizes	distancesotherAppearances	musicFontwordFont
lyricFontslyricLanguagesprintPartNameprintPartAbbreviationmeasureNumberingmeasureNumberStylerv   s    r   rK   StreamStyle.__init__M  sj     " !%)" !%"&r   )r   r   r   r   r   r   r   r   r   r   r   r   r   rz   s   @r   r   r   G  s    
' 'r   r   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )	BeamStyleia  z
Style for beams
c                0   > [         TU ]  5         S U l        g rY   )ru   rK   fanrv   s    r   rK   BeamStyle.__init__f  s    r   )r   r   rz   s   @r   r   r   a  s     r   r   c                      \ rS rSrSr\rSrSS jr\	SS j5       r
\	SS j5       r\R                  SS j5       r\	SS j5       r\	SS	 j5       r\R                  SS
 j5       rSrg)
StyleMixinik  a  
Mixin for any class that wants to support style and editorial, since several
non-music21 objects, such as Lyrics and Accidentals will support Style.

Not used by Music21Objects because of the added trouble in copying etc. so
there is code duplication with base.Music21Object
_style
_editorialc                     S U l         S U l        g rY   r   rI   s    r   rK   StyleMixin.__init__x  s     #'48r   c                X     U R                     U R                   SL$ ! [         a     Nf = f)a  
Returns True if there is a :class:`~music21.style.Style` object
already associated with this object, False otherwise.

Calling .style on an object will always create a new
Style object, so even though a new Style object isn't too expensive
to create, this property helps to prevent creating new Styles more than
necessary.

>>> lObj = note.Lyric('hello')
>>> lObj.hasStyleInformation
False
>>> lObj.style
<music21.style.TextStylePlacement object at 0x10b0a2080>
>>> lObj.hasStyleInformation
True
N)r   AttributeErrorrI   s    r   hasStyleInformationStyleMixin.hasStyleInformation~  s3    &	KK KK4'(  		s    
))c                d    U R                   c  U R                  nU" 5       U l         U R                   $ )a=  
Returns (or Creates and then Returns) the Style object
associated with this object, or sets a new
style object.  Different classes might use
different Style objects because they might have different
style needs (such as text formatting or bezier positioning)

Eventually will also query the groups to see if they have
any styles associated with them.

>>> acc = pitch.Accidental()
>>> st = acc.style
>>> st
<music21.style.TextStyle object at 0x10ba96208>
>>> st.absoluteX = 20.0
>>> st.absoluteX
20.0
>>> acc.style = style.TextStyle()
>>> acc.style.absoluteX is None
True
)r   _styleClass)rJ   
styleClasss     r   styleStyleMixin.style  s,    0 ;;))J$,DK{{r   c                    Xl         g rY   )r   )rJ   newStyles     r   r
  r    s    r   c                    U R                   SL$ )a  
Returns True if there is a :class:`~music21.editorial.Editorial` object
already associated with this object, False otherwise.

Calling .style on an object will always create a new
Style object, so even though a new Style object isn't too expensive
to create, this property helps to prevent creating new Styles more than
necessary.

>>> acc = pitch.Accidental('#')
>>> acc.hasEditorialInformation
False
>>> acc.editorial
<music21.editorial.Editorial {}>
>>> acc.hasEditorialInformation
True
Nr   rI   s    r   hasEditorialInformation"StyleMixin.hasEditorialInformation  s    & OOt+,r   c                l    SSK Jn  U R                  c  UR                  " 5       U l        U R                  $ )a  
a :class:`~music21.editorial.Editorial` object that stores editorial information
(comments, footnotes, harmonic information, ficta).

Created automatically as needed:

>>> acc = pitch.Accidental()
>>> acc.editorial
<music21.editorial.Editorial {}>
>>> acc.editorial.ficta = pitch.Accidental('sharp')
>>> acc.editorial.ficta
<music21.pitch.Accidental sharp>
>>> acc.editorial
<music21.editorial.Editorial {'ficta': <music21.pitch.Accidental sharp>}>
r   r   )music21r   r   	Editorial)rJ   r   s     r   r   StyleMixin.editorial  s+    $ 	&??"'113DOr   c                    Xl         g rY   r  )rJ   eds     r   r   r    s    r   )r   r   Nrf   )rg   bool)rg   r7   )r  r7   )rg   editorial.Editorial)r  r  )r   r   r   r   ri   r7   r  	__slots__rK   rk   r  r
  rl   r  r   r   r   r   r   r   r   k  s     K(I9 ) )2  8 \\  - -(  ,  r   r   c                      \ rS rSrSrg)Testi  r   Nr   r   r   r   r  r    r   r   r  __main__)ri   
__future__r   typingtunittestr  r   r   music21.prebaser   TYPE_CHECKINGr   Music21Exceptionr
   StrEnumr   r7   ro   r|   r   r   r   r   r   SlottedObjectMixinr   TestCaser  r   mainTestr   r   r   <module>r)     s    #      * ??!	,77 	 $pN pf3' 3'lzI zIz % "   &'% '4 |** |~	8 	 zT r   