
    rhZ                   j   S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  \R:                  " S5      r \" S5      (       a  \" S5      (       a  SrOSr C " S S5      r!\!" 5       r"S r#S r$ " S S5      r% " S S\RL                  5      r' " S S \RP                  5      r) " S! S"\RP                  5      r*\+S#:X  a  SSKr\RX                  " \)5        gg! \  a    Sr Nf = f)$z
music21 translates to Lilypond format and if Lilypond is installed on the
local computer, can automatically generate .pdf, .png, and .svg versions
of musical files using Lilypond.
    )annotations)OrderedDict)	find_specN)clef)common)SubConverter)corpus)duration)environment)exceptions21key)note)stream)variant)lilyObjectszlily.translatez	PIL.ImagezPIL.ImageOpsFTc                  $    \ rS rSr% 0 rS\S'   Srg)_sharedCorpusTestObject7   zdict[str, stream.Stream]sharedCache N)__name__
__module____qualname____firstlineno__r   __annotations____static_attributes__r       P/home/james-whalen/.local/lib/python3.13/site-packages/music21/lily/translate.pyr   r   7   s    ,.K).r   r   c                    U [         R                  ;  a'  [        R                  " U 5      [         R                  U '   [         R                  U    $ N)sharedCacheObjectr   r	   parse)keyNames    r   _getCachedCorpusFiler%   >   s<    '33317g1F%%g.((11r   c                    [        U 5      n SnU  H6  nUR                  5       (       d  [        [        U5      S-  S-   5      nX-  nM8     U$ )z
Takes an id and makes it purely letters by substituting
letters for all other characters.


>>> print(lily.translate.makeLettersOnlyId('rainbow123@@dfas'))
rainbowxyzmmdfas
    a   )strisalphachrord)inputStringreturnStringcs      r   makeLettersOnlyIdr1   G   sO     k"KLyy{{CFRK"$%A 
 r   c                     \ rS rSrSR	                  5       rSR	                  5       rSR	                  5       rSR	                  5       rSR	                  5       r	SR	                  5       r
SS	S
SSSSSS.rSSSSSSSSSSSSS.rS rS rS  rS! rS" rS# rS$ rSSS& jrSSS' jrS( rS) rSTS* jrSUS+ jrSVS, jrS- rSUS. jr   SWS/ jrS0 rS1 rS2 r S3 r!S4 r"S5 r#S6 r$S7 r%S8 r&S9 r'S: r(S; r)  SXS< jr*S= r+S> r,S? r-S@ r.SA r/SB r0SYSC jr1  SYSD jr2 SZSE jr3SF r4S[SG jr5SZSH jr6SI r7S\SJ jr8  S]SK jr9SUSL jr:SM r;SUSN jr<SO r=SUSP jr>SUSQ jr?SRr@g%)^LilypondConverter]   zi
    ficta = #(define-music-function (parser location) () #{ \once \set suggestAccidentals = ##t #})
    a;  
    color = #(define-music-function (parser location color) (string?) #{
        \once \override NoteHead.color = #(x11-color color)
        \once \override Stem.color = #(x11-color color)
        \once \override Rest.color = #(x11-color color)
        \once \override Beam.color = #(x11-color color)
     #})
    z
    \paper { #(define dump-extents #t)
    indent = 0\mm
    force-assignment = #""
    oddFooterMarkup=##f
    oddHeaderMarkup=##f
    bookTitleMarkup=##f
    }
    zT
     \override Rest.transparent  = ##t
     \override Dots.transparent  = ##t
     zF
     \revert Rest #'transparent
     \revert Dots #'transparent
     z.
    \include "lilypond-book-preamble.ly"
    isisesesisihesehisesiheh)zdouble-sharpzdouble-flatzone-and-a-half-sharpzone-and-a-half-flatsharpflatz
half-sharpz	half-flat|:dashed.z||z|.z.|z.|.z|:z:|'r'   )regulardottedrA   heavydoublefinalzheavy-lightzheavy-heavyzstart-repeatz
end-repeatticknonec                l   SU l         SU l        SU l        SU l        SU l        SU l        SU l        [        R                  " 5       U l	        U R                  5         U R                  U l        / U l        / U l        S U l        / U l        / SQU l        SU l        SU l        S U l        S U l        S U l        g )	N10z1.0psr'   
--backend=)blueredpurplegreenorangeyellowgreyF)majorVersionminorVersionversionStringbackendversionSchemeheaderSchemebackendStringlyoLyLilypondToptopLevelObject
setupToolscontextstoredContextsdoNotOutputcurrentMeasureaddedVariantsvariantColorscoloredVariantsvariantModeLILYEXECtempNameinWordselfs    r   __init__LilypondConverter.__init__   s    ")!//1** "[$ r   c                   [         S   nUb"  UR                  5       (       a  [        U5      nGO[        R                  " 5       nUS:X  a)  Sn[
        R                  R                  U5      (       d  SnOUS:X  at  [
        R                  R                  S5      (       aP  Sn[
        R                  R                  U5      (       d)  [
        R                  R                  US-   5      (       d  SnOXUS:X  aP  S	n[
        R                  R                  U5      (       d)  [
        R                  R                  US-   5      (       d  SnOSnX l        U$ )
NlilypondPathdarwinz:/Applications/Lilypond.app/Contents/Resources/bin/lilypondlilypondwinzc:/Program Files (x86)z2c:/Program\ Files\ (x86)/lilypond/usr/bin/lilypondz.exez+c:/Program\ Files/lilypond/usr/bin/lilypond)environLocalexistsr*   r   getPlatformospathrj   )rn   lpEnvironmentrj   platforms       r   findLilyExecLilypondConverter.findLilyExec   s    $^4$)=)=)?)?=)H))+H8#Www~~h//)HU"rww~~6N'O'OPww~~h//xRXGX8Y8Y)HU"Iww~~h//xRXGX8Y8Y)H% r   c                   U R                  5       nUS/n[        R                  " 5       nUS:X  a  [        R                  OSn [        R
                  " U[        R                  US9 nUR                  5       u  pgUR                  SS9nUR                  5       S   nUR                  S5      n	S S S 5        W	S   U l        U	S
   U l        U R                  R                  S-   U R                  R!                  [#        U R                  5      S-   [#        U R                  5      -   5      -   U l        [&        R(                  " U R$                  5      U l        [&        R(                  " U R,                  5      U l        SU l        [3        U R                  5      S:  a)  [3        U R                  5      S:  a  SU l        g SU l        g SU l        g ! , (       d  f       GN$= f! [         a  n
[        S	5      U
eS n
A
ff = f)Nz	--versionru   r   )stdoutcreationflagsutf-8encoding   rB   zCannot find a copy of Lilypond installed on your system. Please be sure it is installed. And that your environment.UserSettings()['lilypondPath'] is set to find it.   zversion rN      z
-dbackend=rO   )r}   r   rx   
subprocessCREATE_NO_WINDOWPopenPIPEcommunicatedecodesplitOSErrorLilyTranslateExceptionrW   rX   r`   	backslashquoteStringr*   rY   r^   LyEmbeddedScmr[   
bookHeaderr\   rZ   intr]   )rn   rj   commandr|   creation_flagsprocr   unusedrY   versionPiecesexcs              r   ra   LilypondConverter.setupTools   s   $$&[)%%'8@E8I44q	\!!'*//0>@CG!%!1!1!38 &q 1 - 3 3C 8@ *!,)!,"11;; *+ $ 3 3 ? ?DDUDU@VBEAFBEdFWFWBXAY !ZZ
 !..t/A/AB--doo>t  !Q&4$$%+%1"%1"!-D?@ @  	\(RS Y\\	\s7   $G 'AG
-G 

GG G 
G7&G22G7c                Z    U R                   R                  U R                  5        Xl        g r!   )rc   appendrb   )rn   
newContexts     r   r   LilypondConverter.newContext   s    ""4<<0!r   c                     U R                   R                  5       U l        g ! [         a    U R                  U l         g f = fr!   )rc   poprb   
IndexErrorr`   rm   s    r   restoreContext LilypondConverter.restoreContext   s9    	/..224DL 	/..DL	/s   " A A c                    U R                  U5        [        U R                  5      n[        R                  " SSU5      R                  5       nU$ )am  
get a proper lilypond text file for writing from a music21 object


>>> n = note.Note()
>>> print(lily.translate.LilypondConverter().textFromMusic21Object(n))
\version "2..."
\include "lilypond-book-preamble.ly"
color = #(define-music-function (parser location color) (string?) #{
        \once \override NoteHead.color = #(x11-color color)
        \once \override Stem.color = #(x11-color color)
        \once \override Rest.color = #(x11-color color)
        \once \override Beam.color = #(x11-color color)
     #})
\header { }
\score  {
      << \new Staff  = ... { c' 4
              }
        >>
  }
