
    <`                       d dl mZmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlZdZg dZd	 Z eg d
          Zd Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d  d!e          Z G d" d#e          Z G d$ d%e          Z G d& d'e          Z  G d( d)e          Z! G d* d+e          Z" G d, d-e          Z# G d. d/e          Z$ G d0 d1e          Z% G d2 d3e          Z& G d4 d5e          Z' G d6 d7e          Z( G d8 d9e          Z) G d: d;e          Z* G d< d=e          Z+ G d> d?e          Z, G d@ dAe          Z- G dB dCe          Z. G dD dEe          Z/ G dF dGe          Z0 G dH dIe          Z1 G dJ dKe          Z2 G dL dMe          Z3 G dN dOe          Z4 G dP dQe          Z5 G dR dSe          Z6 G dT dUe          Z7 G dV dWe          Z8 G dX dYe          Z9 G dZ d[e          Z: G d\ d]e          Z; G d^ d_e          Z< G d` dae          Z= G db dce          Z> G dd dee          Z? G df dge          Z@ G dh die          ZA G dj dke          ZB G dl dme          ZC G dn doe          ZD G dp dqe          ZEdr ZF G ds dte          ZG G du dveG          ZH G dw dxeG          ZI G dy dze          ZJ G d{ d|eG          ZK G d} d~e          ZL G d de          ZM G d de          ZN G d de          ZO G d de          ZP G d de          ZQ G d de          ZR G d de          ZS G d de          ZT G d de          ZUdS )    )byteordtobytes)FeatureLibError)FeatureLibLocation)getEncoding)OrderedDictNz    )AElementFeatureFileComment	GlyphName
GlyphClassGlyphClassNameMarkClassNameAnonymousBlockBlockFeatureBlockNestedBlockLookupBlockGlyphClassDefinitionGlyphClassDefStatement	MarkClassMarkClassDefinitionAlternateSubstStatementAnchorAnchorDefinitionAttachStatementAxisValueLocationStatementBaseAxisCVParametersNameStatementChainContextPosStatementChainContextSubstStatementCharacterStatementCursivePosStatementElidedFallbackNameElidedFallbackNameID
ExpressionFeatureNameStatementFeatureReferenceStatementFontRevisionStatement	HheaFieldIgnorePosStatementIgnoreSubstStatementIncludeStatementLanguageStatementLanguageSystemStatementLigatureCaretByIndexStatementLigatureCaretByPosStatementLigatureSubstStatementLookupFlagStatementLookupReferenceStatementMarkBasePosStatementMarkLigPosStatementMarkMarkPosStatementMultipleSubstStatement
NameRecordOS2FieldPairPosStatement ReverseChainSingleSubstStatementScriptStatementSinglePosStatementSingleSubstStatementSizeParameters	StatementSTATAxisValueStatementSTATDesignAxisStatementSTATNameStatementSubtableStatement
TableBlockValueRecordValueRecordDefinition	VheaFieldc                 N    | dS dd                     d | D                       z  S )Nz<device NULL>z<device %s>, c              3       K   | ]	}d |z  V  
dS )z%d %dN ).0ts     4lib/python3.11/site-packages/fontTools/feaLib/ast.py	<genexpr>z!deviceToString.<locals>.<genexpr>S   s&      (E(E1(E(E(E(E(E(E    )join)devices    rP   deviceToStringrU   O   s2    ~tyy(E(Ef(E(E(EEEEErR   )4anchor	anchordefanon	anonymousbycontourcursiverT   enum	enumerateexcludedfltexclude_dfltfeaturefromignoreignorebaseglyphsignoreligaturesignoremarksincludeincludedfltinclude_dfltlanguagelanguagesystemlookup
lookupflagmarkmarkattachmenttype	markclassnameidnull
parameterspospositionrequiredrighttoleft
reversesubrsubscriptsub
substitutesubtabletableusemarkfilteringsetuseextensionvaluerecorddefbasegdefheadhheanamevheavmtxc                 :   t          | d          r|                                 S t          | t                    rAt	          |           dk    r.t          | d                   dz   t          | d                   z   S |                                 t          v rd| z   S | S )NasFea   r   z -    \)hasattrr   
isinstancetuplelenlowerfea_keywords)gs    rP   r   r      s    q' wwyy	Au		 #a&&A++QqT{{U"U1Q4[[00	
l	"	"axrR   c                   .    e Zd ZdZddZd Zd	dZd ZdS )
r	   z8A base class representing "something" in a feature file.Nc                 T    |rt          |t                    s	t          | }|| _        d S N)r   r   locationselfr   s     rP   __init__zElement.__init__   s1     	5Jx1CDD 	5)84H rR   c                     d S r   rM   r   builders     rP   buildzElement.build   s    rR    c                     t           )zReturns this element as a string of feature code. For block-type
        elements (such as :class:`FeatureBlock`), the `indent` string is
        added to the start of each line in the output.)NotImplementedErrorr   indents     rP   r   zElement.asFea   s
     "!rR   c                 *    |                                  S r   r   r   s    rP   __str__zElement.__str__   s    zz||rR   r   r   )__name__
__module____qualname____doc__r   r   r   r   rM   rR   rP   r	   r	      s`        BB! ! ! !  " " " "    rR   r	   c                       e Zd ZdS )rA   Nr   r   r   rM   rR   rP   rA   rA              DrR   rA   c                       e Zd ZdS )r&   Nr   rM   rR   rP   r&   r&      r   rR   r&   c                   ,     e Zd ZdZd fd	ZddZ xZS )r   zA comment in a feature file.Nc                 f    t          t          |                               |           || _        d S r   )superr   r   text)r   r   r   	__class__s      rP   r   zComment.__init__   s,    gt%%h///			rR   r   c                     | j         S r   )r   r   s     rP   r   zComment.asFea   s
    yrR   r   r   r   r   r   r   r   r   __classcell__r   s   @rP   r   r      sW        &&     
       rR   r   c                   (    e Zd ZdZddZd ZddZdS )		NullGlyphz5The NULL glyph, used in glyph deletion substitutions.Nc                 <    t                               | |           d S r   )r&   r   r   s     rP   r   zNullGlyph.__init__   s    D(+++++rR   c                     dS )BThe glyphs in this class as a tuple of :class:`GlyphName` objects.rM   rM   r   s    rP   glyphSetzNullGlyph.glyphSet   s    rrR   r   c                     dS )NNULLrM   r   s     rP   r   zNullGlyph.asFea   s    vrR   r   r   r   r   r   r   r   r   r   rM   rR   rP   r   r      sQ        ??, , , ,       rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   z)A single glyph name, such as ``cedilla``.Nc                 J    t                               | |           || _        d S r   )r&   r   glyph)r   r   r   s      rP   r   zGlyphName.__init__   s#    D(+++


rR   c                     | j         fS r   )r   r   s    rP   r   zGlyphName.glyphSet   s    
}rR   r   c                 *    t          | j                  S r   )r   r   r   s     rP   r   zGlyphName.asFea   s    TZ   rR   r   r   r   rM   rR   rP   r   r      sQ        33   
  ! ! ! ! ! !rR   r   c                   F    e Zd ZdZddZd ZddZd Zd Zd	 Z	d
 Z
d ZdS )r   z1A glyph class, such as ``[acute cedilla grave]``.Nc                 n    t                               | |           ||ng | _        g | _        d| _        d S )Nr   )r&   r   glyphsoriginalcurr)r   r   r   s      rP   r   zGlyphClass.__init__   s:    D(+++ & 2ff			rR   c                 *    t          | j                  S r   )r   r   r   s    rP   r   zGlyphClass.glyphSet   s    T[!!!rR   r   c                    t          | j                  r| j        t          | j                  k     rE| j                            | j        | j        d                     t          | j                  | _        dd                    t          t          | j                            z   dz   S dd                    t          t          | j                            z   dz   S )N[ ])r   r   r   r   extendrS   mapr   r   s     rP   r   zGlyphClass.asFea   s    t} 	Ay3t{++++$$T[%=>>>,,	#eT]";";<<<sBB#eT["9"9:::S@@rR   c                 :    | j                             |           dS )z6Add a list of :class:`GlyphName` objects to the class.N)r   r   )r   r   s     rP   r   zGlyphClass.extend   s    6"""""rR   c                 :    | j                             |           dS )z4Add a single :class:`GlyphName` object to the class.N)r   append)r   r   s     rP   r   zGlyphClass.append   s    5!!!!!rR   c                 6   | j         t          | j                  k     r,| j                            | j        | j         d                    | j                            ||f           | j                            |           t          | j                  | _         dS )a  Add a range (e.g. ``A-Z``) to the class. ``start`` and ``end``
        are either :class:`GlyphName` objects or strings representing the
        start and end glyphs in the class, and ``glyphs`` is the full list of
        :class:`GlyphName` objects in the range.N)r   r   r   r   r   r   r   startendr   s       rP   	add_rangezGlyphClass.add_range  s    
 9s4;''''M  TY[[!9:::eS\***6"""$$			rR   c                    | j         t          | j                  k     r,| j                            | j        | j         d                    | j                            d                    |          d                    |          f           | j                            |           t          | j                  | _         dS )zAdd a range to the class by glyph ID. ``start`` and ``end`` are the
        initial and final IDs, and ``glyphs`` is the full list of
        :class:`GlyphName` objects in the range.Nz\{})r   r   r   r   r   r   formatr   s       rP   add_cid_rangezGlyphClass.add_cid_range  s     9s4;''''M  TY[[!9:::fmmE22FMM#4F4FGHHH6"""$$			rR   c                 V   | j         t          | j                  k     r,| j                            | j        | j         d                    | j                            |           | j                            |                                           t          | j                  | _         dS )zNAdd glyphs from the given :class:`GlyphClassName` object to the
        class.N)r   r   r   r   r   r   r   )r   gcs     rP   	add_classzGlyphClass.add_class  s     9s4;''''M  TY[[!9:::R   2;;==)))$$			rR   NNr   )r   r   r   r   r   r   r   r   r   r   r   r   rM   rR   rP   r   r      s        ;;   " " "A A A A# # #" " "	% 	% 	%% % %% % % % %rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   zyA glyph class name, such as ``@FRENCH_MARKS``. This must be instantiated
    with a :class:`GlyphClassDefinition` object.Nc                 x    t                               | |           t          |t                    sJ || _        d S r   )r&   r   r   r   
glyphclass)r   r   r   s      rP   r   zGlyphClassName.__init__&  s:    D(+++*&:;;;;;$rR   c                 N    t          | j                                                  S r   )r   r   r   r   s    rP   r   zGlyphClassName.glyphSet+  s    T_--//000rR   r   c                      d| j         j        z   S N@)r   r   r   s     rP   r   zGlyphClassName.asFea/  s    T_)))rR   r   r   r   rM   rR   rP   r   r   "  sU        4 4% % % %
1 1 1* * * * * *rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   zA mark class name, such as ``@FRENCH_MARKS`` defined with ``markClass``.
    This must be instantiated with a :class:`MarkClass` object.Nc                 x    t                               | |           t          |t                    sJ || _        d S r   )r&   r   r   r   	markClass)r   r   r   s      rP   r   zMarkClassName.__init__7  s9    D(+++)Y/////"rR   c                 4    | j                                         S r   )r   r   r   s    rP   r   zMarkClassName.glyphSet<  s    ~&&(((rR   r   c                      d| j         j        z   S r   )r   r   r   s     rP   r   zMarkClassName.asFea@  s    T^(((rR   r   r   r   rM   rR   rP   r   r   3  sW        C C# # # #
) ) )) ) ) ) ) )rR   r   c                   "    e Zd ZdZddZddZdS )r   zAn anonymous data block.Nc                 X    t                               | |           || _        || _        d S r   )rA   r   tagcontent)r   r   r   r   s       rP   r   zAnonymousBlock.__init__G  s*    4***rR   r   c                     d                     | j                  }|| j        z  }|d                     | j                  z  }|S )Nzanon {} {{
z}} {};

)r   r   r   r   r   ress      rP   r   zAnonymousBlock.asFeaL  sB    ##DH--t||""48,,,
rR   r   r   r   r   r   r   r   r   rM   rR   rP   r   r   D  sB        ""   
     rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   z,A block of statements: feature, lookup, etc.Nc                 J    t                               | |           g | _        d S r   )rA   r   
statementsr   s     rP   r   zBlock.__init__V  s#    4***rR   c                 D    | j         D ]}|                    |           dS )zWhen handed a 'builder' object of comparable interface to
        :class:`fontTools.feaLib.builder`, walks the statements in this
        block, calling the builder callbacks.N)r   r   )r   r   ss      rP   r   zBlock.buildZ  s4      	 	AGGG	 	rR   r   c                 v    t           z  dz                       fd| j        D                       z   dz   S )N
c                 <    g | ]}|                                S r   r   rN   r   r   s     rP   
<listcomp>zBlock.asFea.<locals>.<listcomp>e  s'    #T#T#TqAGG6G$:$:#T#T#TrR   )SHIFTrS   r   r   s    `rP   r   zBlock.asFeaa  sN    %f}""#T#T#T#TDO#T#T#TUUV	
rR   r   r   r   r   r   r   r   r   r   rM   rR   rP   r   r   S  sQ        66     
 
 
 
 
 
rR   r   c                        e Zd ZdZd ZddZdS )r
   zpThe top-level element of the syntax tree, containing the whole feature
    file in its ``statements`` attribute.c                 L    t                               | d            i | _        d S N)r   )r   r   markClassesr   s    rP   r   zFeatureFile.__init__n  s&    td+++rR   r   c                 P    d                     fd| j        D                       S )Nr   c              3   D   K   | ]}|                                V  dS )r  Nr   r  s     rP   rQ   z$FeatureFile.asFea.<locals>.<genexpr>s  s1      IIA//IIIIIIrR   )rS   r   r   s    `rP   r   zFeatureFile.asFear  s,    yyIIIIIIIIIIrR   Nr   r   rM   rR   rP   r
   r
   j  sG        - -  J J J J J JrR   r
   c                   (    e Zd ZdZddZd Zd	dZdS )
r   zA named feature block.FNc                 Z    t                               | |           ||c| _        | _        d S r   r   r   r   use_extensionr   r   r  r   s       rP   r   zFeatureBlock.__init__y  -    tX&&&(,m%	4%%%rR   c                 ^   |                     | j        | j                   |j        }i |_        t                              | |           |j                                        D ].\  }}|                    |g                               |           /||_        |	                                 dS )zCall the ``start_feature`` callback on the builder object, visit
        all the statements in this feature, and then call ``end_feature``.N)
start_featurer   r   	features_r   r   items
setdefaultr   end_feature)r   r   featureskeyvalues        rP   r   zFeatureBlock.build}  s     	dmTY777 $D'"""!+1133 	7 	7JCR((//6666$rR   r   c                     |d| j                                         z  z   }| j        r|dz  }|dz  }|t                              | |          z  }||d| j                                         z  z   z  }|S )Nzfeature %s useExtension {
r  z} %s;
)r   stripr  r   r   r   s      rP   r   zFeatureBlock.asFea  sz    }ty'8'888 	#?"Cuu{{4{///v	DIOO$5$5555
rR   FNr   r  rM   rR   rP   r   r   v  sQ          < < < <       rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   zYA block inside another block, for example when found inside a
    ``cvParameters`` block.Nc                 X    t                               | |           || _        || _        d S r   )r   r   r   
block_name)r   r   r#  r   s       rP   r   zNestedBlock.__init__  s(    tX&&&$rR   c                     t                               | |           | j        dk    r|                    | j                   d S d S )NParamUILabelNameID)r   r   r#  add_to_cv_num_named_paramsr   r   s     rP   r   zNestedBlock.build  sH    D'"""?222..tx88888 32rR   r   c                     d                     || j                  }|t                              | |          z  }|d                     |          z  }|S )Nz{}{} {{
r  z{}}};
)r   r#  r   r   r   s      rP   r   zNestedBlock.asFea  sP      99u{{4{///y'''
rR   r   r   r  rM   rR   rP   r   r     sU         % % % %
9 9 9
     rR   r   c                   (    e Zd ZdZddZd Zd	dZdS )
r   z*A named lookup, containing ``statements``.FNc                 Z    t                               | |           ||c| _        | _        d S r   r  r  s       rP   r   zLookupBlock.__init__  r  rR   c                     |                     | j        | j                   t                              | |           |                                 d S r   )start_lookup_blockr   r   r   r   end_lookup_blockr   s     rP   r   zLookupBlock.build  sH    ""4=$)<<<D'"""  """""rR   r   c                     d                     | j                  }| j        r|dz  }|dz  }|t                              | |          z  }|d                     || j                  z  }|S )Nz
lookup {} r  r  r  z	{}}} {};
)r   r   r  r   r   r   s      rP   r   zLookupBlock.asFea  sp    !!$),, 	#?"Cuu{{4{///|""649555
rR   r   r   r  rM   rR   rP   r   r     sQ        44< < < <# # #     rR   r   c                   ,     e Zd ZdZddZd fd	Z xZS )rF   zA ``table ... { }`` block.Nc                 J    t                               | |           || _        d S r   )r   r   r   )r   r   r   s      rP   r   zTableBlock.__init__  s!    tX&&&			rR   r   c                    d                     | j                                                  }|t          t          |                               |          z  }|d                     | j                                                  z  }|S )Nztable {} {{
r  z}} {};
)r   r   r  r   rF   r   )r   r   r   r   s      rP   r   zTableBlock.asFea  sp    $$TY__%6%677uZ&&,,F,;;;z  !2!2333
rR   r   r   r   r   s   @rP   rF   rF     sW        $$            rR   rF   c                   (    e Zd ZdZddZd ZddZdS )	r   z!Example: ``@UPPERCASE = [A-Z];``.Nc                 X    t                               | |           || _        || _        d S r   )rA   r   r   r   )r   r   r   r   s       rP   r   zGlyphClassDefinition.__init__  s*    4***	rR   c                 N    t          | j                                                  S r   )r   r   r   r   s    rP   r   zGlyphClassDefinition.glyphSet  s    T[))++,,,rR   r   c                 V    d| j         z   dz   | j                                        z   dz   S )Nr   z = ;)r   r   r   r   s     rP   r   zGlyphClassDefinition.asFea  s+    TY&):):)<)<<sBBrR   r   r   r   rM   rR   rP   r   r     sW        ++   
- - -C C C C C CrR   r   c                   *    e Zd ZdZ	 ddZd ZddZdS )	r   zExample: ``GlyphClassDef @UPPERCASE, [B], [C], [D];``. The parameters
    must be either :class:`GlyphClass` or :class:`GlyphClassName` objects, or
    ``None``.Nc                 v    t                               | |           ||c| _        | _        || _        || _        d S r   )rA   r   
baseGlyphs
markGlyphsligatureGlyphscomponentGlyphs)r   r8  r9  r:  r;  r   s         rP   r   zGlyphClassDefStatement.__init__  s@     	4***,6
(,.rR   c                    | j         r| j                                         nt                      }| j        r| j                                        nt                      }| j        r| j                                        nt                      }| j        r| j                                        nt                      }|                    | j        ||||           dS )z3Calls the builder's ``add_glyphClassDef`` callback.N)r8  r   r   r:  r9  r;  add_glyphClassDefr   )r   r   r   ligarn   comps         rP   r   zGlyphClassDefStatement.build  s    -1_It'')))%''151DQt"++---%''-1_It'')))%''262FSt#,,...EGG!!$-tT4HHHHHrR   r   c                 2   d                     | j        r| j                                        nd| j        r| j                                        nd| j        r| j                                        nd| j        r| j                                        nd          S )NzGlyphClassDef {}, {}, {}, {};r   )r   r8  r   r:  r9  r;  r   s     rP   r   zGlyphClassDefStatement.asFea  s    .55'+>DO!!###B+/+>FD%%'''B'+>DO!!###B,0,@HD &&(((b	
 
 	
rR   r   r   r  rM   rR   rP   r   r     s_         
 QU/ / / /I I I
 
 
 
 
 
rR   r   c                   ,    e Zd ZdZd Zd Zd ZddZdS )	r   aB  One `or more` ``markClass`` statements for the same mark class.

    While glyph classes can be defined only once, the feature file format
    allows expanding mark classes with multiple definitions, each using
    different glyphs and anchors. The following are two ``MarkClassDefinitions``
    for the same ``MarkClass``::

        markClass [acute grave] <anchor 350 800> @FRENCH_ACCENTS;
        markClass [cedilla] <anchor 350 -200> @FRENCH_ACCENTS;

    The ``MarkClass`` object is therefore just a container for a list of
    :class:`MarkClassDefinition` statements.
    c                 H    || _         g | _        t                      | _        d S r   )r   definitionsr   r   )r   r   s     rP   r   zMarkClass.__init__  s     	!mmrR   c                 *   t          |t                    sJ | j                            |           |                                D ]L}|| j        v r7| j        |         j        }|d}nd| }t          d|d||j                  || j        |<   MdS )z@Add a :class:`MarkClassDefinition` statement to this mark class.Nr   z at zGlyph z already defined)r   r   rC  r   r   r   r   r   )r   
definitionr   otherLocr   s        rP   addDefinitionzMarkClass.addDefinition  s    *&9:::::
+++((** 
	, 
	,E##;u-6#CC+++C%o49EE33?AT   ",DK
	, 
	,rR   c                 N    t          | j                                                  S r   )r   r   keysr   s    rP   r   zMarkClass.glyphSet"  s    T[%%''(((rR   r   c                 N    d                     d | j        D                       }|S )Nr   c              3   >   K   | ]}|                                 V  d S r   r   )rN   ds     rP   rQ   z"MarkClass.asFea.<locals>.<genexpr>'  s*      <<a		<<<<<<rR   )rS   rC  r   s      rP   r   zMarkClass.asFea&  s*    ii<<4+;<<<<<
rR   Nr   )r   r   r   r   r   rG  r   r   rM   rR   rP   r   r     s_         $ $ $
, , , ) ) )     rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   a   A single ``markClass`` statement. The ``markClass`` should be a
    :class:`MarkClass` object, the ``anchor`` an :class:`Anchor` object,
    and the ``glyphs`` parameter should be a `glyph-containing object`_ .

    Example:

        .. code:: python

            mc = MarkClass("FRENCH_ACCENTS")
            mc.addDefinition( MarkClassDefinition(mc, Anchor(350, 800),
                GlyphClass([ GlyphName("acute"), GlyphName("grave") ])
            ) )
            mc.addDefinition( MarkClassDefinition(mc, Anchor(350, -200),
                GlyphClass([ GlyphName("cedilla") ])
            ) )

            mc.asFea()
            # markClass [acute grave] <anchor 350 800> @FRENCH_ACCENTS;
            # markClass [cedilla] <anchor 350 -200> @FRENCH_ACCENTS;

    Nc                     t                               | |           t          |t                    sJ t          |t                    rt          |t
                    sJ |||c| _        | _        | _        d S r   )	rA   r   r   r   r   r&   r   rV   r   )r   r   rV   r   r   s        rP   r   zMarkClassDefinition.__init__B  sm    4***)Y/////&&))Lj.L.LLLL3<ff0T[[[rR   c                 4    | j                                         S r   )r   r   r   s    rP   r   zMarkClassDefinition.glyphSetH  s    {##%%%rR   r   c                     d                     | j                                        | j                                        | j        j                  S )NzmarkClass {} {} @{};)r   r   r   rV   r   r   r   s     rP   r   zMarkClassDefinition.asFeaL  sB    %,,K!2!2!4!4dn6I
 
 	
rR   r   r   r   rM   rR   rP   r   r   +  sY         ,M M M M& & &
 
 
 
 
 
rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   zA ``sub ... from ...`` statement.

    ``prefix``, ``glyph``, ``suffix`` and ``replacement`` should be lists of
    `glyph-containing objects`_. ``glyph`` should be a `one element list`.Nc                 v    t                               | |           |||c| _        | _        | _        || _        d S r   )rA   r   prefixr   suffixreplacement)r   rS  r   rT  rU  r   s         rP   r   z AlternateSubstStatement.__init__X  s<    4***06v,TZ&rR   c                 N   | j                                         }t          |          dk    s