\paper { }
...
z
\s*\n\s*\n
)loadFromMusic21Objectr*   r`   resubstrip)rn   m21ObjectInss      r   textFromMusic21Object'LilypondConverter.textFromMusic21Object   sB    0 	"";/##$FF=$*002r   c                   UR                   nSU;   aC  U[        R                     (       a+  [        R                  " USS9n[        R                  " U5        SU;  d  SU;   d  SU;   a_  [
        R                  " 5       n[
        R                  " 5       nUR                  SU5        UR                  SU5        U R                  USS9  gS	U;   a8  [
        R                  " 5       nUR                  SU5        U R                  USS9  gS
U;   a  U R                  USS9  gSU;   a  U R                  USS9  g[
        R                  " 5       nUR                  SU5        U R                  USS9  g)z
Create a Lilypond object hierarchy in self.topLevelObject from an
arbitrary music21 object.

TODO: make lilypond automatically run makeNotation.makeTupletBrackets(s)
TODO: Add tests.
StreamT)recurseMeasureVoicer   FmakeNotationPartScoreOpusN)classesr   VariantmakeAllVariantsReplacementsmakeVariantBlocksr   r   r   insertloadObjectFromScoreloadObjectFromOpus)rn   r   r0   scoreObjpartObjs        r   r   'LilypondConverter.loadFromMusic21Object  s/    q=7??+%AA+W[\))+6A9>w!|||~HkkmGNN1k*OOAw'$$XE$Bq[||~HOOA{+$$XE$B\$$[u$Eq[##Ke#D||~HOOA{+$$XE$Br   Nc                   / nU R                   nU R                  n[        R                  " U R                  5      nUR                  U5        UR                  U5        UR                  U5        UR                   H  nUSL a  UR                  SS9n[        R                  " 5       nU R                  U5      n	UR                  b  U R                  UR                  US9  UR                  U5        UR                  U	5        M     [        R                  " SS9n
[        R                  " U
S9n[        R                  " US	9nUR                  U5        [        R                  " 5       nUR                  U5        X0R                   l        g)
a  
creates a filled topLevelObject (lily.lilyObjects.LyLilypondTop)
whose string representation accurately reflects all the Score objects
in this Opus object.


>>> #_DOCS_SHOW fifeOpus = corpus.parse('miscFolk/americanfifeopus.abc')
>>> #_DOCS_SHOW lpc = lily.translate.LilypondConverter()
>>> #_DOCS_SHOW lpc.loadObjectFromOpus(fifeOpus, makeNotation=False)
>>> #_DOCS_SHOW lpc.showPDF()
TFinPlaceNlpHeaderpaperdefTypeoutputDefHeadoutputDefBody)r[   r\   r^   r   colorDefr   scoresr   LyLilypondHeaderlyScoreBlockFromScoremetadatasetHeaderFromMetadataLyOutputDefHeadLyOutputDefBodyLyOutputDefLyLayoutrb   contents)rn   opusInr   r   lpVersionSchemelpHeaderSchemelpColorScheme	thisScorer   lpScoreBlocklpOutputDefHeadlpOutputDefBodylpOutputDeflpLayouts                 r   r   $LilypondConverter.loadObjectFromOpus?  s8    ,,**))$--8('&It#%2252A	++-H55i@L!!-**9+=+=*QOOH%OOL) ' --g>--OLooOD$<<>! (r   c                   USL a  UR                  SS9nU R                  nU R                  n[        R                  " U R
                  5      n[        R                  " 5       nU R                  U5      n[        R                  " SS9n[        R                  " US9n	[        R                  " U	S9n
[        R                  " 5       nX4UXgX/nUR                  b  U R                  UR                  US	9  XR                  l        g)
aM  

creates a filled topLevelObject (lily.lilyObjects.LyLilypondTop)
whose string representation accurately reflects this Score object.


>>> lpc = lily.translate.LilypondConverter()
>>> #_DOCS_SHOW b = corpus.parse('bach/bwv66.6')
>>> b = lily.translate._getCachedCorpusFile('bach/bwv66.6') #_DOCS_HIDE
>>> lpc.loadObjectFromScore(b)
TFr   r   r   r   r   Nr   )r   r[   r\   r^   r   r   r   r   r   r   r   r   r   r   rb   r   )rn   scoreInr   r   r   r   r   r   r   r   r   r   r   s                r   r   %LilypondConverter.loadObjectFromScorej  s     4**5*9G,,**))$--8'') 11':--g>--OLooOD<<>#]KC '&&w'7'7(&K (r   c                   [         R                  " 5       nU R                  U5        [        US5      (       aq  UR	                  5       R
                  (       aR  U[        R                     (       a"  U R                  U5      nU R                  UUS9nOU R                  U5      nXBl
        OU R                  U5      nXRl        [         R                  " US9n[         R                  " US9n[         R                  " US9nU R!                  5         U$ )Nparts)	scoreInitcompositeMusic)music)	scoreBody)r^   LyCompositeMusicr   hasattriterr   r   r   lyPartsAndOssiaInitFromScore$lyGroupedMusicListFromScoreWithPartsgroupedMusicList lyPrefixCompositeMusicFromStreamprefixCompositeMusicLyMusicLyScoreBodyLyScoreBlockr   )	rn   r   lpCompositeMusiclpPartsAndOssiaInitlpGroupedMusicListlpPrefixCompositeMusiclpMusiclpScoreBodyr   s	            r   r   'LilypondConverter.lyScoreBlockFromScore  s    //1() 7G$$)=)=w'&*&G&G&P#%)%N%N1 &O &3" &*%N%Nw%W"0B- &*%J%J7%S"4J1++-=>ooG4''+>r   c                    [         R                  " 5       n/ nSnUR                   GHM  n[        UR                  5      n[         R
                  " U5      nU R                  U5      n[         R                  " SUSXH-  S9n	UR                  U	5        / n
UR                  [        R                  5       H  nUR                  S   nX;  d  M  U R                  R                  U5        U
R                  U5        [         R
                  " [        U5      U-   5      n[         R                  " SUSXH-  S9nSSU S3S	S
SSSSSS/
n[         R                  " U5      nUUl        UR                  U5        M     GMP     X2l        U$ )a  
Takes in a score and returns a block that starts each part context and variant context
with an identifier and {\stopStaff s1*n} (or s, whatever is needed for the duration)
where n is the number of measures in the score.


>>> import copy

Set up score:

>>> s = stream.Score()
>>> p1,p2 = stream.Part(), stream.Part()
>>> p1.insert(0, meter.TimeSignature('4/4'))
>>> p2.insert(0, meter.TimeSignature('4/4'))
>>> p1.append(variant.Variant(name='london'))
>>> p2.append(variant.Variant(name='london'))
>>> p1.append(variant.Variant(name='rome'))
>>> p2.append(variant.Variant(name='rome'))
>>> for i in range(4):
...    m = stream.Measure()
...    n = note.Note('D4', type='whole')
...    m.append(n)
...    p1.append(m)
...    p2.append(copy.deepcopy(m))
>>> p1.id = 'pa'
>>> p2.id = 'pb'
>>> s.append(p1)
>>> s.append(p2)

Run method

>>> lpc = lily.translate.LilypondConverter()
>>> print(lpc.lyPartsAndOssiaInitFromScore(s))
\new Staff  = pa { \stopStaff s1 s1 s1 s1 }
\new Staff  = londonpa
            \with {
                  \remove "Time_signature_engraver"
                  alignAboveContext = #"pa"
                  fontSize = #-3
                  \override StaffSymbol.staff-space = #(magstep -3)
                  \override StaffSymbol.thickness = #(magstep -3)
                  \override TupletBracket.bracket-visibility = ##f
                  \override TupletNumber.stencil = ##f
                  \override Clef.transparent = ##t
                  \override OctavateEight.transparent = ##t
                  \consists "Default_bar_line_engraver"
                }
         { \stopStaff s1 s1 s1 s1 }
\new Staff  = romepa
            \with {
                  \remove "Time_signature_engraver"
                  alignAboveContext = #"pa"
                  fontSize = #-3
                  \override StaffSymbol.staff-space = #(magstep -3)
                  \override StaffSymbol.thickness = #(magstep -3)
                  \override TupletBracket.bracket-visibility = ##f
                  \override TupletNumber.stencil = ##f
                  \override Clef.transparent = ##t
                  \override OctavateEight.transparent = ##t
                  \consists "Default_bar_line_engraver"
                }
         { \stopStaff s1 s1 s1 s1 }
\new Staff  = pb { \stopStaff s1 s1 s1 s1 }
\new Staff  = londonpb
            \with {
                  \remove "Time_signature_engraver"
                  alignAboveContext = #"pb...
                  fontSize = #-3
                  \override StaffSymbol.staff-space = #(magstep -3)
                  \override StaffSymbol.thickness = #(magstep -3)
                  \override TupletBracket.bracket-visibility = ##f
                  \override TupletNumber.stencil = ##f
                  \override Clef.transparent = ##t
                  \override OctavateEight.transparent = ##t
                  \consists "Default_bar_line_engraver"
                }
         { \stopStaff s1 s1 s1 s1 }
\new Staff  = romepb
            \with {
                  \remove "Time_signature_engraver"
                  alignAboveContext = #"pb...
                  fontSize = #-3
                  \override StaffSymbol.staff-space = #(magstep -3)
                  \override StaffSymbol.thickness = #(magstep -3)
                  \override TupletBracket.bracket-visibility = ##f
                  \override TupletNumber.stencil = ##f
                  \override Clef.transparent = ##t
                  \override OctavateEight.transparent = ##t
                  \consists "Default_bar_line_engraver"
                }
         { \stopStaff s1 s1 s1 s1 }
z{ \stopStaff %s}newStafftype
optionalIdsimpleStringr   r   z!\remove "Time_signature_engraver"zalignAboveContext = #""zfontSize = #-3z1\override StaffSymbol.staff-space = #(magstep -3)z/\override StaffSymbol.thickness = #(magstep -3)z0\override TupletBracket.bracket-visibility = ##fz$\override TupletNumber.stencil = ##fz \override Clef.transparent = ##tz)\override OctavateEight.transparent = ##tz%\consists "Default_bar_line_engraver")r^   LyMusicListr   r1   idLyOptionalIdgetLySpacersFromStreamLyPrefixCompositeMusicr   getElementsByClassr   r   groupsrf   LyContextModificationoptionalContextModr   )rn   r   lpMusicList	musicListr   p
partIdTextpartIdspacerDurationlpPrefixCompositeMusicPartvariantsAddedForPartvvariantName	variantIdlpPrefixCompositeMusicVariantcontextModListr  s                    r   r   .LilypondConverter.lyPartsAndOssiaInitFromScore  s   z oo'	%A*1440J%%j1F!88;N),)C)COUQXJQJb*d& 78#% ))'//:hhqk:&&--k:(//< # 0 01B;1OR\1\ ]I474N4N"#,%,%6	51 'K)?
|1&M&7&Z&X&Y&M&I&R&N
&(N *-)B)B>)R&GY1D$$%BC5 ; N  )r   c                ~   SnU Hm  n[        U[        R                  5      (       d  M$  UR                  R                  S:X  a  M@   [        U R                  UR                  5      5      nUS-   U-   nMo     U$ !   UR                  R                   H%  n[        U R                  U5      5      nUS-   U-   nM'      M  = f)a  
Creates a series of Spacer objects for the measures in a Stream Part.


>>> m1 = stream.Measure(converter.parse('tinynotation: 3/4 a2.'))
>>> m2 = stream.Measure(converter.parse('tinynotation: 3/4 b2.'))
>>> m3 = stream.Measure(converter.parse('tinynotation: 4/4 a1'))
>>> m4 = stream.Measure(converter.parse('tinynotation: 4/4 b1'))
>>> m5 = stream.Measure(converter.parse('tinynotation: 4/4 c1'))
>>> m6 = stream.Measure(converter.parse('tinynotation: 5/4 a4 b1'))
>>> streamIn = stream.Stream([m1, m2, m3, m4, m5, m6])
>>> lpc = lily.translate.LilypondConverter()
>>> print(lpc.getLySpacersFromStream(streamIn))
s2. s2. s1 s1 s1 s1 s4

TODO: Low-priority: rare, but possible: tuplet time signatures (3/10), etc.
r'           r   )
isinstancer   r   r
   quarterLengthr*    lyMultipliedDurationFromDuration
components)rn   streamInmeasuresOnlyr/   eldurr0   s          r   r  (LilypondConverter.getLySpacersFromStream7  s    (  Bb&..11{{((C/<$??LM+c1C7 0 <//AdCCAFGC#/##5#;L 0s   ,A88AB<c           	        / n[         R                  " 5       n[         R                  " 5       n[         R                  " 5       nXel        XTl        U R                  U5        Uc4  UR                   H#  nUR                  U R                  U5      5        M%     ODUR                  U5        UR                   H#  nUR                  U R                  USSS95        M%     U R                  5         X6l        U$ )aU  
More complex example showing how the score can be set up with ossia parts:

>>> lpc = lily.translate.LilypondConverter()
>>> #_DOCS_SHOW b = corpus.parse('bach/bwv66.6')
>>> b = lily.translate._getCachedCorpusFile('bach/bwv66.6')  #_DOCS_HIDE
>>> lpPartsAndOssiaInit = lpc.lyPartsAndOssiaInitFromScore(b)
>>> lpGroupedMusicList = lpc.lyGroupedMusicListFromScoreWithParts(b,
...                scoreInit=lpPartsAndOssiaInit)
>>> print(lpGroupedMusicList)
<BLANKLINE>
 << \new Staff  = Soprano { \stopStaff s4 s1 s1 s1 s1 s1 s1 s1 s1 s2. }
   \new Staff  = Alto { \stopStaff s4 s1 s1 s1 s1 s1 s1 s1 s1 s2. }
   \new Staff  = Tenor { \stopStaff s4 s1 s1 s1 s1 s1 s1 s1 s1 s2. }
   \new Staff  = Bass { \stopStaff s4 s1 s1 s1 s1 s1 s1 s1 s1 s2. }
<BLANKLINE>
  \context Staff  = Soprano \with {
      \autoBeamOff
  }
  { \startStaff \partial 32*8
        \clef "treble"
        \key fis \minor
        \time 4/4
        \set stemRightBeamCount = #1
        \once \override Stem.direction = #DOWN
        cis'' 8 [
        \set stemLeftBeamCount = #1
        \once \override Stem.direction = #DOWN
        b... 8 ]
        \bar "|"  %{ end measure 0 %}
        \once \override Stem.direction = #UP
        a' 4
        \once \override Stem.direction = #DOWN
        b... 4
        \once \override Stem.direction = #DOWN
        cis'' 4  \fermata
        \once \override Stem.direction = #DOWN
        e'' 4
        \bar "|"  %{ end measure 1 %}
        \once \override Stem.direction = #DOWN
        cis'' 4
        ...
}
<BLANKLINE>
<BLANKLINE>
\context Staff  = Alto \with  {
    \autoBeamOff
 }
 { \startStaff \partial 32*8
    \clef "treble"...
    \once \override Stem.direction = #UP
    e' 4
    \bar "|"  %{ end measure 0 %}
    \once \override Stem.direction = #UP
    fis' 4
    \once \override Stem.direction = #UP
    e' 4
...
}
<BLANKLINE>
<BLANKLINE>
>>
<BLANKLINE>
rb   
startStaff)r  beforeMatter)r^   LyGroupedMusicListLySimultaneousMusicr
  r  simultaneousMusicr   r   r   r   r   r   )rn   r   r   compositeMusicListr   lpSimultaneousMusicr  r  s           r   r   6LilypondConverter.lyGroupedMusicListFromScoreWithPartsh  s    F   335!557oo'(3%/B,$]]"))$*O*OPQ*RS # %%i0]]"))99!?HGS : UV # 	1!!r   c                X   UR                  SS9nUc  [        UR                  5      nS[        R                  " 5       R                  U5      -   n/ n[        U5       H  n/ n[        R                  " SUUS9nUR                  U5        SU l	        XF    H%  n	U R                  U	5      n
UR                  U
5        M'     SU l	        [        R                  " U5      n[        R                  " US9n[        R                  " US9nUR                  U5        M     [        R                  " US	9nU$ )
a  
returns a LyNewLyrics object

This is a bit of a hack. This should be switched over to using a
prefixed context thing with \new Lyric = "id" \with { } {}

>>> s = converter.parse('tinyNotation: 4/4 c4_hel- d4_-lo r4 e4_world')
>>> s.makeMeasures(inPlace=True)
>>> s.id = 'helloWorld'

>>> lpc = lily.translate.LilypondConverter()
>>> lyNewLyrics = lpc.lyNewLyricsFromStream(s)
>>> print(lyNewLyrics)
\addlyrics { \set alignBelowContext = #"helloWorld"
   "hel" --
   "lo"__
   "world"
    }
T)skipTies#set)modevalue1value2Fr  sequentialMusic)groupedMusicLists)lyricsr1   r  r^   LyObjectr   sortedLyPropertyOperationr   rl   lyLyricElementFromM21Lyricr
  LySequentialMusicr/  LyNewLyrics)rn   r'  streamId	alignment
lyricsDictlpGroupedMusicListslyricNum	lyricListlpAlignmentPropertyr)  lpLyricElementlpLyricListlpSequentialMusicr   lpNewLyricss                  r   lyNewLyricsFromStream'LilypondConverter.lyNewLyricsFromStream  s   ( __d_3
(5H33H== z*HI"%"9"9uAJAI#K 01DK *!%!@!@!D  0 +  DK//)4K # 5 5 L!$!7!7HY!Z&&'9:% +( oo8KLr   c                z   [        U S5      (       a  U R                  nOSnUnUc
  U(       a  SnOoUc  USL a  SnOdUR                  S:X  a  SnOQUR                  c  SnOASUR                  -   S-   nUR                  S:X  a  US-   nSnOUR                  S;   a  US	-   nS
nX l        [        R
                  " U5      nU$ )a?  
Returns a :class:`~music21.lily.lilyObjects.LyLyricElement` object
from a :class:`~music21.note.Lyric` object.

Uses self.inWord to keep track of whether we're in the middle of
a word.

>>> s = converter.parse('tinyNotation: 4/4 c4_hel- d4_-lo r2 e2 f2_world')
>>> s.makeMeasures(inPlace=True)
>>> lyrics = s.lyrics()[1]  # get first verse (yes, 1 = first, not 0!)

>>> lpc = lily.translate.LilypondConverter()
>>> lpc.lyLyricElementFromM21Lyric(lyrics[0])
<music21.lily.lilyObjects.LyLyricElement "hel" -->
>>> lpc.inWord
True
>>> lpc.lyLyricElementFromM21Lyric(lyrics[1])
<music21.lily.lilyObjects.LyLyricElement "lo"__>
>>> lpc.lyLyricElementFromM21Lyric(lyrics[2])
<music21.lily.lilyObjects.LyLyricElement _>
>>> lpc.lyLyricElementFromM21Lyric(lyrics[3])
<music21.lily.lilyObjects.LyLyricElement "world">
>>> lpc.inWord
False
rl   Fz _ r'   r	  end__)beginmiddlez --T)r   rl   textsyllabicr^   LyLyricElement)rn   m21Lyricrl   r)  rY  rN  s         r   rD  ,LilypondConverter.lyLyricElementFromM21Lyric  s    6 4""[[FF:&DZFeODWW]DWW_D=3&D{{e#d{ 33e| ++D1r   c                   / n[         R                  " US9n[         R                  " UUS9nU R                  U5        U R	                  U5        U R                  5       nUb  UR                  U5        U R                  5         U$ )a  
returns a LySequentialMusic object from a stream

>>> c = converter.parse('tinynotation: 3/4 C4 D E F2.')
>>> lpc = lily.translate.LilypondConverter()
>>> lySequentialMusicOut = lpc.lySequentialMusicFromStream(c)
>>> lySequentialMusicOut
<music21.lily.lilyObjects.LySequentialMusic { \clef "b...>
>>> print(lySequentialMusicOut)
{ \clef "bass"
 \time 3/4
 c 4
 d 4
 e 4
 \bar "|"  %{ end measure 1 %}
 f 2.
 \bar "|."  %{ end measure 2 %}
  }
<BLANKLINE>
r   )r  r.  )r^   r
  rE  r    appendObjectsToContextFromStreamcloseMeasurer   r   )rn   r'  r.  r  r  rP  lyObjects          r   lySequentialMusicFromStream-LilypondConverter.lySequentialMusicFromStream1  s|    * 	ooy911K?KM$--h7$$&X&  r   c                T   UnSn/ nUR                   nUc>  SU;   a,  Sn	[        R                  " [        UR                  5      5      nO7SU;   a  Sn	O.Sn	O+Un	[        R                  " [        UR                  5      5      nUR
                  R                  SL a  UR                  S5        [        US5      (       aB  UR                  S:w  a2  UR                  S	UR                   35        UR                  S
-  S:X  a   U R                  U[        UR                  5      S9n
U R                  XS9n[        R                  " US9n[        R                  " UU
S9n[        R                  " US9nUc  SnU(       a  [        R                  " U5      nOSn[        R                   " UUU	UUS9nU$ )a  
returns an LyPrefixCompositeMusic object from
a stream (generally a part, but who knows!)

>>> c = converter.parse('tinynotation: 3/4 C4 D E F2.')
>>> c.staffLines = 4

>>> lpc = lily.translate.LilypondConverter()
>>> lyPrefixCompositeMusicOut = lpc.lyPrefixCompositeMusicFromStream(c, contextType='Staff')
>>> lyPrefixCompositeMusicOut
<music21.lily.lilyObjects.LyPrefixCompositeMusic \new Staff...>
>>> print(lyPrefixCompositeMusicOut)
\new Staff = ... \with {
 \override StaffSymbol.line-count = #4
}
{ \clef "bass"
     \time 3/4
     c 4
     d 4
     e 4
     \bar "|"  %{ end measure 1 %}
     f 2.
     \bar "|."  %{ end measure 2 %}
      }
<BLANKLINE>
<BLANKLINE>
Nr   r  r   Tz\autoBeamOff 
staffLines   z$\override StaffSymbol.line-count = #r   r   )rG  )r.  r=  )r   	newLyricsr   r  )r  r  r  r  r   )r   r^   r  r1   r  streamStatusbeamsr   r   rf  rR  rc  r/  r   r   r  r  )rn   r'  contextTyper  r.  compositeMusicTyper  r  r0   r   rQ  rP  r   r   r   
contextModr   s                    r   r   2LilypondConverter.lyPrefixCompositeMusicFromStreamV  s   F "
{$
 --.?.LM
A$
$
$J))*;HKK*HIJ  &&$.!!"238\**x/B/Ba/G!!%I(J]J]I^"_`""Q&!+00DUV^VaVaDb0c <<X<a 33DUV//AS:EG++-=>%!&22>BJJ!$!;!;ASGQISOYBI	"K
 &%r   c                   SSK Jn  U" U5       GH  n[        U5      S:X  a  US   nXl        U R	                  U5        M1  / n/ n/ nU H~  n[        U[        R                  5      (       a  UR                  U5        M5  [        U[        R                  5      (       a  UR                  U5        Mg  Xl        UR                  U5        M     U(       a*  U H	  nXl        M     U R                  UUU R                  S9  U(       a  / n	[        R                  " 5       n