J |            t          |          d         }d | j        D             }d | j        D             }| j                                        }|                    | j        ||||           dS )z5Calls the builder's ``add_alternate_subst`` callback.r   r   c                 6    g | ]}|                                 S rM   r   rN   ps     rP   r  z1AlternateSubstStatement.build.<locals>.<listcomp>b       4441!**,,444rR   c                 6    g | ]}|                                 S rM   rX  rN   r   s     rP   r  z1AlternateSubstStatement.build.<locals>.<listcomp>c  r[  rR   N)	r   r   r   listrS  rT  rU  add_alternate_substr   )r   r   r   rS  rT  rU  s         rP   r   zAlternateSubstStatement.build]  s    
##%%5zzQUA4444444444&//11##DM65&+VVVVVrR   r   c                    d}t          | j                  st          | j                  rt          | j                  r3|d                    t	          t
          | j                            dz   z  }|t          | j                  dz   z  }t          | j                  r3|dd                    t	          t
          | j                            z   z  }n|t          | j                  z  }|dz  }|t          | j                  z  }|dz  }|S )Nsub r   'z from r5  )r   rS  rT  rS   r   r   r   rU  r   s      rP   r   zAlternateSubstStatement.asFeag  s    t{ 	%s4;// 	%4; ?sxxE4; 7 7883>>5$$s**C4; ?sSXXc%&=&=>>>>5$$$CxuT%&&&s

rR   r   r   r  rM   rR   rP   r   r   R  sZ        N N
' ' ' '
W W W     rR   r   c                   ,    e Zd ZdZ	 	 	 	 	 ddZddZdS )r   zAn ``Anchor`` element, used inside a ``pos`` rule.

    If a ``name`` is given, this will be used in preference to the coordinates.
    Other values should be integer.
    Nc                     t                               | |           || _        |||c| _        | _        | _        ||c| _        | _        d S r   )r&   r   r   xycontourpointxDeviceTableyDeviceTable)r   re  rf  r   rg  rh  ri  r   s           rP   r   zAnchor.__init__~  sP     	D(+++	,-q,))/;\,4,,,rR   r   c                 f   | j         d                    | j                   S d                    | j        | j                  }| j        r|d                    | j                  z  }| j        s| j        r8|dz  }|t          | j                  z  }|dz  }|t          | j                  z  }|dz  }|S )Nz<anchor {}>z<anchor {} {} contourpoint {}r   >)r   r   re  rf  rg  rh  ri  rU   r   s      rP   r   zAnchor.asFea  s    9  ''	222$$TVTV44 	@%,,T->???C 	5 1 	53JC>$"3444C3JC>$"3444Cs

rR   )NNNNNr   r   rM   rR   rP   r   r   w  s[          J J J J     rR   r   c                   "    e Zd ZdZddZddZdS )r   zCA named anchor definition. (2.e.viii). ``name`` should be a string.Nc                 z    t                               | |           ||||f\  | _        | _        | _        | _        d S r   )rA   r   r   re  rf  rg  )r   r   re  rf  rg  r   s         rP   r   zAnchorDefinition.__init__  s>    4***7;Q<7O4	46464#4#4#4rR   r   c                     d                     | j        | j                  }| j        r|d                     | j                  z  }|d                     | j                  z  }|S )NzanchorDef {} {}rk  z {};)r   re  rf  rg  r   r   s      rP   r   zAnchorDefinition.asFea  s`    &&tvtv66 	@%,,T->???Cv}}TY'''
rR   r   r   r   rM   rR   rP   r   r     sF        MMP P P P     rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r   z&A ``GDEF`` table ``Attach`` statement.Nc                 X    t                               | |           || _        || _        d S r   )rA   r   r   contourPoints)r   r   rr  r   s       rP   r   zAttachStatement.__init__  s-    4****rR   c                 z    | j                                         }|                    | j        || j                   dS )z3Calls the builder's ``add_attach_points`` callback.N)r   r   add_attach_pointsr   rr  r   r   r   s      rP   r   zAttachStatement.build  s8    %%''!!$-9KLLLLLrR   r   c                     d                     | j                                        d                    d | j        D                                 S )NzAttach {} {};r   c              3   4   K   | ]}t          |          V  d S r   str)rN   cs     rP   rQ   z(AttachStatement.asFea.<locals>.<genexpr>  s(      )M)MQ#a&&)M)M)M)M)M)MrR   )r   r   r   rS   rr  r   s     rP   r   zAttachStatement.asFea  sK    %%K)M)M$:L)M)M)M!M!M
 
 	
rR   r   r   r  rM   rR   rP   r   r     sT        00+ + + +
M M M

 
 
 
 
 
rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r    a@  A chained contextual positioning statement.

    ``prefix``, ``glyphs``, and ``suffix`` should be lists of
    `glyph-containing objects`_ .

    ``lookups`` should be a list of elements representing what lookups
    to apply at each glyph position. Each element should be a
    :class:`LookupBlock` to apply a single chaining lookup at the given
    position, a list of :class:`LookupBlock`\ s to apply multiple
    lookups, or ``None`` to apply no lookup. The length of the outer
    list should equal the length of ``glyphs``; the inner lists can be
    of variable length.Nc                    t                               | |           |||c| _        | _        | _        t          |          | _        t          |          D ]0\  }}|r)	 d |D              # t          $ r |g| j        |<   Y ,w xY w1d S )Nc              3      K   | ]}|V  d S r   rM   rN   _s     rP   rQ   z4ChainContextPosStatement.__init__.<locals>.<genexpr>  "      ''1Q''''''rR   	rA   r   rS  r   rT  r^  lookupsr^   	TypeErrorr   rS  r   rT  r  r   irl   s           rP   r   z!ChainContextPosStatement.__init__      4***06-T[$+G}}"7++ 	/ 	/IAv //'''''''  / / /'-hDLOOO//	/ 	/   A**BBc                     d | j         D             }d | j        D             }d | j        D             }|                    | j        |||| j                   dS )z7Calls the builder's ``add_chain_context_pos`` callback.c                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z2ChainContextPosStatement.build.<locals>.<listcomp>  r[  rR   c                 6    g | ]}|                                 S rM   rX  rN   r   s     rP   r  z2ChainContextPosStatement.build.<locals>.<listcomp>  r[  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z2ChainContextPosStatement.build.<locals>.<listcomp>  r[  rR   N)rS  r   rT  add_chain_context_posr   r  r   r   rS  r   rT  s        rP   r   zChainContextPosStatement.build  sr    444444444444444%%M6664<	
 	
 	
 	
 	
rR   r   c                 
   d}t          | j                  s3t          | j                  st          d | j        D                       rt          | j                  r*|d                    d | j        D                       dz   z  }t          | j                  D ]i\  }}||                                dz   z  }| j        |         r| j        |         D ]}|d|j	        z   z  }|t          | j                  dz
  k     r|dz  }jt          | j                  r3|dd                    t          t          | j                            z   z  }n0|d                    t          t          | j                            z  }|dz  }|S )	Npos c                     g | ]}|d uS r   rM   rN   re  s     rP   r  z2ChainContextPosStatement.asFea.<locals>.<listcomp>      888aATM888rR   r   c              3   >   K   | ]}|                                 V  d S r   r   r  s     rP   rQ   z1ChainContextPosStatement.asFea.<locals>.<genexpr>  *      ??a		??????rR   rb   lookup r   r5  r   rS  rT  anyr  rS   r^   r   r   r   r   r   r   r   r   r  r   lus         rP   r   zChainContextPosStatement.asFea     	44;	4 884<88899	4
 4; Fsxx??4;?????#EE!$+..  1qwwyy3&<? 4"l1o 4 4zBG33s4;''!+++3JC4; ?sSXXc%&=&=>>>>388Ctz22333Cs

rR   r   r   r  rM   rR   rP   r    r      U         	/ 	/ 	/ 	/
 
 
     rR   r    c                   (    e Zd ZdZddZd ZddZdS )	r!   aA  A chained contextual substitution statement.

    ``prefix``, ``glyphs``, and ``suffix`` should be lists of
    `glyph-containing objects`_ .

    ``lookups`` should be a list of elements representing what lookups
    to apply at each glyph position. Each element should be a
    :class:`LookupBlock` to apply a single chaining lookup at the given
    position, a list of :class:`LookupBlock`\ s to apply multiple
    lookups, or ``None`` to apply no lookup. The length of the outer
    list should equal the length of ``glyphs``; the inner lists can be
    of variable length.Nc                    t                               | |           |||c| _        | _        | _        t          |          | _        t          |          D ]0\  }}|r)	 d |D              # t          $ r |g| j        |<   Y ,w xY w1d S )Nc              3      K   | ]}|V  d S r   rM   r~  s     rP   rQ   z6ChainContextSubstStatement.__init__.<locals>.<genexpr>  r  rR   r  r  s           rP   r   z#ChainContextSubstStatement.__init__  r  r  c                     d | j         D             }d | j        D             }d | j        D             }|                    | j        |||| j                   dS )z9Calls the builder's ``add_chain_context_subst`` callback.c                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z4ChainContextSubstStatement.build.<locals>.<listcomp>  r[  rR   c                 6    g | ]}|                                 S rM   rX  r  s     rP   r  z4ChainContextSubstStatement.build.<locals>.<listcomp>  r[  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z4ChainContextSubstStatement.build.<locals>.<listcomp>  r[  rR   N)rS  r   rT  add_chain_context_substr   r  r  s        rP   r   z ChainContextSubstStatement.build  sr    444444444444444''M6664<	
 	
 	
 	
 	
rR   r   c                 
   d}t          | j                  s3t          | j                  st          d | j        D                       rt          | j                  r*|d                    d | j        D                       dz   z  }t          | j                  D ]i\  }}||                                dz   z  }| j        |         r| j        |         D ]}|d|j	        z   z  }|t          | j                  dz
  k     r|dz  }jt          | j                  r3|dd                    t          t          | j                            z   z  }n0|d                    t          t          | j                            z  }|dz  }|S )	Nra  c                     g | ]}|d uS r   rM   r  s     rP   r  z4ChainContextSubstStatement.asFea.<locals>.<listcomp>  r  rR   r   c              3   >   K   | ]}|                                 V  d S r   r   r  s     rP   rQ   z3ChainContextSubstStatement.asFea.<locals>.<genexpr>"  r  rR   rb  r  r   r5  r  r  s         rP   r   z ChainContextSubstStatement.asFea  r  rR   r   r   r  rM   rR   rP   r!   r!     r  rR   r!   c                   (    e Zd ZdZddZd ZddZdS )	r#   znA cursive positioning statement. Entry and exit anchors can either
    be :class:`Anchor` objects or ``None``.Nc                 h    t                               | |           || _        ||c| _        | _        d S r   )rA   r   r   entryAnchor