[        R                  " 5       n[        R                   " 5       nXl        Xl        U H6  nXR&                  ;  d  M  U R)                  U5      nU	R                  U5        M8     Xl        U R,                  nUR*                  nUR                  U
5        U
R/                  U R,                  5        U(       d  GM  U H  nU R	                  U5        M     GM     g)a
  
takes a Stream and appends all the elements in it to the current
context's .contents list, and deals with creating Voices in it. It also deals with
variants in it.

(should eventually replace the main Score parts finding tools)


>>> lpc = lily.translate.LilypondConverter()
>>> lpMusicList = lily.lilyObjects.LyMusicList()
>>> lpc.context = lpMusicList
>>> lpc.context.contents
[]
>>> c = converter.parse('tinynotation: 3/4 b4 d- e#')
>>> lpc.appendObjectsToContextFromStream(c)
>>> print(lpc.context.contents)
[<music21.lily.lilyObjects.LyEmbeddedScm...>,
 <music21.lily.lilyObjects.LySimpleMusic...>,
 <music21.lily.lilyObjects.LySimpleMusic...>,
 <music21.lily.lilyObjects.LySimpleMusic...]
>>> print(lpc.context)
\clef "treble"
\time 3/4
b' 4
des' 4
eis' 4
<BLANKLINE>