exitAnchor)r   r   r  r  r   s        rP   r   zCursivePosStatement.__init__6  s4    4***$,7)$///rR   c                     |                     | j        | j                                        | j        | j                   dS )z8Calls the builder object's ``add_cursive_pos`` callback.N)add_cursive_posr   r   r   r  r  r   s     rP   r   zCursivePosStatement.build;  sB    M4?3355t7G	
 	
 	
 	
 	
rR   r   c                     | j         r| j                                         nd}| j        r| j                                        nd}d                    | j                                        ||          S )N<anchor NULL>zpos cursive {} {} {};)r  r   r  r   r   )r   r   entryexits       rP   r   zCursivePosStatement.asFeaA  sh    ,0,<Q &&(((/*./Nt$$&&&&--do.C.C.E.EudSSSrR   r   r   r  rM   rR   rP   r#   r#   2  s_        / /D D D D

 
 
T T T T T TrR   r#   c                   (    e Zd ZdZddZd ZddZdS )	r(   zExample: ``feature salt;``Nc                 Z    t                               | |           ||c| _        | _        d S r   )rA   r   r   featureName)r   r  r   s      rP   r   z"FeatureReferenceStatement.__init__J  s/    4***+3['t'''rR   c                 F    |                     | j        | j                   dS )z>Calls the builder object's ``add_feature_reference`` callback.N)add_feature_referencer   r  r   s     rP   r   zFeatureReferenceStatement.buildN  s#    %%dmT5EFFFFFrR   r   c                 6    d                     | j                  S )Nzfeature {};)r   r  r   s     rP   r   zFeatureReferenceStatement.asFeaR  s    ##D$4555rR   r   r   r  rM   rR   rP   r(   r(   G  sX        $$B B B BG G G6 6 6 6 6 6rR   r(   c                   (    e Zd ZdZddZd ZddZdS )	r+   zAn ``ignore pos`` statement, containing `one or more` contexts to ignore.

    ``chainContexts`` should be a list of ``(prefix, glyphs, suffix)`` tuples,
    with each of ``prefix``, ``glyphs`` and ``suffix`` being
    `glyph-containing objects`_ .Nc                 J    t                               | |           || _        d S r   rA   r   chainContextsr   r  r   s      rP   r   zIgnorePosStatement.__init__]  &    4****rR   c                     | j         D ]H\  }}}d |D             }d |D             }d |D             }|                    | j        |||g            IdS )z[Calls the builder object's ``add_chain_context_pos`` callback on each
        rule context.c                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z,IgnorePosStatement.build.<locals>.<listcomp>e       333qajjll333rR   c                 6    g | ]}|                                 S rM   rX  r  s     rP   r  z,IgnorePosStatement.build.<locals>.<listcomp>f  r  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z,IgnorePosStatement.build.<locals>.<listcomp>g  r  rR   N)r  r  r   r  s        rP   r   zIgnorePosStatement.builda  s     '+&8 	U 	U"FFF33F333F33F333F33F333F))$-QSTTTT		U 	UrR   r   c           	      V   g }| j         D ]\  }}}d}t          |          st          |          rt          |          r.|d                    t          t          |                    dz   z  }|d                    d |D                       z  }t          |          r.|dd                    t          t          |                    z   z  }n+|d                    t          t          |                    z  }|                    |           dd                    |          z   dz   S )Nr   r   c              3   D   K   | ]}|                                 d z   V  dS rb  Nr   r  s     rP   rQ   z+IgnorePosStatement.asFea.<locals>.<genexpr>q  .      @@A		C@@@@@@rR   zignore pos rK   r5  r  r   rS   r   r   r   r   r   contextsrS  r   rT  r   s          rP   r   zIgnorePosStatement.asFeaj     &*&8 
	! 
	!"FFFC6{{ 4c&kk 4v;; >388Cv$6$677#==Csxx@@@@@@@@v;; >3#eV*<*<!=!===CsxxE6 2 2333OOC    tyy222S88rR   r   r   r  rM   rR   rP   r+   r+   V  sX        % %+ + + +U U U9 9 9 9 9 9rR   r+   c                   (    e Zd ZdZddZd ZddZdS )	r,   zAn ``ignore sub`` statement, containing `one or more` contexts to ignore.

    ``chainContexts`` should be a list of ``(prefix, glyphs, suffix)`` tuples,
    with each of ``prefix``, ``glyphs`` and ``suffix`` being
    `glyph-containing objects`_ .Nc                 J    t                               | |           || _        d S r   r  r  s      rP   r   zIgnoreSubstStatement.__init__  r  rR   c                     | j         D ]H\  }}}d |D             }d |D             }d |D             }|                    | j        |||g            IdS )z]Calls the builder object's ``add_chain_context_subst`` callback on
        each rule context.c                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z.IgnoreSubstStatement.build.<locals>.<listcomp>  r  rR   c                 6    g | ]}|                                 S rM   rX  r  s     rP   r  z.IgnoreSubstStatement.build.<locals>.<listcomp>  r  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z.IgnoreSubstStatement.build.<locals>.<listcomp>  r  rR   N)r  r  r   r  s        rP   r   zIgnoreSubstStatement.build  s     '+&8 	W 	W"FFF33F333F33F333F33F333F++DM666SUVVVV		W 	WrR   r   c           	      V   g }| j         D ]\  }}}d}t          |          st          |          rt          |          r.|d                    t          t          |                    dz   z  }|d                    d |D                       z  }t          |          r.|dd                    t          t          |                    z   z  }n+|d                    t          t          |                    z  }|                    |           dd                    |          z   dz   S )Nr   r   c              3   D   K   | ]}|                                 d z   V  dS r  r   r  s     rP   rQ   z-IgnoreSubstStatement.asFea.<locals>.<genexpr>  r  rR   zignore sub rK   r5  r  r  s          rP   r   zIgnoreSubstStatement.asFea  r  rR   r   r   r  rM   rR   rP   r,   r,   z  sX        % %+ + + +W W W9 9 9 9 9 9rR   r,   c                   2     e Zd ZdZd fd	Zd ZddZ xZS )	r-   zAn ``include()`` statement.Nc                 f    t          t          |                               |           || _        d S r   )r   r-   r   filename)r   r  r   r   s      rP   r   zIncludeStatement.__init__  s-    %%..x888 rR   c                 ,    t          d| j                  )NzqBuilding an include statement is not implemented yet. Instead, use Parser(..., followIncludes=True) for building.)r   r   r   s    rP   r   zIncludeStatement.build  s    JM
 
 	
rR   r   c                     |d| j         z  z   S )Nzinclude(%s);)r  r   s     rP   r   zIncludeStatement.asFea  s    666rR   r   r   )r   r   r   r   r   r   r   r   r   s   @rP   r-   r-     sf        %%! ! ! ! ! !
 
 
7 7 7 7 7 7 7 7rR   r-   c                   (    e Zd ZdZd	dZd Zd
dZdS )r.   z*A ``language`` statement within a feature.TFNc                     t                               | |           t          |          dk    sJ || _        || _        || _        d S )N   )rA   r   r   rj   include_defaultrv   )r   rj   r  rv   r   s        rP   r   zLanguageStatement.__init__  sI    4***8}}!!!! . rR   c                 `    |                     | j        | j        | j        | j                   dS )z4Call the builder object's ``set_language`` callback.)r   rj   r  rv   N)set_languager   rj   r  rv   r   s     rP   r   zLanguageStatement.build  s>    ]] 0]	 	 	
 	
 	
 	
 	
rR   r   c                     d                     | j                                                  }| j        s|dz  }| j        r|dz  }|dz  }|S )Nzlanguage {}z exclude_dfltz	 requiredr5  )r   rj   r  r  rv   r   s      rP   r   zLanguageStatement.asFea  sZ    ""4=#6#6#8#899# 	#?"C= 	;Cs

rR   )TFNr   r  rM   rR   rP   r.   r.     sQ        44! ! ! !
 
 
     rR   r.   c                   (    e Zd ZdZddZd ZddZdS )	r/   z)A top-level ``languagesystem`` statement.Nc                 Z    t                               | |           ||c| _        | _        d S r   )rA   r   rz   rj   )r   rz   rj   r   s       rP   r   z LanguageSystemStatement.__init__  s,    4***&,h"T]]]rR   c                 R    |                     | j        | j        | j                   dS )z<Calls the builder object's ``add_language_system`` callback.N)add_language_systemr   rz   rj   r   s     rP   r   zLanguageSystemStatement.build  s&    ##DM4;NNNNNrR   r   c                 f    d                     | j        | j                                                  S )Nzlanguagesystem {} {};)r   rz   rj   r  r   s     rP   r   zLanguageSystemStatement.asFea  s(    &--dk4=;N;N;P;PQQQrR   r   r   r  rM   rR   rP   r/   r/     sZ        338 8 8 8O O OR R R R R RrR   r/   c                   (    e Zd ZdZddZd ZddZdS )	r)   zA ``head`` table ``FontRevision`` statement. ``revision`` should be a
    number, and will be formatted to three significant decimal places.Nc                 J    t                               | |           || _        d S r   )rA   r   revision)r   r  r   s      rP   r   zFontRevisionStatement.__init__  s#    4*** rR   c                 F    |                     | j        | j                   d S r   )set_font_revisionr   r  r   s     rP   r   zFontRevisionStatement.build  s"    !!$-?????rR   r   c                 6    d                     | j                  S )NzFontRevision {:.3f};)r   r  r   s     rP   r   zFontRevisionStatement.asFea  s    %,,T];;;rR   r   r   r  rM   rR   rP   r)   r)     sZ        J J! ! ! !@ @ @< < < < < <rR   r)   c                   (    e Zd ZdZddZd ZddZdS )	r0   zA ``GDEF`` table ``LigatureCaretByIndex`` statement. ``glyphs`` should be
    a `glyph-containing object`_, and ``carets`` should be a list of integers.Nc                 Z    t                               | |           ||c| _        | _        d S r   rA   r   r   caretsr   r   r  r   s       rP   r   z&LigatureCaretByIndexStatement.__init__  ,    4***$*F T[[[rR   c                     | j                                         }|                    | j        |t	          | j                             dS )zBCalls the builder object's ``add_ligatureCaretByIndex_`` callback.N)r   r   add_ligatureCaretByIndex_r   setr  ru  s      rP   r   z#LigatureCaretByIndexStatement.build  s?    %%''))$-T[AQAQRRRRRrR   r   c                     d                     | j                                        d                    d | j        D                                 S )NzLigatureCaretByIndex {} {};r   c              3   4   K   | ]}t          |          V  d S r   rx  r  s     rP   rQ   z6LigatureCaretByIndexStatement.asFea.<locals>.<genexpr>  (      )F)FQ#a&&)F)F)F)F)F)FrR   r   r   r   rS   r  r   s     rP   r   z#LigatureCaretByIndexStatement.asFea  sJ    ,33K)F)F$+)F)F)F!F!F
 
 	
rR   r   r   r  rM   rR   rP   r0   r0     sZ        R R4 4 4 4S S S

 
 
 
 
 
rR   r0   c                   (    e Zd ZdZddZd ZddZdS )	r1   zA ``GDEF`` table ``LigatureCaretByPos`` statement. ``glyphs`` should be
    a `glyph-containing object`_, and ``carets`` should be a list of integers.Nc                 Z    t                               | |           ||c| _        | _        d S r   r  r  s       rP   r   z$LigatureCaretByPosStatement.__init__  r  rR   c                     | j                                         }|                    | j        |t	          | j                             dS )z@Calls the builder object's ``add_ligatureCaretByPos_`` callback.N)r   r   add_ligatureCaretByPos_r   r  r  ru  s      rP   r   z!LigatureCaretByPosStatement.build  s?    %%''''vs4;?O?OPPPPPrR   r   c                     d                     | j                                        d                    d | j        D                                 S )NzLigatureCaretByPos {} {};r   c              3   4   K   | ]}t          |          V  d S r   rx  r  s     rP   rQ   z4LigatureCaretByPosStatement.asFea.<locals>.<genexpr>  r  rR   r  r   s     rP   r   z!LigatureCaretByPosStatement.asFea  sJ    *11K)F)F$+)F)F)F!F!F
 
 	
rR   r   r   r  rM   rR   rP   r1   r1     sZ        R R4 4 4 4Q Q Q

 
 
 
 
 
rR   r1   c                   (    e Zd ZdZddZd ZddZdS )	r2   aS  A chained contextual substitution statement.

    ``prefix``, ``glyphs``, and ``suffix`` should be lists of
    `glyph-containing objects`_; ``replacement`` should be a single
    `glyph-containing object`_.

    If ``forceChain`` is True, this is expressed as a chaining rule
    (e.g. ``sub f' i' by f_i``) even when no context is given.Nc                     t                               | |           |||c| _        | _        | _        ||c| _        | _        d S r   )rA   r   rS  r   rT  rU  
forceChain)r   rS  r   rT  rU  r  r   s          rP   r   zLigatureSubstStatement.__init__  sC    4***17-T[$+,7)$///rR   c                     d | j         D             }d | j        D             }d | j        D             }|                    | j        |||| j        | j                   d S )Nc                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z0LigatureSubstStatement.build.<locals>.<listcomp>"  r[  rR   c                 6    g | ]}|                                 S rM   rX  r  s     rP   r  z0LigatureSubstStatement.build.<locals>.<listcomp>#  r[  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z0LigatureSubstStatement.build.<locals>.<listcomp>$  r[  rR   )rS  r   rT  add_ligature_substr   rU  r  r  s        rP   r   zLigatureSubstStatement.build!  sw    444444444444444""M66643CT_	
 	
 	
 	
 	
rR   r   c                 @   d}t          | j                  st          | j                  s| j        rt          | j                  r*|d                    d | j        D                       dz   z  }|d                    d | j        D                       z  }t          | j                  r*|dd                    d | j        D                       z   z  }n'|d                    d | j        D                       z  }|dz  }|t          | j                  z  }|dz  }|S )	Nra  r   c              3   >   K   | ]}|                                 V  d S r   r   r  s     rP   rQ   z/LigatureSubstStatement.asFea.<locals>.<genexpr>-  r  rR   c              3   D   K   | ]}|                                 d z   V  dS r  r   r  s     rP   rQ   z/LigatureSubstStatement.asFea.<locals>.<genexpr>.  s.      AAAGGIIOAAAAAArR   c              3   >   K   | ]}|                                 V  d S r   r   r  s     rP   rQ   z/LigatureSubstStatement.asFea.<locals>.<genexpr>0  s*      %E%EAaggii%E%E%E%E%E%ErR   c              3   >   K   | ]}|                                 V  d S r   r   r  s     rP   rQ   z/LigatureSubstStatement.asFea.<locals>.<genexpr>2  s*      ;;!AGGII;;;;;;rR    by r5  )r   rS  rT  r  rS   r   r   rU  r   s      rP   r   zLigatureSubstStatement.asFea)  s,   t{ 	<s4;// 	<4? 	<4; Fsxx??4;?????#EE388AAT[AAAAAAC4; FsSXX%E%E%E%E%EEEEE388;;t{;;;;;;CvuT%&&&s

rR   r   r   r  rM   rR   rP   r2   r2     s[        B BD D D D

 
 
     rR   r2   c                   *    e Zd ZdZ	 ddZd Zd	dZdS )
r3   zA ``lookupflag`` statement. The ``value`` should be an integer value
    representing the flags in use, but not including the ``markAttachment``
    class and ``markFilteringSet`` values, which must be specified as
    glyph-containing objects.r   Nc                 f    t                               | |           || _        || _        || _        d S r   )rA   r   r  markAttachmentmarkFilteringSet)r   r  r  r  r   s        rP   r   zLookupFlagStatement.__init__?  s7     	4***
, 0rR   c                     d}| j         | j                                         }d}| j        | j                                        }|                    | j        | j        ||           dS )z8Calls the builder object's ``set_lookup_flag`` callback.N)r  r   r  set_lookup_flagr   r  )r   r   
markAttach
markFilters       rP   r   zLookupFlagStatement.buildG  sj    
*,5577J
 ,.7799Jtz:zRRRRRrR   r   c                    g }g d}d}t          t          |                    D ]0}| j        |z  dk    r|                    ||                    |dz  }1| j        ?|                    d                    | j                                                             | j        ?|                    d                    | j                                                             |sdg}d                    d                    |                    S )	N)RightToLeftIgnoreBaseGlyphsIgnoreLigaturesIgnoreMarksr   r   zMarkAttachmentType {}zUseMarkFilteringSet {}0zlookupflag {};r   )	ranger   r  r   r  r   r   r  rS   )r   r   r   flagsr   r  s         rP   r   zLookupFlagStatement.asFeaQ  s   UUUs5zz"" 	 	AzD A%%

58$$$19DD*JJ.55d6I6O6O6Q6QRRSSS ,JJ/66t7L7R7R7T7TUUVVV 	%C&&sxx}}555rR   )r   NNNr   r  rM   rR   rP   r3   r3   9  s_        ! ! MQ1 1 1 1S S S6 6 6 6 6 6rR   r3   c                   (    e Zd ZdZddZd ZddZdS )	r4   zRepresents a ``lookup ...;`` statement to include a lookup in a feature.

    The ``lookup`` should be a :class:`LookupBlock` object.Nc                 Z    t                               | |           ||c| _        | _        d S r   )rA   r   r   rl   )r   rl   r   s      rP   r   z!LookupReferenceStatement.__init__g  s,    4***&."t{{{rR   c                 D    |                     | j        j                   dS )z8Calls the builder object's ``add_lookup_call`` callback.N)add_lookup_callrl   r   r   s     rP   r   zLookupReferenceStatement.buildk  s!     011111rR   r   c                 @    d                     | j        j                  S )Nz
lookup {};)r   rl   r   r   s     rP   r   zLookupReferenceStatement.asFeao  s    ""4;#3444rR   r   r   r  rM   rR   rP   r4   r4   b  sU        ? ?8 8 8 82 2 25 5 5 5 5 5rR   r4   c                   (    e Zd ZdZddZd ZddZdS )	r5   zA mark-to-base positioning rule. The ``base`` should be a
    `glyph-containing object`_. The ``marks`` should be a list of
    (:class:`Anchor`, :class:`MarkClass`) tuples.Nc                 Z    t                               | |           ||c| _        | _        d S r   )rA   r   r   marks)r   r   r"  r   s       rP   r   zMarkBasePosStatement.__init__x  s,    4*** $e	4:::rR   c                 v    |                     | j        | j                                        | j                   dS )z:Calls the builder object's ``add_mark_base_pos`` callback.N)add_mark_base_posr   r   r   r"  r   s     rP   r   zMarkBasePosStatement.build|  s2    !!$-1C1C1E1EtzRRRRRrR   r   c                     d                     | j                                                  }| j        D ]C\  }}|d|z   t          z   d                     |                                |j                  z   z  }D|dz  }|S )Nzpos base {}r   {} mark @{}r5  )r   r   r   r"  r  r   r   r   r   ams        rP   r   zMarkBasePosStatement.asFea  sz    ""49??#4#455J 	S 	SDAq4&=5(=+?+?		16+R+RRRCCs

rR   r   r   r  rM   rR   rP   r5   r5   s  sX        5 5, , , ,S S S     rR   r5   c                   (    e Zd ZdZddZd ZddZdS )	r6   a  A mark-to-ligature positioning rule. The ``ligatures`` must be a
    `glyph-containing object`_. The ``marks`` should be a list of lists: each
    element in the top-level list represents a component glyph, and is made
    up of a list of (:class:`Anchor`, :class:`MarkClass`) tuples representing
    mark attachment points for that position.

    Example::

        m1 = MarkClass("TOP_MARKS")
        m2 = MarkClass("BOTTOM_MARKS")
        # ... add definitions to mark classes...

        glyph = GlyphName("lam_meem_jeem")
        marks = [
            [ (Anchor(625,1800), m1) ], # Attachments on 1st component (lam)
            [ (Anchor(376,-378), m2) ], # Attachments on 2nd component (meem)
            [ ]                         # No attachments on the jeem
        ]
        mlp = MarkLigPosStatement(glyph, marks)

        mlp.asFea()
        # pos ligature lam_meem_jeem <anchor 625 1800> mark @TOP_MARKS
        # ligComponent <anchor 376 -378> mark @BOTTOM_MARKS;

    Nc                 Z    t                               | |           ||c| _        | _        d S r   )rA   r   	ligaturesr"  )r   r,  r"  r   s       rP   r   zMarkLigPosStatement.__init__  ,    4***%."


rR   c                 v    |                     | j        | j                                        | j                   dS )z9Calls the builder object's ``add_mark_lig_pos`` callback.N)add_mark_lig_posr   r,  r   r"  r   s     rP   r   zMarkLigPosStatement.build  s2      0G0G0I0I4:VVVVVrR   r   c                    d                     | j                                                  }g }| j        D ]}d}|t	          |          sd|z   t
          dz  z   dz   }nI|D ]F\  }}|d|z   t
          dz  z   d                     |                                |j                  z   z  }G|                    |           |d|z   t
          z   dz                       |          z  }|dz  }|S )	Nzpos ligature {}r   r   r   r  r&  ligComponentr5  )	r   r,  r   r"  r   r  r   r   rS   )r   r   r   ligsltempr(  r)  s           rP   r   zMarkLigPosStatement.asFea  s   &&t~';';'='=>> 	 	ADyAyf}uqy0?B  DAq !!)$ (..qwwyy!&AABDD KKv%6<<TBBBs

rR   r   r   r  rM   rR   rP   r6   r6     sX         46 6 6 6W W W     rR   r6   c                   (    e Zd ZdZddZd ZddZdS )	r7   zA mark-to-mark positioning rule. The ``baseMarks`` must be a
    `glyph-containing object`_. The ``marks`` should be a list of
    (:class:`Anchor`, :class:`MarkClass`) tuples.Nc                 Z    t                               | |           ||c| _        | _        d S r   )rA   r   	baseMarksr"  )r   r7  r"  r   s       rP   r   zMarkMarkPosStatement.__init__  r-  rR   c                 v    |                     | j        | j                                        | j                   dS )z:Calls the builder object's ``add_mark_mark_pos`` callback.N)add_mark_mark_posr   r7  r   r"  r   s     rP   r   zMarkMarkPosStatement.build  s2    !!$-1H1H1J1JDJWWWWWrR   r   c                     d                     | j                                                  }| j        D ]C\  }}|d|z   t          z   d                     |                                |j                  z   z  }D|dz  }|S )Nzpos mark {}r   r&  r5  )r   r7  r   r"  r  r   r'  s        rP   r   zMarkMarkPosStatement.asFea  s|    ""4>#7#7#9#9::J 	S 	SDAq4&=5(=+?+?		16+R+RRRCCs

rR   r   r   r  rM   rR   rP   r7   r7     sX        5 56 6 6 6X X X     rR   r7   c                   *    e Zd ZdZ	 ddZd Zd	dZdS )
r8   a  A multiple substitution statement.

    Args:
        prefix: a list of `glyph-containing objects`_.
        glyph: a single glyph-containing object.
        suffix: a list of glyph-containing objects.
        replacement: a list of glyph-containing objects.
        forceChain: If true, the statement is expressed as a chaining rule
            (e.g. ``sub f' i' by f_i``) even when no context is given.
    FNc                     t                               | |           |||c| _        | _        | _        || _        || _        d S r   )rA   r   rS  r   rT  rU  r  )r   rS  r   rT  rU  r  r   s          rP   r   zMultipleSubstStatement.__init__  sC     	4***/5uf,TZ&$rR   c           	      l   d | j         D             }d | j        D             }| j        s\t          | j        d          rG| j                                        D ]+}|                    | j        |||| j        | j                   ,dS |                    | j        || j        || j        | j                   dS )z;Calls the builder object's ``add_multiple_subst`` callback.c                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z0MultipleSubstStatement.build.<locals>.<listcomp>  r[  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z0MultipleSubstStatement.build.<locals>.<listcomp>  r[  rR   r   N)	rS  rT  rU  r   r   r   add_multiple_substr   r  )r   r   rS  rT  r   s        rP   r   zMultipleSubstStatement.build  s    4444444444 	GDJ
$C$C 	,,..  **M65&$:JDO    
 &&vtz64;KT_    rR   r   c                 ~   d}t          | j                  st          | j                  s| j        rt          | j                  r3|d                    t          t          | j                            dz   z  }|t          | j                  dz   z  }t          | j                  r3|dd                    t          t          | j                            z   z  }n|t          | j                  z  }| j        pt                      g}|dz  }|d                    t          t          |                    z  }|dz  }|S )Nra  r   rb  r
  r5  )
r   rS  rT  r  rS   r   r   r   rU  r   )r   r   r   rU  s       rP   r   zMultipleSubstStatement.asFea  s   t{ 	%s4;// 	%4? 	%4; ?sxxE4; 7 7883>>5$$s**C4; ?sSXXc%&=&=>>>>5$$$C&79;;-vsxxE;//000s

rR   r   r   r  rM   rR   rP   r8   r8     s\        	 	 NR% % % %       rR   r8   c                   ,    e Zd ZdZ	 	 ddZd Zd	dZdS )
r;   a  A pair positioning statement.

    ``glyphs1`` and ``glyphs2`` should be `glyph-containing objects`_.
    ``valuerecord1`` should be a :class:`ValueRecord` object;
    ``valuerecord2`` should be either a :class:`ValueRecord` object or ``None``.
    If ``enumerated`` is true, then this is expressed as an
    `enumerated pair <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#6.b.ii>`_.
    FNc                     t                               | |           || _        ||c| _        | _        ||c| _        | _        d S r   )rA   r   