>>> v1 = stream.Voice()
>>> v1.append(note.Note('C5', quarterLength = 4.0))
>>> v2 = stream.Voice()
>>> v2.append(note.Note('C#5', quarterLength = 4.0))
>>> m = stream.Measure()
>>> m.insert(0, v1)
>>> m.insert(0, v2)
>>> lpMusicList = lily.lilyObjects.LyMusicList()
>>> lpc.context = lpMusicList
>>> lpc.appendObjectsToContextFromStream(m)
>>> print(lpc.context)  # internal spaces removed
  << \new Voice { c'' 1
            \bar "|."  %{ end measure 1 %}
          }
   \new Voice { cis'' 1
          }
    >>
r   )OffsetIteratorr   
activeSiterh   N)music21.stream.iteratorrp  lenrr  appendM21ObjectToContextr#  r   r   r   r   r   appendContextFromVariantrh   r^   r/  r0  r
  r  r1  rd   r   r   rb   	setParent)rn   streamObjectrp  groupedElementsr)  	voiceListvariantList	otherListr  
musicList2lp2GroupedMusicListlp2SimultaneousMusiclp2MusicListvoicer   contextObjectcurrentMusicLists                    r   r`  2LilypondConverter.appendObjectsToContextFromStream  s   ` 	;-l;O ?#q($Q' ,--b1 	 	)B!"fll33!((,#B88#**2.(4!((, * ('3 )11+=IBFBVBV 2 X !#J*-*@*@*B'+.+B+B+D(#&??#4L5A2<P9!* (8(88595Z5Z[`5a2&--.DE "+
 -7)$(LLM'4'='=$$++,?@'11$,,?9'55b9 (c  <r   c                F   XR                   ;   a  gUR                  nSU;  aE  UR                  R                  S:X  a+  UR	                  5       nU H  nU R                  U5        M     gU R                  n[        US5      (       a  UR                  nO[        SU< 35      e[        US5      (       a@  UR                  SL a1  [        R                  " U R                  5      nUR                  U5        SnSU;   a  U R                  5       n	U	b"  UR                  U	5        U	R!                  U5        U R#                  U5      n
U
b"  UR                  U
5        U
R!                  U5        U R%                  U5        Xl        GOSU;   a5  U R)                  U5      nUR                  U5        UR!                  U5        GOS	U;   d  S
U;   a  U R+                  U5        GOwSU;   a  U R-                  U5        GO^SU;   a5  U R/                  U5      nUR                  U5        UR!                  U5        GO#SU;   a4  U R1                  U5      nUR                  U5        UR!                  U5        OSU;   aC  U R2                  SL a4  U R5                  U5      nUR                  U5        UR!                  U5        OSU;   a  U R7                  XR8                  S9  OSU;   a9  [        R                  " S5      nUR                  U5        UR!                  U5        OASU;   a9  [        R                  " S5      nUR                  U5        UR!                  U5        OSn[        US5      (       aB  UR:                  SL a2  [        R                  " U R<                  5      nUR                  U5        ggg)zd
converts any type of object into a lilyObject of LyMusic (
LySimpleMusic, LyEmbeddedScm etc.) type
Nr   complexr   z1Cannot get a currentMusicList from contextObject startTransparencyTr   NoteRestChordClefKeySignatureTimeSignatureFr   rh   SystemLayoutz\break
PageLayoutz
\pageBreakstopTransparency)rd   r   r
   r  splitAtDurationsru  rb   r   r   r   r  r^   r   transparencyStartSchemer   ra  rw  getSchemeForPaddingr`  re   r   appendContextFromNoteOrRestappendContextFromChordlyEmbeddedScmFromCleflyEmbeddedScmFromKeySignatureri   lyEmbeddedScmFromTimeSignaturerv  rh   r  transparencyStopScheme)rn   
thisObjectr0   thisObjectSplitsubComponentr  r  lySchemerb  closeMeasureObjpadObjs              r   ru  *LilypondConverter.appendM21ObjectToContext  sI   
 ))) 1!4!4!9!9Y!F(99;O /--l; !0=*--,55(CMCTUW W :233
8T8TX\8\(()E)EFH##H-> #//1O* ''8))-8--j9F! ''/  / 11*=",]<<ZHH##H-}- q[FaK,,Z8\''
3q[11*=H##H-}-q 99*EH##H-}-!d&6&6%&?:::FH##H-}-!^))*FZFZ)[q ((3H##H-}-Q((7H##H-}-H:122z7R7RVZ7Z(()D)DEH##H- 8[2r   c                f   UR                   R                  (       a  gU R                  U5        U R                  U5        U R	                  U5        U R                  U5      nU R                  R                  R                  U5        UR                  U R                  5        U R                  U5        g)aW  
appends lySimpleMusicFromNoteOrRest to the
current context.


>>> n = note.Note('C#4')
>>> lpc = lily.translate.LilypondConverter()
>>> lpMusicList = lily.lilyObjects.LyMusicList()
>>> lpc.context = lpMusicList
>>> lpc.appendContextFromNoteOrRest(n)
>>> print(lpMusicList)
cis' 4
<BLANKLINE>


>>> n2 = note.Note('D#4')
>>> n2.duration.quarterLength = 1/3
>>> n2.duration.tuplets[0].type = 'start'
>>> n3 = note.Note('E4')
>>> n3.duration.quarterLength = 1/3
>>> n4 = note.Note('F4')
>>> n4.duration.quarterLength = 1/3
>>> n4.duration.tuplets[0].type = 'stop'

>>> n5 = note.Note('F#4')

>>> lpc.appendContextFromNoteOrRest(n2)
>>> lpc.appendContextFromNoteOrRest(n3)
>>> lpc.appendContextFromNoteOrRest(n4)
>>> lpc.appendContextFromNoteOrRest(n5)

>>> print(lpc.context)
cis' 4
\times 2/3 { dis' 8
   e' 8
   f' 8
    }
<BLANKLINE>
fis' 4
<BLANKLINE>

N)r
   isGracesetContextForTupletStartappendBeamCodeappendStemCodelySimpleMusicFromNoteOrRestrb   r   r   rw  setContextForTupletStop)rn   
noteOrRestlpSimpleMusics      r   r  -LilypondConverter.appendContextFromNoteOrResth  s    X && 	%%j1J'J'88D$$]3-$$Z0r   c                .   U R                  U5        U R                  U5        U R                  U5        U R                  U5      nU R                  R
                  R                  U5        UR                  U R                  5        U R                  U5        g)a  
appends lySimpleMusicFromChord to the
current context.


>>> c = chord.Chord(['C4', 'E4', 'G4'])
>>> lpc = lily.translate.LilypondConverter()
>>> lpMusicList = lily.lilyObjects.LyMusicList()
>>> lpc.context = lpMusicList
>>> lpc.appendContextFromChord(c)
>>> print(lpMusicList)
< c' e' g'  > 4
<BLANKLINE>


>>> c2 = chord.Chord(['D4', 'F#4', 'A4'])
>>> c2.duration.quarterLength = 1/3
>>> c2.duration.tuplets[0].type = 'start'
>>> c3 = chord.Chord(['D4', 'F4', 'G4'])
>>> c3.duration.quarterLength = 1/3
>>> c4 = chord.Chord(['C4', 'E4', 'G4', 'C5'])
>>> c4.duration.quarterLength = 1/3
>>> c4.duration.tuplets[0].type = 'stop'

>>> c5 = chord.Chord(['C4', 'F4', 'A-4'])

>>> lpc.appendContextFromChord(c2)
>>> lpc.appendContextFromChord(c3)
>>> lpc.appendContextFromChord(c4)
>>> lpc.appendContextFromChord(c5)

>>> print(lpc.context)
< c'  e'  g'  > 4
\times 2/3 { < d'  fis'  a'  > 8
   < d'  f'  g'  > 8
   < c'  e'  g'  c''  > 8
    }
<BLANKLINE>
< c'  f'  aes'  > 4
<BLANKLINE>

N)	r  r  r  lySimpleMusicFromChordrb   r   r   rw  r  )rn   chordr  s      r   r  (LilypondConverter.appendContextFromChord  sw    V 	%%e,E"E"33E:$$]3-$$U+r   c                   UR                   n/ nUR                  (       a  UR                  R                  (       au  UR                  R                  SL a\  SUR                  R                   S3S-   nSUR                  R                   S3S-   nUR                  U5        UR                  U5        SU;   a  UR                  (       a  UR                  R                  SL a  U R                  UR                  5      nUR                  U5        UR                  R                  bj  UR                  R                  R                  S:X  a  UR                  S5        UR                  R                  R                  S	:X  a  UR                  S
5        OgUR                  S5        OUSU;   aO  UR                  (       a-  UR                  R                  (       a  UR                  S5        OUR                  S5        U R                  UR                  5      nUR                  U5        [        US5      (       a  UR                  (       aq  UR                  R                  S   R                   S:X  a  UR                  S5        O8UR                  R                  S   R                   S:X  a  UR                  S5        ["        R$                  " US9nU R'                  U5      n	["        R(                  " XS9n
["        R*                  " U
S9nU$ )a  
returns a lilyObjects.LySimpleMusic object for the generalNote containing this hierarchy::

    LyEventChord   containing
    LySimpleChordElements containing
    LySimpleElement containing
    LyPitch  AND
    LyMultipliedDuration containing:

        LyMultipliedDuration containing
        LyStenoDuration

does not check for tuplets.  That's in
appendContextFromNoteOrRest

read-only property that returns a string of the lilypond representation of
a note (or via subclassing, rest or chord)

>>> conv = lily.translate.LilypondConverter()

>>> n0 = note.Note('D#5')
>>> n0.pitch.accidental.displayType = 'always'
>>> n0.pitch.accidental.displayStyle = 'parentheses'
>>> n0.style.color = 'blue'
>>> sm = conv.lySimpleMusicFromNoteOrRest(n0)
>>> print(sm)
\override NoteHead.color = "blue"
\override Stem.color = "blue"
dis'' ! ? 4

Now make the note disappear:

>>> n0.style.hideObjectOnPrint = True
>>> sm = conv.lySimpleMusicFromNoteOrRest(n0)
>>> print(sm)
s 4
Fz\override NoteHead.color = "r	  r   z\override Stem.color = "r  always! parentheses? s r  zr rj  r   startz[ stopz] r   )
postEvents
eventChord)r   hasStyleInformationstylecolorhideObjectOnPrintr   lyPitchFromPitchpitch
accidentaldisplayTypedisplayStyler%  r
   r   rj  	beamsListr  r^   LySimpleElementpostEventsFromObjectLyEventChordLySimpleMusic)rn   r  r0   simpleElementPartsnoteheadColor	stemColorlpPitchlpMultipliedDurationsimpleElementr  evcmlSMs               r   r  -LilypondConverter.lySimpleMusicFromNoteOrRest  sq   L  ))%%**:*:*L*LPU*U#?
@P@P@V@V?WWX Y\` `7
8H8H8N8N7OqQTXX	"))-8")))4Q;11Z5E5E5W5W[`5`//
0@0@A"))'2##..:!''22>>(J*11$7!''22??=P*11$7"))$/q[--*2B2B2T2T"))$/"))$/#DDZEXEXY!!"67:w''J,<,<))!,11W<"))$/!!++A.33v="))$/++2DE..z:
}D  C0r   c                   SnSn[        US5      (       Ga^  UR                  GbO  UR                   H{  nUR                  S:X  a  US-  nM  UR                  S:X  a  US-  nUS-  nM6  UR                  S:X  a  US-  nMM  UR                  S:X  d  M_  UR                  S	:X  a  US-  nMv  US-  nM}     US:  a[  S
U 3n[        R
                  " U5      nU R                  R                  R                  U5        UR                  U R                  5        US:  a\  SU 3n[        R
                  " U5      nU R                  R                  R                  U5        UR                  U R                  5        gggg)al  
Adds an LyEmbeddedScm object to the context's contents if the object's has a .beams
attribute.

>>> lpc = lily.translate.LilypondConverter()
>>> lpMusicList = lily.lilyObjects.LyMusicList()
>>> lpc.context = lpMusicList
>>> lpc.context.contents
[]
>>> n1 = note.Note(quarterLength=0.25)
>>> n2 = note.Note(quarterLength=0.25)
>>> n1.beams.fill(2, 'start')
>>> n2.beams.fill(2, 'stop')

>>> lpc.appendBeamCode(n1)
>>> print(lpc.context.contents)
[<music21.lily.lilyObjects.LyEmbeddedScm \set stemR...>]
>>> print(lpc.context)
\set stemRightBeamCount = #2

>>> lpc = lily.translate.LilypondConverter()
>>> lpMusicList = lily.lilyObjects.LyMusicList()
>>> lpc.context = lpMusicList
>>> lpc.context.contents
[]
>>> lpc.appendBeamCode(n2)
>>> print(lpc.context.contents)
[<music21.lily.lilyObjects.LyEmbeddedScm \set stemL...>]
>>> print(lpc.context)
\set stemLeftBeamCount = #2

r   rj  Nr  r   continuer  partialleftz\set stemLeftBeamCount = #z\set stemRightBeamCount = #)
r   rj  r  	directionr^   r   rb   r   r   rw  )rn   noteOrChord	leftBeams
rightBeamsbbeamTextlpBeamSchemes          r   r   LilypondConverter.appendBeamCode5  sU   B 	
;((  ,$**Avv("a
:-"a
!Q	6)!Q	9,;;&0%NI&!OJ + q=$>ykLH#&#4#4X#>LLL))00> **4<<8>$?
|NH#&#4#4X#>LLL))00> **4<<8	 ") - )r   c                >   [        US5      (       a  UR                  b~  UR                  R                  5       nUS;   a]  SU S3n[        R                  " U5      nU R
                  R                  R                  U5        UR                  U R
                  5        gggg)a  
Adds an LyEmbeddedScm object to the context's contents if the object's stem direction
is set (currently, only "up" and "down" are supported).


>>> lpc = lily.translate.LilypondConverter()
>>> lpMusicList = lily.lilyObjects.LyMusicList()
>>> lpc.context = lpMusicList
>>> lpc.context.contents
[]
>>> n = note.Note()
>>> n.stemDirection = 'up'
>>> lpc.appendStemCode(n)
>>> print(lpc.context.contents)
[<music21.lily.lilyObjects.LyEmbeddedScm \once \ove...>]
>>> print(lpc.context.contents[0])
\once \override Stem.direction = #UP
stemDirectionN)UPDOWNz"\once \override Stem.direction = # )	r   r  upperr^   r   rb   r   r   rw  )rn   r  r  stemFilelpStemSchemes        r   r   LilypondConverter.appendStemCodes  s    & ;00[5N5N5Z'55;;=M. B=/QRU"00:%%,,\:&&t||4	 / 6[0r   c                L   U R                  U5        UR                  (       a  UR                  R                  SLa  U R	                  U5        / nUR
                   H  n/ nU R                  U5      nUR                  U5        UR                  bV  UR                  R                  S:X  a  UR                  S5        UR                  R                  S:X  a  UR                  S5        [        R                  " US9nUR                  U5        M     [        R                  " US9nO[        R                  " SS	5      nU R                  UR                   5      nU R#                  U5      n	[        R$                  " UUU	S
9n
[        R&                  " U
S9n[        R(                  " US9nU$ )a]  


>>> conv = lily.translate.LilypondConverter()
>>> c1 = chord.Chord(['C#2', 'E4', 'D#5'])
>>> c1.quarterLength = 3.5
>>> c1.pitches[2].accidental.displayType = 'always'
>>> print(conv.lySimpleMusicFromChord(c1))
 < cis, e' dis''  !  > 2..

test hidden chord:

>>> c1.style.hideObjectOnPrint = True
>>> print(conv.lySimpleMusicFromChord(c1))
s 2..
Tr  r  r  r  r  )chordBodyElementsr  r'   )	chordBodyoptionalNoteModeDurationr  )noteChordElementr  )r  r  r  r  r  pitchesr  r   r  r  r  r^   LyChordBodyElementLyChordBodyLyPitchr%  r
   r  LyNoteChordElementr  r  )rn   chordObjr  r  chordBodyElementPartsr  lpChordElementlpChordBodyr  r  lpNoteChordElementr  r  s                r   r  (LilypondConverter.lySimpleMusicFromChord  sh   " 	H%++x~~/O/OW[/[) "%%(*%//2%,,W5<<+||//8;-44T:||00MA-44T:!$!7!7>S!T!((8 & //<MNK++dB/K#DDXEVEVW..x8
 33kMa?IK 0BC  C0r   c                L   / n[        US5      (       a8  UR                  b+  UR                  R                  S:w  a  UR                  S5        [        US5      (       aG  UR                  (       a6  UR                   H&  nSUR
                  ;   d  M  UR                  S5        M(     U$ )zP
attaches events that apply to notes and chords (and some other things) equally
tier  z~ expressionsFermataz	\fermata )r   r  r  r   r  r   )rn   generalNoter  thisExpressions       r   r  &LilypondConverter.postEventsFromObject  s    
 
 ;&&;??+F##v-!!$';..;3J3J"-"9"9 6 66%%l3 #: r   c                v    U R                  U5      nU R                  U5      n[        R                  " X#5      nU$ )zM
converts a music21.pitch.Pitch object to a lily.lilyObjects.LyPitch
object.
)baseNameFromPitchoctaveCharactersFromPitchr^   r  )rn   r  baseNameoctaveModCharslyPitchs        r   r  "LilypondConverter.lyPitchFromPitch  s7     ))%077>++h7r   c                    UR                   R                  5       nUR                  bI  UR                  R                  U R                  ;   a%  X R                  UR                  R                     -  nU$ )zN
returns a string of the base name (including accidental)
for a music21 pitch
)steplowerr  nameaccidentalConvert)rn   r  r  s      r   r   #LilypondConverter.baseNameFromPitch  s`     ::##%'$$(>(>>2253C3C3H3HIIr   c                V    UR                   nUS:  a  SU-
  nSU-  nU$ US-
  nSU-  nU$ )zu
returns a string of single-quotes or commas or '' representing
the octave of a :class:`~music21.pitch.Pitch` object
   ,rC   )implicitOctave)rn   r  r  correctedOctaver  s        r   r  +LilypondConverter.octaveCharactersFromPitch  sO    
 --A.0O ?2N  -q0O ?2Nr   c                    [         R                  " UR                  5      nUS:X  a  [	        SU 35      eUS:  a  US:X  a  SnOUS	:X  a  S
nO[	        S5      e[        U5      n [        R                  " U[        UR                  5      5      n[        R                  " U5      nU$ ! [         R                   a  n[	        SU SU 35      eSnAff = f! [         R                   a  n[	        SU SU 35      eSnAff = f)a  
take a simple Duration (that is, one with one DurationTuple)
object and return a LyMultipliedDuration object:

>>> d = duration.Duration(3)
>>> lpc = lily.translate.LilypondConverter()
>>> lyMultipliedDuration = lpc.lyMultipliedDurationFromDuration(d)
>>> str(lyMultipliedDuration)
'2. '

>>> str(lpc.lyMultipliedDurationFromDuration(duration.Duration(8.0)))
'\\breve '
>>> str(lpc.lyMultipliedDurationFromDuration(duration.Duration(16.0)))
'\\longa '

Does not work with zero duration notes:

>>> d = duration.Duration(0.0)
>>> str(lpc.lyMultipliedDurationFromDuration(d))
Traceback (most recent call last):
music21.lily.translate.LilyTranslateException: Cannot translate an object of
    zero duration <music21.duration.Duration 0.0>


Does not work with complex durations:

>>> d = duration.Duration(5.0)
>>> str(lpc.lyMultipliedDurationFromDuration(d))
Traceback (most recent call last):
music21.lily.translate.LilyTranslateException: DurationException for durationObject
    <music21.duration.Duration 5.0>: Could not determine durationNumber from complex

Instead, split by components:

>>> components = d.components
>>> [str(lpc.lyMultipliedDurationFromDuration(c)) for c in components]
['1 ', '4 ']
z%DurationException for durationObject z: Nr   z,Cannot translate an object of zero duration r   g      ?z\breveg      ?z\longaz*Cannot support durations longer than longaz3DurationException: Cannot translate durationObject )
r
   convertTypeToNumberr  DurationExceptionr   r   r^   LyStenoDurationdotsLyMultipliedDuration)rn   durationObjnumber_typedestenoDurationmultipliedDurations         r   r%  2LilypondConverter.lyMultipliedDurationFromDuration  s+   V	M"66{7G7GHK
 !(>{mLN N ?c!'$',-YZZk*K	[//SAQAQ=RSM!$!9!9-!H "!1 )) 	M(7}BrdKM M	M* )) 	[(Ek]RTUWTXY[ [	[s0    B' %A C 'C;CCC>(C99C>c                F   [        / SQ5      nUR                  nSnUR                  5        H  u  pVXS;   d  M  Un  O   [        R	                  SU 35        Sn[
        R                  " 5       nUR                  S-   UR                  U5      -   UR                  -   nXl
        U$ )ac  
converts a Clef object to a
lilyObjects.LyEmbeddedScm object


>>> tc = clef.TrebleClef()
>>> conv = lily.translate.LilypondConverter()
>>> lpEmbeddedScm = conv.lyEmbeddedScmFromClef(tc)
>>> print(lpEmbeddedScm)
\clef "treble"

>>> t8c = clef.Treble8vbClef()
>>> lpEmbeddedScm = conv.lyEmbeddedScmFromClef(t8c)
>>> print(lpEmbeddedScm)
\clef "treble_8"

))Treble8vbCleftreble_8)
TrebleCleftreble)BassClefbass)AltoClefalto)	TenorCleftenor)SopranoClefsoprano)PercussionClef
percussionNz8got a clef that lilypond does not know what to do with: r'   zclef )r   r   itemsrv   
printDebugr^   r   r   r   newlineIndentcontent)	rn   clefObjdictTranslater0   lilyNamem21ClasslilyStrlpEmbeddedScm
clefSchemes	            r   r  'LilypondConverter.lyEmbeddedScmFromClefB  s    & $ %
  OO!.!4!4!6H}" "7
 ##J7)TVH))+#--7%11(;<%334
 !+r   c                X   [        U[        R                  5      (       d  UR                  S5      nUR                  nUR
                  nU R                  U5      n[        R                  " 5       nUR                  S-   U-   S-   UR                  -   U-   S-   UR                  -   nXel        U$ )ao  
converts a Key or KeySignature object
to a lilyObjects.LyEmbeddedScm object


>>> d = key.Key('d')
>>> conv = lily.translate.LilypondConverter()
>>> lpEmbeddedScm = conv.lyEmbeddedScmFromKeySignature(d)
>>> print(lpEmbeddedScm)
\key d \minor

Major is assumed:

>>> fSharp = key.KeySignature(6)
>>> print(conv.lyEmbeddedScmFromKeySignature(fSharp))
\key fis \major

majorzkey r  )r#  r   KeyasKeytonicr9  r   r^   r   r   r/  r0  )rn   keyObjr  mpnr6  	keySchemes          r   r  /LilypondConverter.lyEmbeddedScmFromKeySignatureq  s    ( &#''**\\'*FLLKK##A&))+",, "# %../ 233 	
 %223	 !*r   c                    [         R                  " 5       nUR                  S-   UR                  -   UR                  -   nX2l        U$ )z
convert a :class:`~music21.meter.TimeSignature` object
to a lilyObjects.LyEmbeddedScm object


>>> ts = meter.TimeSignature('3/4')
>>> conv = lily.translate.LilypondConverter()
>>> print(conv.lyEmbeddedScmFromTimeSignature(ts))
\time 3/4
ztime )r^   r   r   ratioStringr/  r0  )rn   tsr6  rA  s       r   r  0LilypondConverter.lyEmbeddedScmFromTimeSignature  sB     ))+!++g5FIdIdd	 )r   c                   UR                   R                  (       d  gUR                   R                  S   R                  S:X  a  [        [	        UR                   R                  S   R
                  S   5      5      n[        [	        UR                   R                  S   R                  S   5      5      nU R                  X#5      nU$ g)u  
if the inObj has tuplets then we set a new context
for the tuplets and anything up till a tuplet stop.

Note that a broken tuplet (à la Michael Gordon)
will not work.

If there are no tuplets, this routine does
nothing.  If there are tuplets, and they have type "start", then
it returns an lpMusicList object, which is the new context

For now, no support for nested tuplets.  They're an
easy extension, but there's too much
else that is missing to do it now.
Nr   r  )r
   tupletsr  r*   r   tupletNormaltupletActualsetContextForTimeFraction)rn   inObj	numeratordenominatorr  s        r   r  *LilypondConverter.setContextForTupletStart  s      ~~%%^^##A&++w6C 6 6q 9 F Fq IJKIc%.."8"8";"H"H"KLMK88PKr   c                   [        U5      S-   [        U5      -   n[        R                  " 5       n[        R                  " US9n[        R                  " SUUS9nU R
                  R                  nUc  [        SU R
                  < S35      eUR                  U5        UR                  U R
                  5        U R                  U5        U$ )aM  
Explicitly starts a new context for scaled music (tuplets, etc.)
for the given numerator and denominator (either an int or a string or unicode)

Returns an lpMusicList object contained in an lpSequentialMusic object
in an lpPrefixCompositeMusic object which sets the times object to a particular
fraction.


>>> lpc = lily.translate.LilypondConverter()
>>> lpc.context
<music21.lily.lilyObjects.LyLilypondTop>
>>> lyTop = lpc.context
>>> lyoMusicList = lpc.setContextForTimeFraction(5, 4)
>>> lyoMusicList
<music21.lily.lilyObjects.LyMusicList>
>>> lpc.context
<music21.lily.lilyObjects.LyMusicList>
>>> lpc.context is lyoMusicList
True
>>> lpc.context.getParent()
<music21.lily.lilyObjects.LySequentialMusic {  }>
>>> lpc.context.getParent().getParent()
<music21.lily.lilyObjects.LyPrefixCompositeMusic \times 5/4...>
>>> lpc.context.getParent().getParent().fraction
'5/4'
>>> lpc.context.getParent().getParent().type
'times'
>>> lpc.context.getParent().getParent().getParent()
<music21.lily.lilyObjects.LyLilypondTop \times 5/4...>
>>> lpc.context.getParent().getParent().getParent() is lyTop
True
/r<  timesr  fractionr   z'Cannot find contents for self.context: r  )r*   r^   r
  rE  r  rb   r   r   r   rw  r   )rn   rM  rN  rT  r  rP  r   currentContentss           r   rK  +LilypondConverter.setContextForTimeFraction  s    D y>C'#k*::oo'11KH
 "%!;!;EMBS"U ,,//"(9$,,9IKM M 	56((6$r   c                    UR                   R                  (       d  gUR                   R                  S   R                  S:X  a  U R                  5         gg)z%
Reverse of setContextForTupletStart
Nr   r  )r
   rH  r  r   )rn   rL  s     r   r  )LilypondConverter.setContextForTupletStop  s@     ~~%%^^##A&++v5!r   c                   / n/ n[        U[        R                  5      (       aX  UnUR                  U5      nU R	                  XgUS9nU R                  U5      n	UR                  U5        UR                  U	5        GOW[        U[        5      (       GaA  Sn
0 nU HE  nUR                  (       a  UR                  S   nOSnX;   a  X   R                  U5        M@  U/X'   MG     U H  nX   n[        U5      S:X  a8  US   nUR                  U5      nU R	                  XgUS9nUR                  U5        O%U R                  XUS9nUu  pUR                  U5        XR                  R                  :  d  M  UR                  R                  n
UnM     U R                  U5      n	UR                  U	5        U H  nU R                  R                  U5        M      [        R                  " 5       nUUl        [        R"                  " 5       nUUl        [        R&                  " 5       nUUl        U R*                  nUR                   nUR                  U5        UR-                  U R*                  5        g)zP
Create a new context from the variant object or a list of variants and append.
r  r   r   r   rq  N)r#  r   r   replacedElements!lyPrefixCompositeMusicFromVariantrc  r   listr  rt  )lyPrefixCompositeMusicFromRelatedVariantsr
   r$  rd   r^   r
  r   r0  r  r/  r1  rb   rw  )rn   variantObjectOrListrr  rh   r  longestReplacedElementsvariantObjectr[  r  lpSequentialMusicStandardlongestReplacementLengthvariantDictr  variant_keyr{  varTupler)  r  r  r~  r  r  s                         r   rv  *LilypondConverter.appendContextFromVariant  si    	"$)7??;;/M,==jI,0,R,R -S -) )-(H(HIY(Z%:;67+T22')$K!4 ''"/"6"6q"9K"+K-,33MB0=K, "5  +)6{#q($/NM'4'E'Ej'Q$484Z4Z% 5[ 5Z1$$%BC#MM#O  N  ]HFNC1$$%BC+.G.G.U.UU/?/H/H/V/V,.>+!  +$ )-(H(HI`(a%67-  ''+ . ( )"668)5&!4460D-(11 34%%dll3r   c                h  ^$ S m$UR                  U$4S jS9  US   R                  U5      nUS   nUR                  =(       d    UR                  [        R                  5      nUS   R                  [
        R                  5      nUc  US   R                  S5      nUS   R                  SU5        US   R                  S   nXR                  ;   a  Sn	OU R                  R                  U5        S	n	[        UR                  5      n
[        R                  " [        U5      U
-   5      nUS	L a,  U R                  U R                  R!                  U5      S
-     nOSn/ nSnSnS	U l        U GH  nT$" UR$                  5      nUU:  a  ['        S5      eUU-
  nUR(                  U-   nUS:  aY  [*        R,                  " 5       nS	UR.                  l        UUR2                  l        U R7                  U5      nUR                  U5        US	L a<  UR$                  R9                  5       R:                   H  nUUR.                  l        M     UR>                  n[@        RB                  " UR$                  RE                  UUS95      nUR(                  Ul        UR(                  nUR>                  U-
  nUU:w  ar  [F        RH                  " UU-  5      u  nn[K        U5      S-   [K        U5      -   nU RM                  U5      n[        RN                  " SUUS9n[        RP                  " US9nOU RM                  U5      nUR                  U5        UnGM     UR                  US	S9n[        RR                  " U5      n [        RP                  " U S9n!U	(       a  SOSn"[        RN                  " U"USU!S9n#SU l        U#U4$ )aC  


>>> s1 = converter.parse('tinynotation: 4/4 a4 a a a  a1')
>>> s2 = converter.parse('tinynotation: 4/4 b4 b b b')
>>> s3 = converter.parse('tinynotation: 4/4 c4 c c c')
>>> s4 = converter.parse('tinynotation: 4/4 d4 d d d')
>>> s5 = converter.parse('tinynotation: 4/4 e4 e e e  f f f f  g g g g  a a a a  b b b b')

>>> for s in [ s1, s2, s3, s4, s5]:
...     s.makeMeasures(inPlace=True)

>>> activeSite = stream.Part(s5.elements)

>>> v1 = variant.Variant()
>>> for el in s1:
...     v1.append(el)
>>> v1.replacementDuration = 4.0

>>> v2 = variant.Variant()
>>> sp2 = note.Rest()
>>> sp2.style.hideObjectOnPrint = True
>>> sp2.duration.quarterLength = 4.0
>>> v2.replacementDuration = 4.0
>>> v2.append(sp2)
>>> for el in s2:
...     v2.append(el)

>>> v3 = variant.Variant()
>>> sp3 = note.Rest()
>>> sp3.style.hideObjectOnPrint = True
>>> sp3.duration.quarterLength = 8.0
>>> v3.replacementDuration = 4.0
>>> v3.append(sp3)
>>> for el in s3:
...     v3.append(el)

>>> v4 = variant.Variant()
>>> sp4 = note.Rest()
>>> sp4.style.hideObjectOnPrint = True
>>> sp4.duration.quarterLength = 16.0
>>> v4.replacementDuration = 4.0
>>> v4.append(sp4)
>>> for el in s4:
...     v4.append(el)

>>> variantList = [v4, v1, v3, v2]
>>> for v in variantList :
...     v.groups = ['london']
...     activeSite.insert(0.0, v)


>>> lpc = lily.translate.LilypondConverter()

>>> print(lpc.lyPrefixCompositeMusicFromRelatedVariants(variantList,
...                activeSite=activeSite)[0])
\new Staff  = london... { { \times 1/2 {\startStaff \clef "treble"
      a' 4
      a' 4
      a' 4
      a' 4
      \clef "treble"
      | %{ end measure 1 %}
      a' 1
      | %{ end measure 2 %}
       \stopStaff}
       }
<BLANKLINE>
  {\startStaff \clef "treble"
    b... 4
    b... 4
    b... 4
    b... 4
    | %{ end measure 1 %}
     \stopStaff}
<BLANKLINE>
  {\startStaff \clef "treble"
    c' 4
    c' 4
    c' 4
    c' 4
    | %{ end measure 1 %}
     \stopStaff}
<BLANKLINE>
  s 1
  {\startStaff \clef "treble"
    d' 4
    d' 4
    d' 4
    d' 4
    | %{ end measure 1 %}
     \stopStaff}
<BLANKLINE>
   }
<BLANKLINE>

c                    U  HP  n[        U[        R                  5      (       a  UR                  R                  (       a  M?  U R                  U5      s  $    g r!   )r#  r   r  r  r  elementOffset)inputStreamr)  s     r   !findOffsetOfFirstNonSpacerElementfLilypondConverter.lyPrefixCompositeMusicFromRelatedVariants.<locals>.findOffsetOfFirstNonSpacerElement  s=    !b$)),,1K1K&44R88	 "r   c                (   > T" U R                   5      $ r!   )_stream)vvrl  s    r   <lambda>MLilypondConverter.lyPrefixCompositeMusicFromRelatedVariants.<locals>.<lambda>  s    (I"**(Ur   r   r   Nr   r"  FT   z%Should not have overlapping variants.)	offsetEndrQ  rR  rS  r<  )includeSpacersr  rb   r  r  )*sortr[  r   getContextByClassr  r   r   r   r  rf   r   r1   r  r^   r  rg   indexri   ro  r   replacementDurationr   r  r  r  r
   r$  r  r   notesAndRestsr  containedHighestTimer   r   getElementsByOffsetr   decimalToTupletr*   lyOssiaMusicFromVariantr  rE  r
  )%rn   r{  rr  rh   r[  re0replacedElementsClefvariantContainerStreamr  
newVariantcontainerIdr  r  r  highestOffsetSoFarlongestVariantr  firstOffsetr  spacerlySpacern	endOffset	vStrippedreplacedElementsLengthvariantLengthrM  rN  rT  lpOssiaMusicVariantPreFractionlpVariantTupletlpOssiaMusicVariantr  lpInternalSequentialMusicrl  r  rl  s%                                       @r   r^  ;LilypondConverter.lyPrefixCompositeMusicFromRelatedVariantsE  s   R	9 	UV 'q>:::Fq!"xxK3+@+@+K!,Q!A!A&++!N!)%0^%E%Eh%O"Ac#78!!n++A.,,,J%%k2J'(>(A(AB$$%6{%Ck%QR	d"&&t'9'9'?'?'Lq'PQEE 	 A <AIIFK//,-TUU(+==N!"!6!6!D #15.0>-;;FC  *$&**,::A$)AGGM ; ..I		(E(EkPY )F )[ \I,-,A,AI)%.%B%B"%::[HM 66)/)?)?*]:*<&	;y>C/#k2BB151M1Mi1X."%"<"<'FNCa#c '*&;&;o&V#&*&B&B9&M#01Ni t *:::VZ:[ooi0$'$9$9K$P!&0Ui(+(B(B#  +	)-% !,.>>>r   c                   US   R                  [        R                  5      nUR                  [        R                  5      nUc  UR                  S5      nUb!  XAR
                  ;  a  UR                  SU5        UR                  (       a  UR                  S   nOSnX`R                  ;   a  SnOU R                  R                  U5        Sn[        UR                  5      n[        R                  " [        U5      U-   5      n	USL af  U R                  U R                  R                  U5      S-     n
UR                   R#                  5       R$                   H  nXR&                  l        M     / nUR+                  [,        R.                  5       Vs/ s H"  nUR&                  R0                  (       d  M   UPM$     nnU(       ai  US   nUR2                  R4                  nUR2                  R4                  S:  a"  U R7                  U5      nUR                  U5        UR9                  U5        OSnU R;                  U5      nUR<                  nUR>                  U-
  nSU l         UU:w  ar  [B        RD                  " UU-  5      u  nn[G        U5      S-   [G        U5      -   n[        RH                  " S	UUS
9n[        RJ                  " US9nUR                  U5        OUR                  U5        [        RL                  " U5      n[        RJ                  " US9nUSL a  [        RH                  " SU	SUS9nO[        RH                  " SU	SUS9nSU l         U$ s  snf )a}  

>>> pStream = converter.parse('tinynotation: 4/4 a4 b c d   e4 f g a')
>>> pStream.makeMeasures(inPlace=True)
>>> p = stream.Part(pStream.elements)
>>> p.id = 'p1'
>>> vStream = converter.parse('tinynotation: 4/4 a4. b8 c4 d')
>>> vStream.makeMeasures(inPlace=True)
>>> v = variant.Variant(vStream.elements)
>>> v.groups = ['london']
>>> p.insert(0.0, v)
>>> lpc = lily.translate.LilypondConverter()
>>> replacedElements = v.replacedElements()
>>> lpPrefixCompositeMusicVariant = lpc.lyPrefixCompositeMusicFromVariant(v,
...                                                            replacedElements)
>>> print(lpPrefixCompositeMusicVariant)  # ellipses are for non-byte fix-ups
\new Staff  = londonpx { {\startStaff \clef "treble"
    a' 4.
    b...
    c' 4
    d' 4
    | %{ end measure 1 %}
     \stopStaff}
   }

>>> replacedElements.show('text')
{0.0} <music21.stream.Measure 1 offset=0.0>
    {0.0} <music21.clef.TrebleClef>
    {0.0} <music21.meter.TimeSignature 4/4>
    {0.0} <music21.note.Note A>
    {1.0} <music21.note.Note B>
    {2.0} <music21.note.Note C>
    {3.0} <music21.note.Note D>

>>> print(lpc.addedVariants)
['london']

r   r   r   FTrs  r"  rQ  rR  rS  r<  r  r  r  rb   )'rw  r   r  r   r   elementsr   r  rf   r   r1   r  r^   r  rg   rx  ro  r   rz  r  r  r  r   r  r  r
   r$  r  remover~  ry  r{  ri   r   r}  r*   r  rE  r
  )rn   ra  r[  rh   r  r  r  r  r  r  r  r  r  r	varFilterr  	spacerDurr  r  r  r  rM  rN  rT  r  r  r  lpOssiaMusicVariantWithSpacerr  s                                r   r\  3LilypondConverter.lyPrefixCompositeMusicFromVariant"  s   V  02DDTYYO!.!@!@!M!)%2%D%DX%N"+#+A+AA$$Q(<='..q1K#K,,,J%%k2J'(>(A(AB$$%6{%Ck%QR	d"&&t'9'9'?'?'Lq'PQE"**224BB % C 	 - @ @ K 3 K111  K	 3 q\F55I,,s2;;FC  *  (I"::=I!.!B!B%::YF22%+%;%;<RUb<b%c"I{9~+c+.>>H!88gBJ?RTO ),(=(=(X%6701ooi0(+(=(=(T%,/,F,F$$3	-5) -0,F,F$$3	-5)* !,,3s   M4Mc                6   / n[         R                  " US9n[         R                  " US9nU R                  U5        SU l        U R                  UR                  5        U R                  5       nUb  UR                  U5        U R                  5         SU l        U$ )a  
returns a LyOssiaMusic object from a stream


>>> c = converter.parse('tinynotation: 3/4 C4 D E F2.')
>>> v = variant.Variant(c.elements)
>>> lpc = lily.translate.LilypondConverter()
>>> lySequentialMusicOut = lpc.lySequentialMusicFromStream(v)
>>> lySequentialMusicOut
<music21.lily.lilyObjects.LySequentialMusic { \clef "b...>
>>> print(lySequentialMusicOut)
{ \clef "bass"
 \time 3/4
 c 4
 d 4
 e 4
 \bar "|"  %{ end measure 1 %}
 f 2.
 \bar "|."  %{ end measure 2 %}
  }
<BLANKLINE>
r_  r<  TF)
r^   r
  LyOssiaMusicr   ri   r`  ro  ra  r   r   )rn   	variantInr  r  lpOssiaMusicrb  s         r   r~  )LilypondConverter.lyOssiaMusicFromVariant  s    . 	ooy9''+>$--i.?.?@$$&X& r   c                :   Uc  [         R                  " 5       nUR                  c  [         R                  " 5       nX2l        OUR                  nUR                  nUb  UR
                  nU(       aI  [         R                  " S[         R                  " US9S9nUR                  U5        UR                  U5        UR                  nU(       aI  [         R                  " S[         R                  " US9S9nUR                  U5        UR                  U5        XCl        U$ )an  
Returns a lilypond.lilyObjects.LyLilypondHeader object
set with data from the metadata object

>>> md = metadata.Metadata()
>>> md.title = 'My Title'
>>> md.alternativeTitle = 'My "sub"-title'

>>> lpc = lily.translate.LilypondConverter()
>>> lpHeader = lpc.setHeaderFromMetadata(md)
>>> print(lpHeader)
\header { title = "My Title"
subtitle = "My \"sub\"-title"
}
title)string)assignmentIdidentifierInitsubtitle)r^   r   lilypondHeaderBodyLyLilypondHeaderBodyassignments	bestTitleLyAssignmentLyIdentifierInitr   rw  alternativeTitle)	rn   metadataObjectr   lpHeaderBodylpHeaderBodyAssignmentsr  lyTitleAssignmentr  lySubtitleAssignments	            r   r   'LilypondConverter.setHeaderFromMetadata  s   $ ++-H&&.335L*6'#66L".":":%",,E$'$4$4'DGDXDX@EEG%7! (../@A!++L9%66H'*'7'7ZGJG[G[CKHM(:$ (../CD$..|<#: r   c                   U R                   nSU l         Uc  gU R                  SL a  Sn[        R                  " 5       nUSL a  SnOqUR                  c"  UR
                  S-   UR                  S5      -   nOBUR
                  S-   UR                  U R                  UR                  R                     5      -   nUR                  b   XCR                  SUR                   35      -  nXCl        U$ )a]  
return a LyObject or None for the end of the previous Measure

uses self.currentMeasure

>>> lpc = lily.translate.LilypondConverter()
>>> m = stream.Measure()
>>> m.number = 2
>>> m.rightBarline = 'double'
>>> lpc.currentMeasure = m
>>> lyObj = lpc.closeMeasure()
>>> lpc.currentMeasure is None
True
>>> print(lyObj)
\bar "||"  %{ end measure 2 %}
NTr?   zbar zend measure )re   ri   r^   r   rightBarliner   r   barlineDictr  numbercommentr0  )rn   barChecksOnlyr?  	lpBarline	barStrings        r   ra  LilypondConverter.closeMeasure	  s    $ "9 t# M%%'	D I^^#!++f4y7L7LS7QQI!++f4y7L7L  !4!4587 7I 88**\!((+DEEI%r   c                N   UR                   nUS:X  a  gUR                  5       nU(       d  SnOUS   nUR                  R                  nXB-
  nUS::  a  [	        S5      e[        US-  5      n[        R                  " 5       nUR                  S-   [        U5      -   S-   n	Xl
        U$ )a;  
lilypond partial durations are very strange and are really of
type LyMultipliedDuration.  You notate how many
notes are left in the measure, for a quarter note, write "4"
for an eighth, write "8", but for 3 eighths, write "8*3" !
so we will measure in 32nd notes always. It won't work for tuplets
of course.

Returns a scheme object or None if not needed.

>>> m = stream.Measure()
>>> m.append(meter.TimeSignature('3/4'))
>>> m.paddingLeft = 2.0
>>> lpc = lily.translate.LilypondConverter()
>>> outScheme = lpc.getSchemeForPadding(m)
>>> print(outScheme)
\partial 32*8
r   Ng      @z*your first pickup measure is non-existent!   zpartial 32*r  )paddingLeftgetTimeSignaturesbarDurationr$  r   r   r^   r   r   r*   r0  )
rn   measureObjectpLmeasureTimeSignatures	barLengthrE  remainingQLremaining32srb  	schemeStrs
             r   r  %LilypondConverter.getSchemeForPaddingG	  s    & &&7 - ? ? A$I&q)B44In!()UVV;?+$$&&&6\9JJSP	$r   c                H   [        U R                  5      nUc  [        R                  USS9n[        R
                  " U5      U l        U R                  R                  SSS9 nUR                  U5        SSS5        U R                  $ ! , (       d  f       U R                  $ = f)z
writes the contents of the self.topLevelObject to a file.

The extension should be ly.  If fp is None then a named temporary
file is created by environment.getTempFile.

NF)returnPathlibwr   r   )	r*   r`   rv   getTempFilepathlibPathrk   openwrite)rn   extfptloOutfs        r   writeLyFileLilypondConverter.writeLyFilem	  s     T(():))#U)CBR(]]g6!GGFO 7 }} 76 }}s   "B
B!c                (   U R                  5       nUc  U R                  SS9nOUSL a  U R                  SUS9nSU-   S-   nUb  USU-   S-   -  nUb  X`R                  U-   S-   -  nUS	[        U5      -   S-   [        U5      -   -  n[        R
                  " U5         [        R                  " [        U5      S
-   5        [        U5      S-   U-   n[        R                  R                  U5      (       dz  [        R                  R                  U5      n[        R                  R                  U5      (       d5  [        S[        U5      -   S-   [        U5      -   S-   [        U5      -   5      eUn[        R                  " U5      $ ! [         a     Nf = f)a   
creates a .ly file from self.topLevelObject via .writeLyFile
then runs the file through Lilypond.

Returns the full path of the file produced by lilypond including the format extension.

If skipWriting is True and a fileName is given then it will run
that file through lilypond instead

ly)r  F)r  r  r	  z" z-f r  z-o z.epsrB   zcannot find z or the full path z original file was )r}   r  r]   r*   ry   systemr  r   rz   rw   basenamer   r  r  )	rn   formatrZ   fileNameskipWritingrj   lilyCommandfileFormfileEnds	            r   runThroughLily LilypondConverter.runThroughLily	  s    $$&''D'1He#+++BHnt+56>C//K--7#==Kus8},s2S]BB
		+	IIc(mf,- x=3&/ww~~h''gg&&x0G77>>'**,^c'l-J/C.DFI(m.T/D.EGJ8}.U V V H||H%%  		s   "F 
FFc                J    SU R                   l        U R                  SSUS9nU$ )z
create a PDF file from self.topLevelObject and return the filepath of the file.

most users will just call stream.write('lily.pdf') on a stream.
r'   rN   pdfrZ   r  r  r\   r0  r  rn   r  lilyFiles      r   	createPDFLilypondConverter.createPDF	  s.     %'!&&tEH&Ur   c                8   U R                  5       nUR                  5       (       d  [        S5      e[        R                  S:X  a  S[        U5       S[        U5       3nO%[        R                  S:X  a  S[        U5       3nOSn[        R                  " U5        g)	z
create an SVG file from self.topLevelObject, show it with your pdf reader
(often Adobe Acrobat/Adobe Reader or Apple Preview)
and return the filepath of the file.

most users will just call stream.Stream.show('lily.pdf') on a stream.
z&Something went wrong with PDF Creationntzstart /wait z && del /f rs   zopen r'   N)	r  rw   RuntimeErrorry   r	  r*   sysr|   r  )rn   lFr   s      r   showPDFLilypondConverter.showPDF	  sy     ^^yy{{GHH77d?$SWI[R	BG\\X%c"gY'GG
		'r   c                    U R                  SSUS9n[        SL aR  SSKJnJn   UR                  [        U5      5      nUR                  USS5      nUR                  [        U5      5        U$ U$ ! [         a     U$ f = f)	z
create a PNG file from self.topLevelObject and return the filepath of the file.

most users will just call stream.write('lily.png') on a stream.

if PIL is installed then a small white border is created around the score
epspngr  Fr   )ImageImageOps
   white)
r  noPILPILr  r  r  r*   expandsave	Exception)rn   r  r  r  r  	lilyImage
lilyImage2s          r   	createPNGLilypondConverter.createPNG	  s     &&uUX&VE>+!JJs8}5	%__YGD
H. x  s   AA/ /
A=<A=c                     U R                  5       n[        5       R	                  USS9$ ! [         a  n[        S[        U5      -   S-   5      eSnAff = f)z
Take the object, run it through LilyPond, and then show it as a PNG file.
On Windows, the PNG file will not be deleted, so you  will need to clean out
TEMP every once in a while.

Most users will just want to call stream.Stream.show('lily.png') instead.
zProblems creating PNG file: ()Nr  fmt)r   r   r*   r   launch)rn   r  es      r   showPNGLilypondConverter.showPNG	  s]    	Y~~'H ~$$X5$99 & 	Y()H3q6)QTW)WXX	Ys   * 
AAAc                J    SU R                   l        U R                  SSUS9nU$ )z
create an SVG file from self.topLevelObject and return the filepath of the file.

most users will just call stream.Stream.write('lily.svg') on a stream.
r'   svg)r  rZ   r  r  r  s      r   	createSVGLilypondConverter.createSVG	  s.     %'!&&eUX&Vr   c                T    U R                  U5      n[        5       R                  USS9$ )z
create an SVG file from self.topLevelObject, show it with your
svg reader (often Internet Explorer on PC)
and return the filepath of the file.

most users will just call stream.Stream.show('lily.png') on a stream.
r  r  )r  r   r  r  s      r   showSVGLilypondConverter.showSVG	  s*     >>(+~$$X5$99r   )rj   rf   rZ   r]   rh   rb   re   rd   r\   rl   rW   rX   rc   rk   r`   rg   ri   r[   rY   )NT)Tr!   )NalignBelowContext)NNN)r  z*duration.Duration | duration.DurationTuple)NF)F)NN)r'   N)NNNF)Ar   r   r   r   lstripfictaDefr   simplePaperDefinitionScmr  r  r   r
  r  ro   r}   ra   r   r   r   r   r   r   r   r   r  r   rR  rD  rc  r   r`  ru  r  r  r  r  r  r  r  r  r   r  r%  r  r  r  r  rK  r  rv  r^  r\  r~  r   ra  r  r  r  r  r  r   r  r  r  r   r   r   r   r3   r3   ]   s   	 
	 	   	 	 
 	 
   *0(.1706"&!%'+&* " %! "&"'#'!%K .0%.R"/:!CH))V!)H8KZ/b["z2h6p"!P R&hc:JW.rA1F2,hTl<9|56/d,	
E"=E"N-^$L"44l	@4H >BBG[?@ ;@H-t(T1f,\#L( %)@E)&V(*:	:r   r3   c                      \ rS rSrSrg)r   i
  r   N)r   r   r   r   r   r   r   r   r   r   
  s    r   r   c                  .    \ rS rSr S rS rS rS rSrg)Testi
  c                N    [        5       n[        S5      nUR                  USS9  g )Nbach/bwv66.6Fr   )r3   r%   r   )rn   lpcr  s      r   testExplicitConvertChoraleTest.testExplicitConvertChorale
  s'    ! 06r   c                   SSK Jn  [        R                  " 5       n[        R
                  " S5      nSUR                  l        U R                  UR                  R                  S5        [        R
                  " S5      nSUR                  l        UR                  UR                  S5      5        UR                  U5        UR                  U5        [        5       nUR                  U5        g )	Nr   meterCg      @r  D4g      ?z4/4)music21r  r   r   r   r  r
   r$  assertEqualr  r   r  r3   r   )rn   r  r   n1n2r  s         r   testComplexDurationTest.testComplexDuration
  s    !MMOYYs^$'!))95YYt_$'!	$$U+,		!"r   c                f    [         R                  " S5      n[        5       nUR                  U5        g )Nz theoryExercises/checker_demo.xml)r	   r#   r3   r   )rn   r   r  s      r   testCompositeLyricsTest.testCompositeLyrics#
  s'    LL;<!"r   c                   [         R                  " 5       nSUR                  l        [	        5       R                  U5      nU R                  UR                  5       S5        [         R                  " 5       nSUR                  l        [	        5       R                  U5      nU R                  UR                  5       S5        g )Nz#FF0000zL\override NoteHead.color = "#FF0000"
\override Stem.color = "#FF0000"
c' 4  	darkgreenzP\override NoteHead.color = "darkgreen"
\override Stem.color = "darkgreen"
c' 4  )r   r  r  r  r3   r  r#  stringOutput)rn   red_notesmdark_green_notes       r   
testColorsTest.testColors)
  s    99;( <<XFOO	
 ))+&1# <<_MOO	
r   r   N)	r   r   r   r   r  r&  r)  r1  r   r   r   r   r  r  
  s    7#$#
r   r  c                  6    \ rS rSrSrS rS rS rS rS r	Sr
g	)
TestExternali?
  Tc                v    [         R                  " S5      nU R                  (       a  UR                  S5        g g )NC5lily.png)r   r  show)rn   r  s     r   xtestConvertNoteTestExternal.xtestConvertNoteB
  s'    IIdO99FF: r   c                    [        S5      nUR                  5        H
  nS Ul        M     U R                  (       a  UR                  S   R                  S5        g g )Nr  r   zlily.svg)r%   flattenrj  r8  r   )rn   r  r  s      r   xtestConvertChorale TestExternal.xtestConvertChoraleG
  sC     0AAG 99GGAJOOJ' r   c                v    [         R                  " S5      nU R                  (       a  UR                  S5        g g )NzmiscFolk/americanfifeopus.abcr7  )r	   r#   r8  )rn   fifeOpuss     r   xtestSlowConvertOpus!TestExternal.xtestSlowConvertOpusN
  s)    << ?@99MM*% r   c                   SSK Jn  [        R                  " S5      nSUR                  l        [        R                  " 5       nUR                  UR                  S5      5        UR                  U5        [        R                  " 5       nUR                  U5        [        R                  " 5       nUR                  U5        U R                  (       a  UR                  S5        g g )Nr   r  r6  g       @z8/4r7  )r"  r  r   r  r
   r$  r   r   r   r  r   r   r8  )rn   r  r  r?  r  r   s         r   
xtestBreveTestExternal.xtestBreveS
  s    !IIdO#&

 NN	$$U+,	KKM	LLN	99FF: r   c                   [         R                  " 5       n[         R                  " 5       nUR                  [        R
                  " SSS95        SUl        UR                  SU5        [         R                  " 5       nUR                  [        R
                  " SSS95        SUl        UR                  SU5        U R                  (       a  UR                  S5        g g )NB4whole)r  r   r      r7  )	r   r   r   r   r   r  rf  r   r8  )rn   r   r  p2s       r   testStaffLinesTestExternal.testStaffLinesa
  s    LLNKKM	4g./	A[[]
		$))Dw/0	B99FF: r   r   N)r   r   r   r   r8  r9  r=  rA  rD  rK  r   r   r   r   r4  r4  ?
  s     D
(&
r   r4  __main__)-__doc__
__future__r   collectionsr   importlib.utilr   ry   r  r   r   r  unittestr"  r   r   music21.converter.subConvertersr   r	   r
   r   r   r   r   r   r   music21.lilyr   r^   Environmentrv   r  ModuleNotFoundErrorr   r"   r%   r1   r3   Music21Exceptionr   TestCaser  r4  r   mainTestr   r   r   <module>rZ     s"  
 # # $ 	  	  
    8          +&&'78)N";"; / / ,- 2,d&: d&:NM	\:: 	5
8 5
n-8$$ -b zT AR  Es   D' %D' 'D21D2