enumeratedglyphs1valuerecord1glyphs2valuerecord2)r   rE  rF  rG  rH  rD  r   s          rP   r   zPairPosStatement.__init__  sI     	4***$*1<'d'*1<'d'''rR   c                    | j         rp| j                                        | j                                        g}t	          j        | D ]-\  }}|                    | j        || j        || j	                   .dS t          | j        t                    ot          | j        t                    }|r>|                    | j        | j        j        | j        | j        j        | j	                   dS |                    | j        | j                                        | j        | j                                        | j	                   dS )aM  Calls a callback on the builder object:

        * If the rule is enumerated, calls ``add_specific_pair_pos`` on each
          combination of first and second glyphs.
        * If the glyphs are both single :class:`GlyphName` objects, calls
          ``add_specific_pair_pos``.
        * Else, calls ``add_class_pair_pos``.
        N)rD  rE  r   rG  	itertoolsproductadd_specific_pair_posr   rF  rH  r   r   r   add_class_pair_pos)r   r   r   glyph1glyph2is_specifics         rP   r   zPairPosStatement.build   sS    ? 	&&(($,*?*?*A*ABA"+"3Q"7  --M64+<fdFW    F y99 
jL)?
 ?
  	))"!"!     &&%%''!%%''!    rR   r   c                    | j         rdnd}| j        rx|d                    | j                                        | j                                        | j                                        | j                                                  z  }n_|d                    | j                                        | j                                        | j                                                  z  }|S )Nzenum r   zpos {} {} {} {};zpos {} {} {};)rD  rH  r   rE  r   rF  rG  r   s      rP   r   zPairPosStatement.asFeaE  s    0ggb 
	%,,""$$!''))""$$!''))	  CC ?))""$$dl&8&8&:&:D<M<S<S<U<U  C 
rR   r   r   r  rM   rR   rP   r;   r;     sb          @ @ @ @# # #J     rR   r;   c                   (    e Zd ZdZddZd ZddZdS )	r<   aP  A reverse chaining substitution statement. You don't see those every day.

    Note the unusual argument order: ``suffix`` comes `before` ``glyphs``.
    ``old_prefix``, ``old_suffix``, ``glyphs`` and ``replacements`` should be
    lists of `glyph-containing objects`_. ``glyphs`` and ``replacements`` should
    be one-item lists.
    Nc                 v    t                               | |           ||c| _        | _        || _        || _        d S r   )rA   r   
old_prefix
old_suffixr   replacements)r   rT  rU  r   rV  r   s         rP   r   z)ReverseChainSingleSubstStatement.__init__^  s=    4***+5z((rR   c                    d | j         D             }d | j        D             }| j        d                                         }| j        d                                         }t          |          dk    r|t          |          z  }|                    | j        ||t          t          ||                               d S )Nc                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z:ReverseChainSingleSubstStatement.build.<locals>.<listcomp>e       8881!**,,888rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z:ReverseChainSingleSubstStatement.build.<locals>.<listcomp>f  rY  rR   r   r   )
rT  rU  r   r   rV  r   add_reverse_chain_single_substr   dictzipr   r   rS  rT  	originalsreplacess         rP   r   z&ReverseChainSingleSubstStatement.buildd  s    8888888888KN++--	$Q'0022x==A#i..0H..M664Ix0H0H+I+I	
 	
 	
 	
 	
rR   r   c                 v   d}t          | j                  st          | j                  rt          | j                  r*|d                    d | j        D                       dz   z  }|d                    d | j        D                       z  }t          | j                  r*|dd                    d | j        D                       z   z  }n0|d                    t          t          | j                            z  }|d                    d                    d | j        D                                 z  }|S )Nzrsub r   c              3   4   K   | ]}t          |          V  d S r   r   r  s     rP   rQ   z9ReverseChainSingleSubstStatement.asFea.<locals>.<genexpr>s  s(      BBQaBBBBBBrR   c              3   :   K   | ]}t          |          d z   V  dS r  r   r  s     rP   rQ   z9ReverseChainSingleSubstStatement.asFea.<locals>.<genexpr>t  ,      @@qE!HHsN@@@@@@rR   c              3   4   K   | ]}t          |          V  d S r   r   r  s     rP   rQ   z9ReverseChainSingleSubstStatement.asFea.<locals>.<genexpr>v  s(      %H%H1eAhh%H%H%H%H%H%HrR    by {};c              3   4   K   | ]}t          |          V  d S r   r   r  s     rP   rQ   z9ReverseChainSingleSubstStatement.asFea.<locals>.<genexpr>y  (      (M(Maq(M(M(M(M(M(MrR   )	r   rT  rU  rS   r   r   r   r   rV  r   s      rP   r   z&ReverseChainSingleSubstStatement.asFeao  s-   t 	53t#7#7 	54?## IsxxBB$/BBBBBSHH388@@DK@@@@@@C4?## IsSXX%H%H%H%H%HHHHH388Ct{33444Cy(M(M4;L(M(M(M M MNNN
rR   r   r   r  rM   rR   rP   r<   r<   U  sU         ) ) ) )	
 	
 	
     rR   r<   c                   (    e Zd ZdZddZd ZddZdS )	r?   a.  A single substitution statement.

    Note the unusual argument order: ``prefix`` and suffix come `after`
    the replacement ``glyphs``. ``prefix``, ``suffix``, ``glyphs`` and
    ``replace`` should be lists of `glyph-containing objects`_. ``glyphs`` and
    ``replace`` should be one-item lists.
    Nc                     t                               | |           ||c| _        | _        || _        || _        || _        d S r   )rA   r   rS  rT  r  r   rV  )r   r   replacerS  rT  r  r   s          rP   r   zSingleSubstStatement.__init__  sD    4***#)6 T[$#rR   c                    d | j         D             }d | j        D             }| j        d                                         }| j        d                                         }t          |          dk    r|t          |          z  }|                    | j        ||t          t          ||                    | j
                   dS )z9Calls the builder object's ``add_single_subst`` callback.c                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z.SingleSubstStatement.build.<locals>.<listcomp>  r[  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z.SingleSubstStatement.build.<locals>.<listcomp>  r[  rR   r   r   N)rS  rT  r   r   rV  r   add_single_substr   r   r]  r  r^  s         rP   r   zSingleSubstStatement.build  s    4444444444KN++--	$Q'0022x==A#i..0H  MIx0011O	
 	
 	
 	
 	
rR   r   c                 r   d}t          | j                  st          | j                  s| j        rt          | j                  r*|d                    d | j        D                       dz   z  }|d                    d | j        D                       z  }t          | j                  r*|dd                    d | j        D                       z   z  }n'|d                    d | j        D                       z  }|d                    d                    d | j        D                                 z  }|S )	Nra  r   c              3   4   K   | ]}t          |          V  d S r   r   r  s     rP   rQ   z-SingleSubstStatement.asFea.<locals>.<genexpr>  s(      >>Qa>>>>>>rR   c              3   :   K   | ]}t          |          d z   V  dS r  r   r  s     rP   rQ   z-SingleSubstStatement.asFea.<locals>.<genexpr>  rd  rR   c              3   4   K   | ]}t          |          V  d S r   r   r  s     rP   rQ   z-SingleSubstStatement.asFea.<locals>.<genexpr>  s(      %D%D1eAhh%D%D%D%D%D%DrR   c              3   4   K   | ]}t          |          V  d S r   r   r  s     rP   rQ   z-SingleSubstStatement.asFea.<locals>.<genexpr>  s(      ::E!HH::::::rR   rf  c              3   4   K   | ]}t          |          V  d S r   r   r  s     rP   rQ   z-SingleSubstStatement.asFea.<locals>.<genexpr>  rh  rR   )r   rS  rT  r  rS   r   r   rV  r   s      rP   r   zSingleSubstStatement.asFea  s;   t{ 	;s4;// 	;4? 	;4; Esxx>>$+>>>>>DD388@@DK@@@@@@C4; EsSXX%D%D%D%D%DDDDD388::dk::::::Cy(M(M4;L(M(M(M M MNNN
rR   r   r   r  rM   rR   rP   r?   r?   }  sU         $ $ $ $
 
 
      rR   r?   c                   (    e Zd ZdZddZd ZddZdS )	r=   zA ``script`` statement.Nc                 J    t                               | |           || _        d S r   )rA   r   rz   )r   rz   r   s      rP   r   zScriptStatement.__init__  s#    4***rR   c                 F    |                     | j        | j                   dS )z,Calls the builder's ``set_script`` callback.N)
set_scriptr   rz   r   s     rP   r   zScriptStatement.build  s"    4=$+66666rR   r   c                 Z    d                     | j                                                  S )Nz
script {};)r   rz   r  r   s     rP   r   zScriptStatement.asFea  s$    ""4;#4#4#6#6777rR   r   r   r  rM   rR   rP   r=   r=     sQ        !!   7 7 78 8 8 8 8 8rR   r=   c                   (    e Zd ZdZddZd ZddZdS )	r>   zA single position statement. ``prefix`` and ``suffix`` should be
    lists of `glyph-containing objects`_.

    ``pos`` should be a one-element list containing a (`glyph-containing object`_,
    :class:`ValueRecord`) tuple.Nc                 v    t                               | |           |||c| _        | _        | _        || _        d S r   )rA   r   rt   rS  rT  r  )r   rt   rS  rT  r  r   s         rP   r   zSinglePosStatement.__init__  s9    4***-0&&*$+t{$rR   c                     d | j         D             }d | j        D             }d | j        D             }|                    | j        |||| j                   dS )z7Calls the builder object's ``add_single_pos`` callback.c                 6    g | ]}|                                 S rM   rX  rY  s     rP   r  z,SinglePosStatement.build.<locals>.<listcomp>  r[  rR   c                 6    g | ]}|                                 S rM   rX  r]  s     rP   r  z,SinglePosStatement.build.<locals>.<listcomp>  r[  rR   c                 @    g | ]\  }}|                                 |fS rM   rX  )rN   r   r  s      rP   r  z,SinglePosStatement.build.<locals>.<listcomp>  s)    >>>E

e$>>>rR   N)rS  rT  rt   add_single_posr   r  )r   r   rS  rT  rt   s        rP   r   zSinglePosStatement.build  sg    4444444444>>TX>>>t}ffc4?SSSSSrR   r   c                 ,   d}t          | j                  st          | j                  s| j        rt          | j                  r3|d                    t          t          | j                            dz   z  }|d                    d | j        D                       z  }t          | j                  r3|dd                    t          t          | j                            z   z  }n'|d                    d | j        D                       z  }|dz  }|S )Nr  r   c                     g | ]B}t          |d                    dz   |d         rd|d                                          z   ndz   CS )r   rb  r   r   r   r   r  s     rP   r  z,SinglePosStatement.asFea.<locals>.<listcomp>  s[        !A$KK#%1)M#!

*<*<2N  rR   c                     g | ]?}t          |d                    dz   |d         r|d                                          ndz   @S )r   r   r   r   r   r  s     rP   r  z,SinglePosStatement.asFea.<locals>.<listcomp>  sE    VVVqts"ad&BadjjlllCVVVrR   r5  )r   rS  rT  r  rS   r   r   rt   r   s      rP   r   zSinglePosStatement.asFea  s   t{ 	s4;// 	4? 	4; ?sxxE4; 7 7883>>388 !X    C 4; ?sSXXc%&=&=>>>>388VVTXVVV  C 	s

rR   r   r   r  rM   rR   rP   r>   r>     sX        $ $% % % %
T T T     rR   r>   c                   (    e Zd ZdZddZd ZddZdS )	rE   zRepresents a subtable break.Nc                 <    t                               | |           d S r   )rA   r   r   s     rP   r   zSubtableStatement.__init__  s    4*****rR   c                 :    |                     | j                   dS )z<Calls the builder objects's ``add_subtable_break`` callback.N)add_subtable_breakr   r   s     rP   r   zSubtableStatement.build  s    ""4=11111rR   r   c                     dS )Nz	subtable;rM   r   s     rP   r   zSubtableStatement.asFea  s    {rR   r   r   r  rM   rR   rP   rE   rE     sQ        &&+ + + +2 2 2     rR   rE   c                   R    e Zd ZdZ	 	 	 	 	 	 	 	 	 	 ddZd Zd Zd Zdd	Zd
 Z	e	Z
dS )rG   zRepresents a value record.NFc                     t                               | |
           ||c| _        | _        ||c| _        | _        ||c| _        | _        ||c| _        | _	        |	| _
        d S r   )r&   r   
xPlacement
yPlacementxAdvanceyAdvance
xPlaDevice
yPlaDevice
xAdvDevice
yAdvDevicevertical)r   r  r  r  r  r  r  r  r  r  r   s              rP   r   zValueRecord.__init__  se     	D(+++,6
((0($t},6
(,6
( rR   c                     | j         |j         k    oO| j        |j        k    o?| j        |j        k    o/| j        |j        k    o| j        |j        k    o| j        |j        k    S r   )r  r  r  r  r  r  r   others     rP   __eq__zValueRecord.__eq__  sr    Ou// 45#334/4 /4 5#33	4
 5#33	
rR   c                 .    |                      |           S r   )r  r  s     rP   __ne__zValueRecord.__ne__  s    ;;u%%%%rR   c                 P   t          | j                  t          | j                  z  t          | j                  z  t          | j                  z  t          | j                  z  t          | j                  z  t          | j                  z  t          | j                  z  S r   )	hashr  r  r  r  r  r  r  r  r   s    rP   __hash__zValueRecord.__hash__  s    !!4?##$4=!!" 4=!!" 4?##	$
 4?##$ 4?##$ 4?##$		
rR   r   c                    | sdS | j         | j        }}| j        | j        }}| j        | j        }}| j        | j        }	}| j        }
|(|&||
rt          |          S ||
st          |          S |pd}|pd}|pd}|pd}||||	d|d|d|d|d	S d|d|d|d|dt          |          dt          |          dt          |          dt          |	          dS )Nz<NULL>r   <r   rl  )r  r  r  r  r  r  r  r  r  ry  rU   )r   r   re  rf  r  r  r  r  r  r  r  s              rP   r   zValueRecord.asFea   sR    	81!]DM(!%$/J
!%$/J
= 9H8}}$!(!8}}$ FF=q=q """"&'aaHHHhhh?? AAAAHHHH:&&&&:&&&&:&&&&:&&&&	
 		
rR   c                 :     t           fddD                       S )Nc              3   <   K   | ]}t          |          d uV  d S r   )getattr)rN   vr   s     rP   rQ   z'ValueRecord.__bool__.<locals>.<genexpr>M  sF       
 
 D!D(
 
 
 
 
 
rR   )r  r  r  r  r  r  r  r  )r  r   s   `rP   __bool__zValueRecord.__bool__L  s=     
 
 
 
	
 
 
 
 
 	
rR   )
NNNNNNNNFNr   )r   r   r   r   r   r  r  r  r   r  __nonzero__rM   rR   rP   rG   rG     s        $$ ! ! ! !(
 
 
& & &

 

 

*
 *
 *
 *
X
 
 
 KKKrR   rG   c                   "    e Zd ZdZddZddZdS )rH   z+Represents a named value record definition.Nc                 X    t                               | |           || _        || _        d S r   )rA   r   r   r  )r   r   r  r   s       rP   r   zValueRecordDefinition.__init__a  s*    4***	


rR   r   c                 f    d                     | j                                        | j                  S )NzvalueRecordDef {} {};)r   r  r   r   r   s     rP   r   zValueRecordDefinition.asFeaf  s(    &--dj.>.>.@.@$)LLLrR   r   r   r   rM   rR   rP   rH   rH   ^  sH        55   
M M M M M MrR   rH   c                     | dk    r|dk    r|dk    rdS | dk    r|dk    r|dk    rdS d                     | ||          S )N   r   i	  r   r   1{} {} {}r   )pideidlids      rP   simplify_name_attributesr  j  sV    
axxC1HHr	cQhh3!88s  c3///rR   c                   (    e Zd ZdZddZd ZddZdS )	r9   zRepresents a name record. (`Section 9.e. <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9.e>`_)Nc                     t                               | |           || _        || _        || _        || _        || _        d S r   )rA   r   nameID
platformID	platEncIDlangIDstring)r   r  r  r  r  r  r   s          rP   r   zNameRecord.__init__v  s?    4***$"rR   c                 v    |                     | j        | j        | j        | j        | j        | j                   dS )z8Calls the builder object's ``add_name_record`` callback.N)add_name_recordr   r  r  r  r  r  r   s     rP   r   zNameRecord.build~  sB    MKONKK	
 	
 	
 	
 	
rR   r   c           	          d t          | j        | j        | j                  }|t	          d| j                  t          | j        |          |dk    r?d                    fdt          dt                    d          D                       }n!d                    fd	D                       }t          | j        | j        | j                  }|dk    r|d
z  }d                    | j        ||          S )Nc                 J    | dk    r| dk    r| dvrt          |           S || z  S )N    ~   )"   \   )chr)rz  escape_patterns     rP   escapez NameRecord.asFea.<locals>.escape  s3    DyyQ$YY1L+@+@1vv%))rR   zUnsupported encoding)encoding	utf_16_ber   c           
          g | ]=} t          |                   d z  t          |dz                      z   d          >S )   r   z\%04xr   )rN   r  r  r   s     rP   r  z$NameRecord.asFea.<locals>.<listcomp>  sY        F71Q4==3.1q51B1BBHMM  rR   r   r   c                 B    g | ]} t          |          d           S )z\%02xr  )rN   br  s     rP   r  z$NameRecord.asFea.<locals>.<listcomp>  s+    %N%N%NqffWQZZ&B&B%N%N%NrR   r   znameid {} {}"{}";)r   r  r  r  r   r   r   r  rS   r  r   r  r   r  )r   r   r  escaped_stringplatr  r   s        @@rP   r   zNameRecord.asFea  s!   	* 	* 	* tLL!"8$-HHHDK(333{""WW    "1c!ffa00   NN  WW%N%N%N%NA%N%N%NOON'UU2::CKD"))$+t^LLLrR   r   r   r  rM   rR   rP   r9   r9   s  s]         K  K   	
 	
 	
M M M M M MrR   r9   c                        e Zd ZdZd ZddZdS )r'   z4Represents a ``sizemenuname`` or ``name`` statement.c                 p    t                               | |           |                    | j                   dS )z8Calls the builder object's ``add_featureName`` callback.N)r9   r   add_featureNamer  r   s     rP   r   zFeatureNameStatement.build  s4    w''',,,,,rR   r   c                     | j         dk    rd}nd}t          | j        | j        | j                  }|dk    r|dz  }d                    ||| j                  S )Nsizesizemenunamer   r   r   z
{} {}"{}";)r  r  r  r  r  r   r  )r   r   r   r  s       rP   r   zFeatureNameStatement.asFea  s^    ;&   CCC'UU2::CKD""3dk:::rR   Nr   )r   r   r   r   r   r   rM   rR   rP   r'   r'     s=        >>- - -
; ; ; ; ; ;rR   r'   c                       e Zd ZdZddZdS )rD   z+Represents a STAT table ``name`` statement.r   c                     t          | j        | j        | j                  }|dk    r|dz  }d                    || j                  S Nr   r   zname {}"{}";r  r  r  r  r   r  r   r   r  s      rP   r   zSTATNameStatement.asFea  C    'UU2::CKD$$T4;777rR   Nr   )r   r   r   r   r   rM   rR   rP   rD   rD     s.        558 8 8 8 8 8rR   rD   c                   (    e Zd ZdZddZd ZddZdS )	r@   zA ``parameters`` statement.Nc                 t    t                               | |           || _        || _        || _        || _        d S r   )rA   r   
DesignSizeSubfamilyID
RangeStartRangeEnd)r   r  r  r  r  r   s         rP   r   zSizeParameters.__init__  s9    4***$&$ rR   c                 j    |                     | j        | j        | j        | j        | j                   dS )z<Calls the builder object's ``set_size_parameters`` callback.N)set_size_parametersr   r  r  r  r  r   s     rP   r   zSizeParameters.build  s>    ##MOOM	
 	
 	
 	
 	
rR   r   c                     d                     | j        | j                  }| j        dk    s| j        dk    rC|d                     t          | j        dz            t          | j        dz                      z  }|dz   S )Nzparameters {:.1f} {}r   z {} {}
   r5  )r   r  r  r  r  intr   s      rP   r   zSizeParameters.asFea  sv    $++DOT=MNN?a4=A#5#58??3t';#<#<c$-RTBT>U>UVVVCSyrR   r   r   r  rM   rR   rP   r@   r@     sQ        %%! ! ! !
 
 
     rR   r@   c                   *    e Zd ZdZ	 ddZd ZddZdS )	r   z;Represent a name statement inside a ``cvParameters`` block.Nc           	      V    t                               | ||||||           || _        d S r	  )r9   r   r#  )r   r  r  r  r  r  r#  r   s           rP   r   z"CVParametersNameStatement.__init__  s=     	&*i( 	 	
 	
 	
 %rR   c                    d}| j         dk    r3d                    |j                            | j        d                    }|                    | j                   | j        | j         |z   f| _        t                              | |           dS )z9Calls the builder object's ``add_cv_parameter`` callback.r   r%  z_{}r   N)r#  r   cv_num_named_params_getr  add_cv_parameterr9   r   )r   r   items      rP   r   zCVParametersNameStatement.build  s    ?222<< < @ @a P PQQD  ---{DOd$:;w'''''rR   r   c                     t          | j        | j        | j                  }|dk    r|dz  }d                    || j                  S r  r  r  s      rP   r   zCVParametersNameStatement.asFea  r  rR   r   r   r  rM   rR   rP   r   r     sX        EE SW% % % %( ( (8 8 8 8 8 8rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r"   a  
    Statement used in cvParameters blocks of Character Variant features (cvXX).
    The Unicode value may be written with either decimal or hexadecimal
    notation. The value must be preceded by '0x' if it is a hexadecimal value.
    The largest Unicode value allowed is 0xFFFFFF.
    Nc                 X    t                               | |           || _        || _        d S r   )rA   r   	characterr   )r   r  r   r   s       rP   r   zCharacterStatement.__init__  s*    4***"rR   c                 F    |                     | j        | j                   dS )z9Calls the builder object's ``add_cv_character`` callback.N)add_cv_characterr  r   r   s     rP   r   zCharacterStatement.build  s"      :::::rR   r   c                 6    d                     | j                  S )NzCharacter {:#x};)r   r  r   s     rP   r   zCharacterStatement.asFea  s    !((888rR   r   r   r  rM   rR   rP   r"   r"     sU            
; ; ;9 9 9 9 9 9rR   r"   c                   (    e Zd ZdZddZd ZddZdS )	r   zAn axis definition, being either a ``VertAxis.BaseTagList/BaseScriptList``
    pair or a ``HorizAxis.BaseTagList/BaseScriptList`` pair.Nc                 f    t                               | |           || _        || _        || _        d S r   )rA   r   basesscriptsr  )r   r  r  r  r   s        rP   r   zBaseAxis.__init__  s1    4***
 rR   c                 R    |                     | j        | j        | j                   dS )z6Calls the builder object's ``set_base_axis`` callback.N)set_base_axisr  r  r  r   s     rP   r   zBaseAxis.build  s&    dj$,FFFFFrR   r   c           	          | j         rdnd}d | j        D             }d                    |d                    | j                  ||d                    |                    S )NVertHorizc                     g | ]Q}d                      |d         |d         d                    t          t          |d                                       RS )r  r   r   r   r   )r   rS   r   ry  )rN   r(  s     rP   r  z"BaseAxis.asFea.<locals>.<listcomp>  sZ     
 
 
 adAaD#((3sAaD>>*B*BCC
 
 
rR   z2{}Axis.BaseTagList {};
{}{}Axis.BaseScriptList {};r   rK   )r  r  r   rS   r  )r   r   	directionr  s       rP   r   zBaseAxis.asFea  sr    "m8FF	
 
\
 
 
 EKKsxx
++VY		'@R@R
 
 	
rR   r   r   r  rM   rR   rP   r   r     sZ        @ @! ! ! !G G G
 
 
 
 
 
rR   r   c                   (    e Zd ZdZddZd ZddZdS )	r:   zAn entry in the ``OS/2`` table. Most ``values`` should be numbers or
    strings, apart from when the key is ``UnicodeRange``, ``CodePageRange``
    or ``Panose``, in which case it should be an array of integers.Nc                 X    t                               | |           || _        || _        d S r   rA   r   r  r  r   r  r  r   s       rP   r   zOS2Field.__init__*  *    4***


rR   c                 F    |                     | j        | j                   dS )z6Calls the builder object's ``add_os2_field`` callback.N)add_os2_fieldr  r  r   s     rP   r   zOS2Field.build/  s"    dh
33333rR   r   c                 F   d d}d}t          d |D                       }|                    fd|D                        dg|d<   dd	 g|d
<   | j        |v rFd                    || j                 d          || j                 d         | j                            S dS )Nc                 R    d                     t          t          |                     S )Nr   )rS   r   ry  )re  s    rP   
intarr2strz"OS2Field.asFea.<locals>.intarr2str4  s    88CQKK(((rR   )FSTypeTypoAscenderTypoDescenderTypoLineGap	winAscent
winDescentXHeight	CapHeightWeightClass
WidthClassLowerOpSizeUpperOpSize)UnicodeRangeCodePageRangec                 H    g | ]}|                                 |t          gf S rM   )r   ry  r  s     rP   r  z"OS2Field.asFea.<locals>.<listcomp>F  s)    @@@1!''))aX.@@@rR   c                 @    g | ]}|                                 |gfS rM   r   )rN   re  r  s     rP   r  z"OS2Field.asFea.<locals>.<listcomp>G  s*    FFF!!''))a_5FFFrR   PanosepanoseVendorc                 ,    d                     |           S )Nz"{}"r  )rf  s    rP   <lambda>z OS2Field.asFea.<locals>.<lambda>I  s    &--2B2B rR   vendor{} {};r   r   r   )r\  updater  r   r  )r   r   numbersrangeskeywordsr  s        @rP   r   zOS2Field.asFea3  s    	) 	) 	)
 3@@@@@AAFFFFvFFFGGG&
3&(B(BC8x??"1%'<x'9!'<TZ'H'H   rrR   r   r   r  rM   rR   rP   r:   r:   %  sW        G G   
4 4 4     rR   r:   c                   (    e Zd ZdZddZd ZddZdS )	r*   zAn entry in the ``hhea`` table.Nc                 X    t                               | |           || _        || _        d S r   r  r   s       rP   r   zHheaField.__init__T  r  rR   c                 F    |                     | j        | j                   dS )z7Calls the builder object's ``add_hhea_field`` callback.N)add_hhea_fieldr  r  r   s     rP   r   zHheaField.buildY  "    tx44444rR   r   c                     d}t          d |D                       }d                    || j                 | j                  S )N)CaretOffsetAscender	DescenderLineGapc                 :    g | ]}|                                 |fS rM   r  r  s     rP   r  z#HheaField.asFea.<locals>.<listcomp>_  $    888A!''))Q888rR   r  r\  r   r  r  r   r   fieldsr"  s       rP   r   zHheaField.asFea]  s@    D8888899x14:>>>rR   r   r   r  rM   rR   rP   r*   r*   Q  Q        ))   
5 5 5? ? ? ? ? ?rR   r*   c                   (    e Zd ZdZddZd ZddZdS )	rI   zAn entry in the ``vhea`` table.Nc                 X    t                               | |           || _        || _        d S r   r  r   s       rP   r   zVheaField.__init__f  r  rR   c                 F    |                     | j        | j                   dS )z7Calls the builder object's ``add_vhea_field`` callback.N)add_vhea_fieldr  r  r   s     rP   r   zVheaField.buildk  r'  rR   r   c                     d}t          d |D                       }d                    || j                 | j                  S )N)VertTypoAscenderVertTypoDescenderVertTypoLineGapc                 :    g | ]}|                                 |fS rM   r  r  s     rP   r  z#VheaField.asFea.<locals>.<listcomp>q  r.  rR   r  r/  r0  s       rP   r   zVheaField.asFeao  s@    M8888899x14:>>>rR   r   r   r  rM   rR   rP   rI   rI   c  r2  rR   rI   c                   (    e Zd ZdZddZd ZddZdS )	rC   zA STAT table Design Axis

    Args:
        tag (str): a 4 letter axis tag
        axisOrder (int): an int
        names (list): a list of :class:`STATNameStatement` objects
    Nc                 t    t                               | |           || _        || _        || _        || _        d S r   )rA   r   r   	axisOrdernamesr   )r   r   r>  r?  r   s        rP   r   z STATDesignAxisStatement.__init__~  s8    4***"
 rR   c                 <    |                     | | j                   d S r   )addDesignAxisr   r   s     rP   r   zSTATDesignAxisStatement.build  s     dDM22222rR   r   c                     t           z  d| j         d| j         d}|dz                       fd| j        D                       dz   z  }|dz  }|S )NzDesignAxis r   z { 
r   c                 <    g | ]}|                                S r  r   r  s     rP   r  z1STATDesignAxisStatement.asFea.<locals>.<listcomp>  '    $P$P$PQWWFW%;%;$P$P$PrR   };)r  r   r>  rS   r?  r   s    ` rP   r   zSTATDesignAxisStatement.asFea  so    %=DH==t~===v##$P$P$P$PTZ$P$P$PQQTXXXt
rR   r   r   r  rM   rR   rP   rC   rC   u  sU         ! ! ! !3 3 3     rR   rC   c                   (    e Zd ZdZddZd ZddZdS )	r$   ziSTAT table ElidedFallbackName

    Args:
        names: a list of :class:`STATNameStatement` objects
    Nc                 X    t                               | |           || _        || _        d S r   )rA   r   r?  r   )r   r?  r   s      rP   r   zElidedFallbackName.__init__  *    4***
 rR   c                 F    |                     | j        | j                   d S r   )setElidedFallbackNamer?  r   r   s     rP   r   zElidedFallbackName.build  "    %%dj$-@@@@@rR   r   c                     t           z  d}|dz                       fd| j        D                       dz   z  }|dz  }|S )NzElidedFallbackName { 
r   c                 <    g | ]}|                                S r  r   r  s     rP   r  z,ElidedFallbackName.asFea.<locals>.<listcomp>  rD  rR   rE  )r  rS   r?  r   s    ` rP   r   zElidedFallbackName.asFea  sX    %'v##$P$P$P$PTZ$P$P$PQQTXXXt
rR   r   r   r  rM   rR   rP   r$   r$     sX         ! ! ! !
A A A     rR   r$   c                   (    e Zd ZdZddZd ZddZdS )	r%   zpSTAT table ElidedFallbackNameID

    Args:
        value: an int pointing to an existing name table name ID
    Nc                 X    t                               | |           || _        || _        d S r   )rA   r   r  r   )r   r  r   s      rP   r   zElidedFallbackNameID.__init__  rH  rR   c                 F    |                     | j        | j                   d S r   )rJ  r  r   r   s     rP   r   zElidedFallbackNameID.build  rK  rR   r   c                     d| j          dS )NzElidedFallbackNameID r5  )r  r   s     rP   r   zElidedFallbackNameID.asFea  s    4tz4444rR   r   r   r  rM   rR   rP   r%   r%     sX         ! ! ! !
A A A5 5 5 5 5 5rR   r%   c                   (    e Zd ZdZddZd ZddZdS )	rB   zA STAT table Axis Value Record

    Args:
        names (list): a list of :class:`STATNameStatement` objects
        locations (list): a list of :class:`AxisValueLocationStatement` objects
        flags (int): an int
    Nc                 f    t                               | |           || _        || _        || _        d S r   )rA   r   r?  	locationsr  )r   r?  rT  r  r   s        rP   r   zSTATAxisValueStatement.__init__  s1    4***
"


rR   c                 <    |                     | | j                   d S r   )addAxisValueRecordr   r   s     rP   r   zSTATAxisValueStatement.build  s     ""477777rR   r   c                    d}| j         D ]}||                                z  }| j        D ]}||                                z  }|dz  }| j        rqddg}g }d}t	          t          |                    D ]0}| j        |z  dk    r|                    ||                    |dz  }1|dd                    |           d	z  }|d
z  }|S )NzAxisValue {
r   OlderSiblingFontAttributeElidableAxisValueNamer   r   zflag r   ;
rE  )rT  r   r?  r  r  r   r   rS   )	r   r   r   r   
nameRecordr  flagStringsr   r  s	            rP   r   zSTATAxisValueStatement.asFea  s    	$ 	$H8>>###CC* 	 	J:##%%%C4KCC: 	602IJEKD3u::&& ! !:$))&&uQx000qy5388K005555Ct
rR   r   r   r  rM   rR   rP   rB   rB     sU            8 8 8     rR   rB   c                   "    e Zd ZdZddZddZdS )r   z
    A STAT table Axis Value Location

    Args:
        tag (str): a 4 letter axis tag
        values (list): a list of ints and/or floats
    Nc                 X    t                               | |           || _        || _        d S r   )rA   r   r   values)r   r   r_  r   s       rP   r   z#AxisValueLocationStatement.__init__  s*    4***rR   r   c                 v    |d| j          dz  }|d                    d | j        D                        dz  }|S )Nz	location r   c              3   4   K   | ]}t          |          V  d S r   rx  )rN   r  s     rP   rQ   z3AxisValueLocationStatement.asFea.<locals>.<genexpr>  s(      77a3q66777777rR   rZ  )r   rS   r_  )r   r   s     rP   r   z AxisValueLocationStatement.asFea  sO    &48&&&&#((774;77777<<<<
rR   r   r   r   rM   rR   rP   r   r     sF            
     rR   r   )VfontTools.misc.py23r   r   fontTools.feaLib.errorr   fontTools.feaLib.locationr   fontTools.misc.encodingToolsr   collectionsr   rJ  r  __all__rU   r  r   r   objectr	   rA   r&   r   r   r   r   r   r   r   r   r
   r   r   r   rF   r   r   r   r   r   r   r   r   r    r!   r#   r(   r+   r,   r-   r.   r/   r)   r0   r1   r2   r3   r4   r5   r6   r7   r8   r;   r<   r?   r=   r>   rE   rG   rH   r  r9   r'   rD   r@   r   r"   r   r:   r*   rI   rC   r$   r%   rB   r   rM   rR   rP   <module>ri     s   0 0 0 0 0 0 0 0 2 2 2 2 2 2 8 8 8 8 8 8 4 4 4 4 4 4 # # # # # #    B B BJF F F s5 5 57 7t      f   ,	 	 	 	 	 	 	 		 	 	 	 	 	 	 		 	 	 	 	g 	 	 	    
   ! ! ! ! !
 ! ! ! ;% ;% ;% ;% ;% ;% ;% ;%|* * * * *Z * * *") ) ) ) )J ) ) )"    Y   
 
 
 
 
I 
 
 
.	J 	J 	J 	J 	J% 	J 	J 	J    5   @    %   *    %   .       C C C C C9 C C C 
 
 
 
 
Y 
 
 
<* * * * * * * *Z$
 $
 $
 $
 $
) $
 $
 $
N" " " " "i " " "J" " " " "Z " " "J    y   
 
 
 
 
i 
 
 
&7 7 7 7 7y 7 7 7t7 7 7 7 7 7 7 7tT T T T T) T T T*6 6 6 6 6	 6 6 6!9 !9 !9 !9 !9 !9 !9 !9H!9 !9 !9 !9 !99 !9 !9 !9H7 7 7 7 7y 7 7 7&    	   :R R R R Ri R R R< < < < <I < < <
 
 
 
 
I 
 
 
&
 
 
 
 
) 
 
 
&$ $ $ $ $Y $ $ $N&6 &6 &6 &6 &6) &6 &6 &6R5 5 5 5 5y 5 5 5"    9   *5 5 5 5 5) 5 5 5p    9   *0 0 0 0 0Y 0 0 0fJ J J J Jy J J JZ% % % % %y % % %P+ + + + +9 + + +\8 8 8 8 8i 8 8 8% % % % % % % %P    	   k k k k k* k k k\	M 	M 	M 	M 	MI 	M 	M 	M0 0 0.M .M .M .M .M .M .M .Mb; ; ; ; ;: ; ; ;&8 8 8 8 8
 8 8 8    Y   68 8 8 8 8
 8 8 869 9 9 9 9 9 9 9*
 
 
 
 
y 
 
 
2) ) ) ) )y ) ) )X? ? ? ? ?	 ? ? ?$? ? ? ? ?	 ? ? ?$    i   6       .5 5 5 5 59 5 5 5&% % % % %Y % % %P         rR   